Читать ADC, используя DMA на STM32F103 с OpenCM3
Я пытаюсь прочитать 4 канала АЦП, используя движок dma на stm32f103c8t6.
Я пытаюсь добиться этого с помощью libopencm3 и не могу понять, чего не хватает.
Код должен делать следующее:
- настроить АЦП в режиме непрерывного сканирования, т.е. он должен преобразовать 4 значения и повторить
- Настройте DMA, чтобы скопировать значения из АЦП по мере их преобразования и поместить их в
dmaBuffer
dmaBuffer
следует использовать в качестве кольцевого буфера.
Однако он ничего не делает. Значения в dmaBuffer
никогда не меняется. Есть идеи, что мне не хватает?
static uint16_t dmaBuffer[] = {0, 0, 0, 0};
static void adc_setup()
{
rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0 |
GPIO1 | GPIO2 | GPIO3);
rcc_periph_clock_enable(RCC_ADC1);
adc_power_off(ADC1); //needs to be off for config
adc_enable_scan_mode(ADC1);
adc_set_continuous_conversion_mode(ADC1);
adc_disable_external_trigger_regular(ADC1);
adc_set_right_aligned(ADC1);
adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_71DOT5CYC);
adc_enable_dma(ADC1);
adc_power_on(ADC1);
/* Wait for ADC starting up. */
for(int i = 0; i < 800000; i++) //FIXME use delayms
__asm__("nop");
adc_reset_calibration(ADC1);
while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0);
adc_calibration(ADC1);
while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0);
uint8_t channels[] = {0, 1, 2, 3};
adc_set_regular_sequence(ADC1, 4, channels);
}
static void dma_setup()
{
//ADC1 ist h DMA1 channel 1
rcc_periph_clock_enable(RCC_DMA1);
dma_disable_channel(DMA1, DMA_CHANNEL1);
dma_channel_reset(DMA1, DMA_CHANNEL1);
dma_set_peripheral_address(DMA1, DMA_CHANNEL1, ADC1_DR);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_set_number_of_data(DMA1, DMA_CHANNEL1, 4);
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t)&dmaBuffer);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_enable_circular_mode(DMA1, DMA_CHANNEL1);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
dma_set_priority(DMA1, DMA_CHANNEL1, DMA_CCR_PL_MEDIUM);
dma_enable_channel(DMA1, DMA_CHANNEL1);
}