Код:
Добрый день!
Имеется контролер F030F4P6.
Нужно настроить 2 канала АЦП через DMA.
Так же имеется документ (RM0360) к нему, собственно по нему и велись настройки.
Проблема в том что не запускается. Ничего не измеряет. Выводит переменную на дисплей всегда "0"
В отладчике показывает что все настройки проходят а самого преобразования нет! И даже нет прерывания
по отправке по DMA ( конец передачи ). Я в хендлере установил переменную (DMA_Counter++;) чтобы как-то
смотреть что происходит, но ничего не происходи переменная не инкрементируется похоже что запросов нет.
Приложу код настроек ADC и DMA.
Кто знает укажите пожалуйста где я ошибся?
Последний кусок кода он расположен в main. Перед функцией int main(void).
Код:
void ADC_DMA_Init(void){
//---------- ADC_DMA_PA3_PA4 ----------
MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER3_Msk, 0b11 << GPIO_MODER_MODER3_Pos); // PA3 аналог.режим
MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER4_Msk, 0b11 << GPIO_MODER_MODER4_Pos); // PA4 аналог.режим
MODIFY_REG(ADC1->CFGR2, ADC_CFGR2_CKMODE_Msk, 0b01 << ADC_CFGR2_CKMODE_Pos); // Поделить 48 мГц/2 = 12 мГц
SET_BIT(RCC->AHBENR, RCC_AHBENR_DMAEN); // Подать тактирование на DMA
DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR); // Откуда брать...
DMA1_Channel1->CMAR = (uint32_t)Adc; // Куда ложить...
DMA1_Channel1->CNDTR = 2; // Кол-во байт для передачи...
MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_PL_Msk, 0b01 << DMA_CCR_PL_Pos); // Приоритет канала "средний"
CLEAR_BIT(DMA1_Channel1->CCR, DMA_CCR_DIR); // Из перифирии
SET_BIT(DMA1_Channel1->CCR, DMA_CCR_CIRC); // Непрерывный режим DMA включён
MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_MSIZE_Msk, 0b01 << DMA_CCR_MSIZE_Pos); // Размер памяти 16
MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_PSIZE_Msk, 0b01 << DMA_CCR_PSIZE_Pos); // Размер периферии 16
SET_BIT(DMA1_Channel1->CCR, DMA_CCR_TCIE); // Прерывание от DMA включено
SET_BIT(DMA1_Channel1->CCR, DMA_CCR_MINC); // Инкремент памяти включён
SET_BIT(DMA1_Channel1->CCR, DMA_CCR_EN); // Канал 1 DMA включён
SET_BIT(ADC1->CFGR1, ADC_CFGR1_DMAEN); // Подключить DMA
SET_BIT(ADC1->CFGR1, ADC_CFGR1_DMACFG); // Циклическое преобразование DMA
NVIC_EnableIRQ(DMA1_Channel1_IRQn); // Прерывание от DMA включено
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN); // Подать тактирование на ADC1
while(READ_BIT(ADC1->ISR, ADC_ISR_ADRDY)); // Ждать пока не включится ADC1
CLEAR_BIT(ADC1->CR, ADC_CR_ADEN); // Пока выключить ADC для нстройки
SET_BIT(ADC1->CR, ADC_CR_ADCAL); // Откалиброать ADC
while(READ_BIT(ADC1->ISR, ADC_CR_ADCAL)); // Ожидать окончания калибровки
//(0b000 1.5) (0b001 7.5) (0b010 13.5) (0b011 28.5) (0b100 41.5) (0b101 55.5) (0b110 71.5) (0b111 239.5) тактов
// Применяется к всем каналам ADC
MODIFY_REG(ADC1->SMPR, ADC_SMPR_SMP_Msk, 0b111 << ADC_SMPR_SMP_Pos); // Сэмплинг
SET_BIT(ADC1->CFGR1, ADC_CFGR1_OVRMOD); // Данные перезаписываются новыми
SET_BIT(ADC1->CFGR1, ADC_CFGR1_CONT); // Режим непрерывного преобразования ADC
CLEAR_BIT(ADC1->CFGR1, ADC_CFGR1_SCANDIR); // от CHSEL3 к CHSEL4
SET_BIT(ADC1->CHSELR, ADC_CHSELR_CHSEL3); // Канал 3 PA3
SET_BIT(ADC1->CHSELR, ADC_CHSELR_CHSEL4); // Канал 4 PA34
// ---------- DMA_CH1 ----------
SET_BIT(ADC1->CR, ADC_CR_ADEN); // Включить ADC
SET_BIT(ADC1->CR, ADC_CR_ADSTART); // Запустить преобразование ADC
}
void DMA1_Channel1_IRQHandler(void){ // Обработчик для DMA
if(READ_BIT(DMA1->ISR, DMA_ISR_TCIF1)){
SET_BIT(DMA1->IFCR, DMA_IFCR_CTCIF1); // Сбросить флаг прерывания предачи канала 1
}
DMA_Counter++;
}