реклама на сайте
подробности

 
 
> STM32 ADC, Как сэмплировать два канала?
uriy
сообщение Mar 1 2012, 13:30
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Не могу понять как получать данные с двух каналов АЦП. Интересует ADC1. Регистр данных всего лишь один, хочу использовать regular режим. С одним каналом сейчас все работает, снимаю данные по таймеру. Где-то встречал упоминание что можно настроить DMA на работу с несколькими каналами АЦП. При этом определяется несколько буферов по количеству опрашиваемых каналов. Дальше АЦП (или DMA) как-то сам складывает семплы в свой буфер и генерит прерывание по заполнению буфера. Такой вариант был бы для меня идеальным. Может быть есть у кого примеры кода?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
scifi
сообщение Mar 1 2012, 14:31
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Для таких целей я включаю режим continuous mode + auto-injection. Так можно сканировать до 5 каналов: 1 regular и 4 injected (там как раз 4 регистра ADC_JDRx).
Ну а если хочется через DMA, то вот пример кода:
CODE
#define AVERAGING 128
#define ADC_NCHANNELS 6

static uint16_t volatile buf[AVERAGING][ADC_NCHANNELS];

void
adc_init(void)
{
/* enable clocking of ADC1, PORT A */
RCC_APB2ENR |= 0x00000204;
/* configure PA0,1,2,3,4,6 as analog inputs */
GPIOA_CRL &= 0xF0F00000;
/* enable clocking of DMA1 */
REGBIT(RCC_AHBENR, 0) = 1;
ADC1_CR2 = 0; /* turn ADC off */
timer_delay(2); /* wait at least 2 ADC clock cycles before calibration */
ADC1_CR1 = (1 << 8); /* enable scan mode */
ADC1_CR2 = (1 << 23) /* enable Vrefint */
| (1 << 8) /* enable DMA mode */
| (1 << 1) /* enable continuous conversion mode */
| (1 << 0);/* switch ADC on */
ADC1_SMPR2 = 0x3FFFFFFF; /* sample time 239.5 cycles for ch. 0-9 */
/* conversion sequence: ch. 0, 1, 2, 3, 6, 17 */
ADC1_SQR3 = (0 << 0) | (1 << 5) | (2 << 10)
| (3 << 15) | (6 << 20) | (17 << 25);
ADC1_SQR1 = ((ADC_NCHANNELS - 1) << 20); /* sequence length */
REGBIT(ADC1_CR2, 2) = 1; /* start ADC calibration */
while (REGBIT(ADC1_CR2, 2) != 0)
{
/* wait for calibration to complete */
}
DMA1_CNDTR(1) = AVERAGING * ADC_NCHANNELS;
DMA1_CPAR(1) = (uint32_t)&ADC1_DR;
DMA1_CMAR(1) = (uint32_t)buf;
DMA1_CCR(1) = (1 << 10) /* memory size 16 bits */
| (1 << 8) /* peripheral size 16 bits */
| (1 << 7) /* memory increment mode */
| (1 << 5) /* circular mode */
| (1 << 1) /* transfer complete interrupt enable */
| (1 << 0);/* channel enable */
REGBIT(ADC1_CR2, 0) = 1; /* start ADC conversions */
}


Сообщение отредактировал IgorKossak - Mar 1 2012, 14:34
Причина редактирования: [codebox]!!!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 00:30
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016