Jump to content

    

STM32L100, ADC+DMA

Всем привет. Переношу код с stm32f103 на stm32l100. На f103 все нормально работало в циклическом режиме, данные от ADC c 4ех каналов с помощью DMA постоянно 

обновлялись в массиве, на l100 обновляются только один раз при старте программы, так же обновляются когда в отладчике дергаю в CR2 DMA. В DR данные обновляться.

DMA у камней одинаковый. Что может быть? По описанию понял, что на l100 ADC тактируеться только от HSI. Это так? И зачем?

RCC->AHBENR |= RCC_AHBENR_DMA1EN;                         //
    DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;         // Peripherial adr
    DMA1_Channel1->CMAR = (uint32_t)&RegInputBuf; // Memory adr
    DMA1_Channel1->CCR &= ~DMA_CCR1_DIR;                     //
    DMA1_Channel1->CNDTR = 4;                                         // Buffer size
    DMA1_Channel1->CCR &= ~DMA_CCR1_PINC;                 // Periph sdr not increment
    DMA1_Channel1->CCR |= DMA_CCR1_MINC;                     // Memory adr increment
    DMA1_Channel1->CCR |= DMA_CCR1_PSIZE_0;             // Periph size 16bit
    DMA1_Channel1->CCR |= DMA_CCR1_MSIZE_0;             // Memory size 16 bit
    DMA1_Channel1->CCR |= DMA_CCR1_PL;                         //
    DMA1_Channel1->CCR |= DMA_CCR1_CIRC;                     //
    DMA1_Channel1->CCR |= DMA_CCR1_EN;                         // DMA On

Edited by vadias

Share this post


Link to post
Share on other sites
6 hours ago, vadias said:

Всем привет. Переношу код с stm32f103 на stm32l100. На f103 все нормально работало в циклическом режиме, данные от ADC c 4ех каналов с помощью DMA постоянно 

 

Извините, что встреваю. Просто хочу поделиться граблями.

Я неоднократно наблюдал, что (предположительно при пиках питания) может произойти рассинхронизация ADC и DMA, если их отпустить работать самих в циклическом режиме. То есть, может случиться, что в буфере данных произойдет циклический сдвиг: на месте ожидаемой первой выбоки будет вторая, вместо второй - третья, и так по циклу. Это заставляло меня отказаться от полной автономии связки ADC-DMA и пинать ее в прерывании от TC DMA, перезапуская ADC.

Share this post


Link to post
Share on other sites
7 minutes ago, KnightIgor said:

Я неоднократно наблюдал, что (предположительно при пиках питания) может произойти рассинхронизация ADC и DMA, если их отпустить работать самих в циклическом режиме.

Ни разу такого не видел. Много лет и ~10000 устройств. Видимо, нужно делать так, чтобы не было "пиков питания".

Share this post


Link to post
Share on other sites
42 minutes ago, scifi said:

Ни разу такого не видел. Много лет и ~10000 устройств. Видимо, нужно делать так, чтобы не было "пиков питания".

От пиков нет панацеи.

Share this post


Link to post
Share on other sites
1 час назад, KnightIgor сказал:

От пиков нет панацеи.

Странное рассказываете. Также за много лет и устройств с непрерывной работой DMA ни разу такого не наблюдал.

Да и при чём тут "автоматичность"? Если-б такое происходило в реале, то в любом устройстве при работе DMA (хоть с автоперезапуском хоть без) происходили бы сбои от внешних помех. А этого нет.

Сдаётся мне, что проблема у Вас была в другом....

Share this post


Link to post
Share on other sites

scifi, действительно, после выставления DDS все заработало!

