STM32L-DISCOVERY - проблема с АЦП

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
vadim_ova
Открыл глаза
Сообщения: 43
Зарегистрирован: Пт мар 26, 2010 03:46:57
Откуда: Томск
Контактная информация:

STM32L-DISCOVERY - проблема с АЦП

Сообщение vadim_ova »

Добрый день!

В двух словах, проблема такая.

когда зашивается вот этот код:

Код: Выделить всё


int main(void)
{

	volatile int i;
	int adc_channel_0_value;

	 /*led*/ 
	RCC->AHBENR |=  RCC_AHBENR_GPIOBEN;
	GPIOB->MODER |=	  GPIO_MODER_MODER6_0;
	 
	 /*ADC Prescaler =2 */
	ADC->CCR &= 0xFFFCFFFF;
	ADC->CCR  |= ADC_CCR_ADCPRE_0;  

/*add clock*/
	RCC->APB2ENR |=	RCC_APB2ENR_ADC1EN;
	

	/*PIN A0 - ADC_IN0*/
	RCC->AHBENR |=  RCC_AHBENR_GPIOAEN;
	GPIOA->MODER |=	  GPIO_MODER_MODER0;

	ADC1->SQR5 |= ADC_SQR5_SQ1_0;
	ADC1->CR2 = ADC_CR2_EXTSEL_0 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTEN;

	
	/*add power*/
	ADC1->CR2 |= ADC_CR2_ADON;
 

    /* Wait until the ADC1 is ready */
 
 	while((ADC1->SR & ADC_FLAG_ADONS) == (uint32_t)RESET);

	while(1)
	{	
	
	 	ADC1->CR2 |= ADC_CR2_SWSTART;
  		while ((ADC1->SR & ADC_SR_EOC) != ADC_SR_EOC);
		
		adc_channel_0_value = ADC1->DR;
	
	
	
		GPIOB->BSRRL = GPIO_BSRR_BS_6;
		for( i=0 ;i<100000;i++){};
		GPIOB->BSRRH = GPIO_BSRR_BS_6;
		for( i=0 ;i<100000;i++){};
	}

	return 0;
}

Вот, перед началом последнего бесконечного цикла на строке:

Код: Выделить всё

while((ADC1->SR & ADC_FLAG_ADONS) == (uint32_t)RESET);
он виснет. Значит, АЦП никак не выйдет в состояние готовности. Ну что же я сделал не так?!

Спасибо!
Реклама
Аватара пользователя
Satyr
Друг Кота
Сообщения: 7439
Зарегистрирован: Чт ноя 04, 2010 01:56:36
Откуда: г. Москва

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение Satyr »

Проверь, меняются ли вобще регистры настройки ADC, что ты выставляешь или нет.
Вобще, сначала надо подкать клок и убрать резет с переферии, а потом уже с ним работать. У тебя наоборот.
Если не поможет - то далее проверять, все ли и правильные регистры поставил.
Реклама
Аватара пользователя
vadim_ova
Открыл глаза
Сообщения: 43
Зарегистрирован: Пт мар 26, 2010 03:46:57
Откуда: Томск
Контактная информация:

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение vadim_ova »

так-с.

Как я понял, надо сначала резет поставить и сбросить, а потом включить тактирование АЦП? это приведено в коде ниже.

Далее, я завел переменную и с ее помощью по очереди проверил все регистры.

Сначала нашелся косяк в SR, там стояла неготовность регулярных каналов, я это исправил, сейчас там стабильно все нули.

Вот окончательный код:

Код: Выделить всё

int main(void)
{
	/* Configure SysTick IRQ and SysTick Timer to generate interrupts every 500µs */
	volatile int i;
	int adc_channel_0_value;
	
	 
	/*  
	RCC->AHBENR |=  RCC_AHBENR_GPIOBEN;
	GPIOB->MODER |=	  GPIO_MODER_MODER6_0;
	  */
	test  =		RCC->APB2RSTR;
	
	RCC->APB2RSTR|= RCC_APB2RSTR_ADC1RST;

	test  =		RCC->APB2RSTR;

	RCC->APB2RSTR&= !(RCC_APB2RSTR_ADC1RST);

	test  = 	RCC->APB2RSTR;
	 
	RCC->APB2ENR |=	RCC_APB2ENR_ADC1EN;

	test  = 	RCC->APB2ENR;

	

	 /*ADC Prescaler =2 */
	ADC->CCR &= 0xFFFCFFFF;
	ADC->CCR  |= ADC_CCR_ADCPRE_0;  

   test  = 	ADC->CCR;
	
	/*A0 - ADC*/
	RCC->AHBENR |=  RCC_AHBENR_GPIOAEN;
	GPIOA->MODER |=	  GPIO_MODER_MODER0;

	/*when ADONS == 1*/
//	ADC1->CR2 = ADC_CR2_EXTSEL_0 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTEN;
	
				 /*Regular chamnel*/
	ADC1->SMPR3 |= ADC_SMPR3_SMP0;
//	ADC1->SQR5 |= ADC_SQR5_SQ1_0;


	ADC1->CR2 |= ADC_CR2_ADON;

	test = ADC1->CR2;
		test = ADC1->CR2;

//	RCC->APB2RSTR|= RCC_APB2RSTR_ADC1RST;
//	RCC->APB2RSTR&= !(RCC_APB2RSTR_ADC1RST);

	test = ADC1->CR2;
				 
	ADC1->CR1 &= !(ADC_CR1_PDD);
	ADC1->CR1 &= !(ADC_CR1_PDI);

	test = ADC1->CR2;

	test = ADC1->SR;

    /* Wait until the ADC1 is ready */
 
 	while((ADC1->SR & ADC_FLAG_ADONS) == (uint32_t)RESET)
	{
				test = ADC1->SR;
	}

	while(1)
	{	
	
	 	ADC1->CR2 |= ADC_CR2_SWSTART;
  		while ((ADC1->SR & ADC_SR_EOC) != ADC_SR_EOC);
		
		adc_channel_0_value = ADC1->DR;
	
	
	
		GPIOB->BSRRL = GPIO_BSRR_BS_6;
		for( i=0 ;i<100000;i++){};
		GPIOB->BSRRH = GPIO_BSRR_BS_6;
		for( i=0 ;i<100000;i++){};
	}

	return 0;
}

Но при этом в SR - все нули и ADONS все равно не ставится.... Проверял все регистры - все путем. Может быть еще что-то? не так поставил? или порядок не тот? или что упустил?
Аватара пользователя
Satyr
Друг Кота
Сообщения: 7439
Зарегистрирован: Чт ноя 04, 2010 01:56:36
Откуда: г. Москва

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение Satyr »

Это глянь. http://radiokot.ru/forum/download/file.php?id=81574
использую cmsis и periph. lib под STM32, что идет с IARом. там, впринципе, функции крошечные, только из структур в регистры ставят, быстро скомпонуешь.

Это по крайней мере работает, включая каллибрацию
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
GRAF
Мудрый кот
Сообщения: 1867
Зарегистрирован: Ср янв 23, 2008 22:11:54
Откуда: Калининград

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение GRAF »

vadim_ova, сначала включается тактирование нужного модуля, потом делаются настройки, иначе все регистры будут сброшены. Это ко всей перефирии относится.
Реклама
Аватара пользователя
vadim_ova
Открыл глаза
Сообщения: 43
Зарегистрирован: Пт мар 26, 2010 03:46:57
Откуда: Томск
Контактная информация:

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение vadim_ova »

Satyr писал(а):Это глянь. http://radiokot.ru/forum/download/file.php?id=81574
использую cmsis и periph. lib под STM32, что идет с IARом. там, впринципе, функции крошечные, только из структур в регистры ставят, быстро скомпонуешь.

Это по крайней мере работает, включая каллибрацию
на моем проце нет регистра, касающегося калибровки вообще))))
ну это не важно, остальное очень схоже.

Но выставляется бит RCNR - то есть, не готовы каналы. как я понял:

RCNR: Regular channel not ready
This bit is set and cleared by hardware after one of the SQRx register is written or after the
OVR bit is cleared. It indicates if a new regular conversion can be launched (by setting the
SWSTART bit).
0: Regular channel ready
1: Regular channel not ready, SWSTART must not be set
что менять-то нужно?

у меня же нулевой канал и преобразование всего одно в очереди - значит, SQR0 должен нулям равняться - что и показывает отладка.

Как тогда быть?
может быть, он требует настройки свойств таких как режим преобразования (непрерывный и т.д.) и тому подобных? этого я не успел сделать еще.
Реклама
Аватара пользователя
vadim_ova
Открыл глаза
Сообщения: 43
Зарегистрирован: Пт мар 26, 2010 03:46:57
Откуда: Томск
Контактная информация:

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение vadim_ova »

GRAF писал(а):vadim_ova, сначала включается тактирование нужного модуля, потом делаются настройки, иначе все регистры будут сброшены. Это ко всей перефирии относится.
спасибо! звучит очень логично, так и поступил. тоже, правда, не помогло.
Delfer
Родился
Сообщения: 4
Зарегистрирован: Пн июн 04, 2012 12:19:46

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение Delfer »

