【目的】驱动ADC外设,并初始测量ADC的精度。这里使用PA1做为采集IO,使用定时器触发,DMA数据传输。
1、配置ADC0、DMA、定时器的时钟
- void rcu_config(void)
- {
- /* enable GPIOA clock */
- rcu_periph_clock_enable(RCU_GPIOA);
- /* enable ADC0 clock */
- rcu_periph_clock_enable(RCU_ADC0);
- /* enable ADC1 clock */
- //rcu_periph_clock_enable(RCU_ADC1);
- /* enable DMA0 clock */
- rcu_periph_clock_enable(RCU_DMA0);
- /* enable timer1 clock */
- rcu_periph_clock_enable(RCU_TIMER1);
- /* config ADC clock */
- rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
- }
2、配置PA1
- void gpio_config(void)
- {
- /* config the GPIO as analog mode */
- gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
- }
3、配置DMA
- void dma_config(void)
- {
- /* ADC_DMA_channel configuration */
- dma_parameter_struct dma_data_parameter;
- /* ADC DMA_channel configuration */
- dma_deinit(DMA0, DMA_CH0);
- /* initialize DMA data mode */
- dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
- dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_data_parameter.memory_addr = (uint32_t)(&adc_value);
- dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_32BIT;
- dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_32BIT;
- dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_data_parameter.number = 1;
- dma_data_parameter.priority = DMA_PRIORITY_HIGH;
- dma_init(DMA0, DMA_CH0, &dma_data_parameter);
- dma_circulation_enable(DMA0, DMA_CH0);
- /* enable DMA channel */
- dma_channel_enable(DMA0, DMA_CH0);
- }
4、配置定时器:
- void timer_config(void)
- {
- timer_oc_parameter_struct timer_ocintpara;
- timer_parameter_struct timer_initpara;
- /* TIMER1 configuration */
- timer_struct_para_init(&timer_initpara);
- timer_initpara.prescaler = 5399;
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 9999;
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
- timer_initpara.repetitioncounter = 0;
- timer_init(TIMER1,&timer_initpara);
- /* CH0 configuration in PWM mode1 */
- timer_channel_output_struct_para_init(&timer_ocintpara);
- timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
- timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
- timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocintpara);
- timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, 3999);
- timer_channel_output_mode_config(TIMER1, TIMER_CH_1, TIMER_OC_MODE_PWM1);
- timer_channel_output_shadow_config(TIMER1, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
- }
5、配置ADC0:
- void adc_config(void)
- {
- /* reset ADC */
- adc_deinit(ADC0);
- /* ADC mode config */
- adc_mode_config(ADC_DAUL_REGULAL_PARALLEL);
- /* ADC continous function enable */
- adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
- /* ADC data alignment config */
- adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
- /* ADC channel length config */
- adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 2);
- /* ADC regular channel config */
- adc_regular_channel_config(ADC0, 0, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
- adc_regular_channel_config(ADC0, 1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
- /* ADC trigger config */
- adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_T1_CH1);
- /* ADC external trigger enable */
- adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
- /* enable ADC interface */
- adc_enable(ADC0);
- /* ADC calibration and reset calibration */
- adc_calibration_enable(ADC0);
- delay_1ms(1);
- /* ADC DMA function enable */
- adc_dma_mode_enable(ADC0);
- }
6、在主函数主读取DMA中的数据并用OLED显示:
- float vref_value ;
- int value_h,value_l;
- int main(void) {
- uint8_t v_show[10];
- /* system clocks configuration */
- rcu_config();
- /* GPIO configuration */
- gpio_config();
- /* TIMER configuration */
- timer_config();
- /* DMA configuration */
- dma_config();
- /* ADC configuration */
- adc_config();
- /* enable TIMER1 */
- timer_enable(TIMER1);
- led_init();
- key_init();
- my_i2c0_init();
- gd_eval_com_init();
- printf("GD32VF103rn");
- oled_display_test();
- delay_1ms(2000);
- oled_clear();
- OLED_ShowStr(2,0,"GD32VF103R",24);
- while (1) {
- //sta_flash(key_sta);
- printf("rn ADC0 regular channel 0 data = %08X rn",adc_value[0]);
- vref_value = (adc_value[0] * 3.3f/4096);
- value_h = (int)vref_value;
- vref_value = (vref_value-value_h)*1000;
- value_l = (int)vref_value;
- printf(" the Reference voltage data is %2d.%03dV rn", value_h,value_l);
- sprintf(v_show,"%d.%03dV",value_h,value_l);
- OLED_ShowStr(18,3,v_show,24);
- delay_1ms(1000);
- }
- }
【总结】用定时器触发ADC采集数据,DMA传输。获取的数据没有处理,但是精度还算可以,目测在正负0.03之间。