Читать 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);
}

0 ответов

Другие вопросы по тегам