Advertisement
petrdynin

CH32V003 ADC + DMA

Dec 30th, 2024
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.97 KB | None | 0 0
  1. volatile uint16_t adc_buff[4];
  2.  
  3. void ADC_Initialize(void){
  4.    
  5.     RCC->APB2PCENR |= RCC_APB2Periph_GPIOD;
  6.     // PD3 (ADC канал 4)
  7.     GPIOD->CFGLR &= ~GPIO_CFGLR_CNF3;
  8.     // PD2 (ADC канал 3)
  9.     GPIOD->CFGLR &= ~GPIO_CFGLR_CNF2;
  10.    
  11.      RCC->AHBPCENR |= RCC_AHBPeriph_DMA1;                  //Разрешаем тактирование первого DMA модуля
  12.      DMA1_Channel1->PADDR  = (uint32_t)&(ADC1->RDATAR);    //Указываем адрес периферии
  13.      DMA1_Channel1->MADDR  = (uint32_t)adc_buff;           //Задаем адрес памяти - базовый адрес массива в RAM
  14.      DMA1_Channel1->CFGR   &= ~DMA_CFGR1_DIR ;             //Указываем направление передачи данных, из периферии в память
  15.      DMA1_Channel1->CNTR   = 4;                            //Количество пересылаемых значений
  16.      DMA1_Channel1->CFGR   &= ~DMA_CFGR1_PINC;             //Адрес периферии не инкрементируем после каждой пересылки
  17.      DMA1_Channel1->CFGR   |= DMA_CFGR1_MINC;              //Адрес памяти инкрементируем после каждой пересылки
  18.      DMA1_Channel1->CFGR   |= DMA_CFGR1_PSIZE_0;           //Размерность данных периферии - 16 бит
  19.      DMA1_Channel1->CFGR   |= DMA_CFGR1_MSIZE_0;           //Размерность данных памяти - 16 бит
  20.      DMA1_Channel1->CFGR   |= DMA_CFGR1_PL;                //Приоритет - очень высокий
  21.      DMA1_Channel1->CFGR   |= DMA_CFGR1_CIRC;              //Разрешаем работу DMA в циклическом режиме
  22.      DMA1_Channel1->CFGR   |= DMA_CFGR1_TCIE;              //Разрешаем прерывание по окончанию передачи
  23.      DMA1_Channel1->CFGR   |= DMA_CFGR1_EN;                //Разрешаем работу 1-го канала DMA
  24.      
  25.      RCC->CFGR0 |= RCC_ADCPRE_DIV8;                        //тактовая частота АЦП не должна превышать 12MHz@3.3v
  26.      RCC->APB2PCENR |= RCC_APB2Periph_ADC1;                //разрешаем тактирование АЦП
  27.      //запускаем калибровку и ждем пока завершится
  28.      ADC1->CTLR1 =  (ADC1->CTLR1 & ~ADC_CALVOL_50PERCENT) | ADC_CALVOL_75PERCENT;
  29.      ADC1->CTLR2 |= ADC_ADON;
  30.      ADC1->CTLR2 |= ADC_RSTCAL;
  31.      while(ADC1->CTLR2 & ADC_RSTCAL);
  32.      ADC1->CTLR2 |= ADC_CAL;
  33.      while (ADC1->CTLR2 & ADC_CAL);
  34.      // Длина последовательности = 4; 3-й, 4-й, 8-й (Vref) и 9-й (Vcal) канал
  35.      ADC1->RSQR1 = 0x00300000;  // Установить длину последовательности на 4
  36.      ADC1->RSQR2 = 0x00000000;  // Пустой, поскольку длина последовательности мала
  37.      ADC1->RSQR3 = 0x0004A083;  // Установить последовательность каналов 3, 4, 8 (Vref), 9 (Vcal)
  38.      ADC1->CTLR1 |= ADC_SCAN;   // режим сканирования
  39.      //для 3, 4, 8, 9-го каналов между выборками 241 цикла
  40.      ADC1->SAMPTR2 = ADC_SMP3| ADC_SMP4 | ADC_SMP8 | ADC_SMP9;
  41.      //ADC1->CTRL1 |=  ADC_EOCIE;           // прерывание по окончанию преобразования
  42.      //NVIC_SetPriority(ADC_IRQn,1);
  43.      //NVIC_EnableIRQ(ADC_IRQn);
  44.      NVIC_SetPriority(DMA1_Channel1_IRQn,1);
  45.      NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  46.      // разрешение - запросов DMA, внешние запуски, внешний запуск от SWSTART, непрерывный режим преобразования
  47.      ADC1->CTLR2 |= ADC_DMA | ADC_EXTTRIG | ADC_EXTSEL | ADC_CONT;
  48.      //запускаем преобразование
  49.      ADC1->CTLR2 |= ADC_SWSTART;
  50.  }
  51.  
  52.  void DMA1_Channel1_IRQHandler (void){
  53.       DMA1->INTFCR |= DMA_CGIF1;
  54.   }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement