Jump to content

    
Sign in to follow this  
vadias

STM32L100, ADC+DMA

Recommended Posts

Всем привет. Переношу код с 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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this