Сейчас с тем же бьюсь(

Код: Выделить всё

//ADC & SYSCFG
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG, ENABLE);
 /* Enable the GPIOs Clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  //ADC PA5
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  //ADC com conf
  ADC_CommonInitTypeDef ADC_CommonStr;
  ADC_CommonStructInit (&ADC_CommonStr);
  ADC_CommonStr.ADC_Prescaler = ADC_Prescaler_Div1;
  ADC_CommonInit (&ADC_CommonStr);
  // define ADC config
  ADC_InitTypeDef ADC_InitStructure;
  ADC_StructInit(&ADC_InitStructure);
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	// we work in continuous sampling mode
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_Init ( ADC1, &ADC_InitStructure);	//set config of ADC1
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_384Cycles); // define regular conversion config
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Wait until the ADC1 is ready */
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == SET);

  ADC_ContinuousModeCmd(ADC1, ENABLE);

  // start conversion
  //ADC_Cmd (ADC1,ENABLE);	//enable ADC1
  ADC_SoftwareStartConv(ADC1);	// start conversion (will be endless as we are in continuous mode)
...
int bf;
bf = ADC_GetConversionValue(ADC1);
Получается всегда 0, так же висит бит RCNR.
Аватара пользователя
Shapa
Встал на лапы
Сообщения: 127
Зарегистрирован: Пт июн 20, 2008 09:38:05
Откуда: Харьков
Контактная информация:

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение Shapa »

ADC_InitStructure.ADC_NbrOfConversion = 1;
Посмотрите хидер, где описана структура ADC_InitTypeDef, данного поля, лично я не нахожу.

Если это не поможет, вот вам живой пример инициализации ( STM32F100C8R6)

Код: Выделить всё

void adcInit(){
	ADC_InitTypeDef ADCInitStructure;

	ADCChannelInit();

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

	ADCInitStructure.ADC_Mode = ADC_Mode_Independent;
	ADCInitStructure.ADC_ScanConvMode = ENABLE;
	ADCInitStructure.ADC_ContinuousConvMode = ENABLE;
	ADCInitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
	ADCInitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADCInitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1, &ADCInitStructure);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5);
	ADC_Cmd(ADC1, ENABLE);

	/* Enable ADC1 reset calibaration register */
	ADC_ResetCalibration(ADC1);

	/* Check the end of ADC1 reset calibration register */
	while (ADC_GetResetCalibrationStatus(ADC1));

	/* Start ADC1 calibaration */
	ADC_StartCalibration(ADC1);

	/* Check the end of ADC1 calibration */
	while (ADC_GetCalibrationStatus(ADC1));

	/* Start ADC1 Software Conversion */
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
Только переконфигурируйте под свой канал
Delfer
Родился
Сообщения: 4
Зарегистрирован: Пн июн 04, 2012 12:19:46

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение Delfer »

Нашел ответ.
Не был выбран источник тактового, и, как следствие, тактирование шло от MSI. АЦП по какой то причине не хотел с этим мириться. Я не знаю по какой причине. Ничего в REFERENCE MANUAL и в ERRATA не нашел(
По диаграмме тактирования такты должны доходить.

Добавление строчек помогло.

Код: Выделить всё

  /* Enable HSI Clock */
    RCC_HSICmd(ENABLE);
    /*!< Wait till HSI is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
    {}
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
И в ожидании готовности у меня ошибка была

Код: Выделить всё

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Wait until ADC1 ON status */
  while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET);
Аватара пользователя
vadim_ova
Открыл глаза
Сообщения: 43
Зарегистрирован: Пт мар 26, 2010 03:46:57
Откуда: Томск
Контактная информация:

Re: STM32L-DISCOVERY - проблема с АЦП

Сообщение vadim_ova »

Delfer писал(а):Нашел ответ.
Не был выбран источник тактового, и, как следствие, тактирование шло от MSI. АЦП по какой то причине не хотел с этим мириться. Я не знаю по какой причине. Ничего в REFERENCE MANUAL и в ERRATA не нашел(
По диаграмме тактирования такты должны доходить.

Добавление строчек помогло.

Код: Выделить всё

  /* Enable HSI Clock */
    RCC_HSICmd(ENABLE);
    /*!< Wait till HSI is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
    {}
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
И в ожидании готовности у меня ошибка была

Код: Выделить всё

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Wait until ADC1 ON status */
  while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET);

оо, отлично!

Все-таки в тактировании дело)
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»