- void dma_config(void)
- {
- dma_parameter_struct dma_init_struct;
- rcu_periph_clock_enable(RCU_DMA);
- /* initialize DMA channel0 */
- dma_deinit(DMA_CH0);
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_addr = (uint32_t)ad_value;//指定DMA数据空间地址
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
- dma_init_struct.number = 48;
- dma_init_struct.periph_addr = (uint32_t)&(ADC_RDATA);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_init(DMA_CH0, dma_init_struct);
-
- /* configure DMA mode */
- dma_circulation_enable(DMA_CH0);
- dma_memory_to_memory_disable(DMA_CH0);
-
- /* enable DMA channel0 */
- dma_channel_enable(DMA_CH0);
- dma_interrupt_enable(DMA_CH0, DMA_INT_FTF);
- nvic_irq_enable(DMA_Channel0_IRQn , 0U, 0U);//配置中断优先级
- }
- void ADCSampleInit(void)
- {
- // rcu_periph_clock_enable(RCU_GPIOB);
- // gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);
- // gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
-
- dma_config();
- // ADCCLK = PCLK2/6
- rcu_adc_clock_config(RCU_ADCCK_APB2_DIV4);// ADC时钟27MHz
- rcu_periph_clock_enable(RCU_ADC);
- rcu_periph_clock_enable(RCU_GPIOA);
-
- //PA2,3,4,5,6
- gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE,
- GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
-
- // ADC channel length config 设置规则组的数量,转换扫描时按此数量扫描
- adc_channel_length_config(ADC_REGULAR_CHANNEL, 6);
- /* ADC regular channel config */
- adc_regular_channel_config(0, ADC_CHANNEL_2, ADC_SAMPLETIME_1POINT5);
- adc_regular_channel_config(1, ADC_CHANNEL_3, ADC_SAMPLETIME_1POINT5);
- adc_regular_channel_config(2, ADC_CHANNEL_4, ADC_SAMPLETIME_1POINT5);
- adc_regular_channel_config(3, ADC_CHANNEL_5, ADC_SAMPLETIME_1POINT5);
- adc_regular_channel_config(4, ADC_CHANNEL_6, ADC_SAMPLETIME_1POINT5);
- //Vrefin
- adc_regular_channel_config(5, ADC_CHANNEL_17, ADC_SAMPLETIME_13POINT5);//ADC_SAMPLETIME_13POINT5 1515 //ADC_SAMPLETIME_28POINT5 1462
- //adc_regular_channel_config(5, ADC_CHANNEL_16, ADC_SAMPLETIME_13POINT5);
- // Vrefin enable
- adc_tempsensor_vrefint_enable();
- /* ADC external trigger enable */
- adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
- /* ADC external trigger source config */
- adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
-
- /* ADC data alignment config */
- adc_data_alignment_config(ADC_DATAALIGN_RIGHT);//数据为右对齐
- /* enable ADC interface */
- adc_enable();
- /* ADC calibration and reset calibration */
- adc_calibration_enable();
- /* ADC SCAN function enable */
- adc_special_function_config(ADC_SCAN_MODE, ENABLE);//使能扫描模式
- /* ADC continuous mode function enable */
- adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE); //连续模式
- /* ADC DMA function enable */
- adc_dma_mode_enable();//使用ADC DMA, ADC的数据将会存入DMA模块中,这是定义的DMA数据空间为ad_value[]
-
- adc_software_trigger_enable(ADC_REGULAR_CHANNEL);// 软件出发一次采样
- }
原来就这个简单。
这里还要注意一个问题,就是采样时间,采样时间越短,输入的阻抗越小,这是如果你的信号是经过电阻分压后接入单片机的,那输入阻抗会改变电路设计上的分压比例,这时就要通过测量校准实际的比例值,比如电压经过300k+200K的电阻接到地,从两个电阻中间取信号,按电阻比例算分压比例是2/(3+2)=0.4,但若设置采样时间为1.5T,实际测出的比例是0.3355。
另一个是基准电压问题,如果VDDA不怎么稳定,会导致调试代码是容易中断,还有就是采集到的信号和实际偏差很大,这是可以通过采集弹片内部1.2V基准电压Vrefin得到的值反推出实际的VDDA的值,即实际采样值Vin=1.2xVrefinADC/VrefinADC.