В заключение рабочий вариант. И да, в stm32lxx ADC тактируеться только от HSI. 

   
        

	RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
	/*Set PA1, PA2, PA3, PA4 to analog mode */
	GPIOA->MODER &= ~(GPIO_MODER_MODER1 | GPIO_MODER_MODER2 | GPIO_MODER_MODER3 | GPIO_MODER_MODER4 );
	
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;

	DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; // Peripherial adr
	DMA1_Channel1->CMAR = (uint32_t)&AdcBuf; // Memory adr
	DMA1_Channel1->CCR &= ~DMA_CCR_DIR; // Data transfer direction
	DMA1_Channel1->CNDTR = 4; 			// Buf size
	DMA1_Channel1->CCR &= ~DMA_CCR_PINC; // Peripherial not inc
	DMA1_Channel1->CCR |= DMA_CCR_MINC; // Memory inc
	DMA1_Channel1->CCR |= DMA_CCR_PSIZE_0; // Peripherial size 16
	DMA1_Channel1->CCR |= DMA_CCR_MSIZE_0; // Memory size 16
	DMA1_Channel1->CCR |= DMA_CCR_PL_0; //
	DMA1_Channel1->CCR |= DMA_CCR_CIRC; // Circular mode
	NVIC_EnableIRQ(DMA1_Channel1_IRQn);
	DMA1_Channel1->CCR |= DMA_CCR_EN; //
							
	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;								// Enable ADC1
	/* scan mode */
	ADC1->CR1 |= ADC_CR1_SCAN | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCNUM_1 ;													
	/* Start convertion after SWSTRT, DMA mode */
	ADC1->CR2 |= ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS; 
	/* ADC sample time 239.5 */
	ADC1->SMPR3 |= ADC_SMPR3_SMP1 | ADC_SMPR3_SMP2 | ADC_SMPR3_SMP3 | ADC_SMPR3_SMP4;
	/* 4 channel sequence lenght */
	ADC1->SQR1 |= ADC_SQR1_L_0 | ADC_SQR1_L_1;
	/* sequence to be convertion */
	ADC1->SQR5 |= ADC_SQR5_SQ1_0;										// 1 channel
	ADC1->SQR5 |= ADC_SQR5_SQ2_1;										// 2 channel
	ADC1->SQR5 |= ADC_SQR5_SQ3_0 | ADC_SQR5_SQ3_1;						// 3 channel
	ADC1->SQR5 |= ADC_SQR5_SQ4_2;										// 4 channel
	//NVIC_EnableIRQ (ADC1_IRQn);
	ADC1->CR2 |= ADC_CR2_ADON;
	ADC1->CR2 |= ADC_CR2_SWSTART;		// Start Convertion

                    
    

 

Edited by vadias

Share this post


Link to post
Share on other sites

А зачем вы содержимое регистров не одной операцией изменяете, а несколькими? Они же объявлены как volatile, и gcc скорей всего не соберет все эти |= в одну кучу, а так и будет последовательно выполнять... И флеша больше тратится, и времени.

Share this post


Link to post
Share on other sites
27 минут назад, Eddy_Em сказал:

А зачем вы содержимое регистров не одной операцией изменяете, а несколькими? Они же объявлены как volatile, и gcc скорей всего не соберет все эти |= в одну кучу, а так и будет последовательно выполнять... И флеша больше тратится, и времени.

Открою страшную тайну начинающих: |= для регистров конфигурации обычно не нужно! А во многих случаях и вредно. Достаточно =:shok:

Share this post


Link to post
Share on other sites
On 10/31/2019 at 4:01 PM, KnightIgor said:

Я неоднократно наблюдал, что (предположительно при пиках питания) может произойти рассинхронизация ADC и DMA, если их отпустить работать самих в циклическом режиме. То есть, может случиться, что в буфере данных произойдет циклический сдвиг: на месте ожидаемой первой выбоки будет вторая, вместо второй - третья, и так по циклу. Это заставляло меня отказаться от полной автономии связки ADC-DMA и пинать ее в прерывании от TC DMA, перезапуская ADC.

Здравствуйте! У меня такая же проблема в STM32L100 серии при использовании нескольких каналов АЦП и DMA, обычно они складываются в буфер по порядку, который я предписываю в Rank , но иногда некоторые каналы почемуто меняются местами ... из-за чего это сулчается я так и не понял но что-то мне подсказывает дело в Sampling Time . 

Share this post


Link to post
Share on other sites
On 11/2/2019 at 12:28 PM, Mysteo said:

Здравствуйте! У меня такая же проблема в STM32L100 серии при использовании нескольких каналов АЦП и DMA, обычно они складываются в буфер по порядку, который я предписываю в Rank , но иногда некоторые каналы почемуто меняются местами ... из-за чего это сулчается я так и не понял но что-то мне подсказывает дело в Sampling Time . 

Все проблемы у L1хх только из-за неправильной настройки ACC64,  FlashLatency and vCore. Когда все стоит правильно то ни каких проблем не наблюдается. У вас как с этим делом?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now