ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
13 июля
471129
pav256 (06.12.2013 16:36, просмотров: 25889)
Не работает ADC->DMA в STM32F4 Необходимо по 4-м каналам АЦП через DMA передавать массив данных в память. Другими словами последовательно по каждому каналу осуществляется измерение, затем процесс повторяется и так необходимое количество раз, определяемое объемом передаваемых через DMA выборок. Как только DMA передаст необходимый массив данных (SAMPL_ADC*CHANNEL_ADC), перестанут выполняться запросы ADC (при этом ADC_SR_OVR=1). Реализация: запускаю таймер на 1мс (заведомо больше чем время обработки ADC), обрабатываю массив полученных данных и перезапускаю ADC и DMA. Все вроде просто, однако не работает как надо. После инициализации корректные данные в памяти, т.е. ADC и DMA работают. А вот после этого получаю только 2-3-4... выборок, остальные "0". При этом NDTR=0, т.е. DMA передал все данные. Пробовал подключать прерывание DMA, там останавливать ADC и DMA, а по таймеру обрабатывать и перезапускать ADC и DMA - результат аналогичный. Что то я недопонимаю в связке ADC<->DMA, RM0090 перечитывал несколько раз. Кто сталкивался или хотя бы может кинуть идею куда рыть, прошу ответить. //настройка ADC1_IN10(PC.0), ADC1_IN11(PC.1), ADC1_IN12(PC.2), ADC1_IN13(PC.3) void instal_adc_dma(void) { // включаем тактирование ADC1, DMA2 and GPIO RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN | RCC_AHB1ENR_GPIOCEN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // вход - аналоговый GPIOC->MODER &= ~(uint32_t)(3 << 0*2 | 3 << 1*2 | 3 << 2*2 | 3 << 3*2); // конфигурируем 4-й поток DMA (0 канал) DMA2_Stream4->CR |= DMA_SxCR_MSIZE_0; // данные в памяти 2 байта DMA2_Stream4->CR |= DMA_SxCR_PSIZE_0; // данные в перефирии 2 байта DMA2_Stream4->CR |= DMA_SxCR_MINC; // инкремент указателя в памяти - ВКЛ // DMA2_Stream4->CR |= DMA_SxCR_TCIE; // прерывание по окончании передачи - ВКЛ DMA2_Stream4->M0AR = (uint32_t)&DataADC; // базовый адрес памяти DMA2_Stream4->PAR = (uint32_t)&(ADC1->DR); // базовый адрес переферии // DMA2->HIFCR |= DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4; DMA2_Stream4->NDTR = SAMPL_ADC * CHANNEL_ADC; // объем передаваемого блока // ADC1 (каналы 10-13) ADC1->SMPR1 |= ADC_SMPR1_SMP10_1 | ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP12_1 | ADC_SMPR1_SMP13_1; ADC1->SQR1 |= 4 << 20; ADC1->SQR3 |= 10<<0*5 | 11<<1*5 | 12<<2*5 | 13<<3*5; ADC1->CR1 |= ADC_CR1_SCAN; ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS; //старт DMA2_Stream4->CR |= DMA_SxCR_EN; // активация 4-го потока DMA2 ADC1->CR2 |= ADC_CR2_SWSTART; // запускаем преобразование return; } // таймер (1ms) void TIM7_IRQHandler(void) { TIM7->SR &= ~TIM_SR_UIF; // сбрасываем прерывание DMA2_Stream4->CR &= ~DMA_SxCR_EN; // деактивация 4-го потока DMA2 ADC1->SR &= ~ADC_SR_STRT; // останавливаем ADC //обработка выборок... // DMA2->HIFCR |= DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4; ADC1->SR &= ~ADC_SR_OVR; // сбрасываем флаг переполнения DMA2_Stream4->NDTR = SAMPL_ADC * CHANNEL_ADC; // объем передаваемого блока DMA2_Stream4->CR |= DMA_SxCR_EN; // активация 4-го потока DMA2 (как и было 0-ой канал) ADC1->CR2 |= ADC_CR2_SWSTART; // запускаем преобразование }