- void Adc_Init(void)
- {
- ADC_ConfigType adcConfig; /*! ADC初始化配置*/
- memset(&adcConfig, 0x00, sizeof(adcConfig)); /*! 清空结构体*/
- /*! ADC输入端口(MQ-5)配置*/
- GPIO_SetFunc(GPIOA, GPIO_PIN11, GPIO_FUN2); /*! PA10复用为FUN2,为ADC_IN1 ,对应电位器VR1*/
- /*! ADC输入端口(电位器)配置*/
- GPIO_SetFunc(GPIOA, GPIO_PIN10, GPIO_FUN2); /*! PA10复用为FUN2,为ADC_IN1 ,对应电位器VR1*/
- /*! ADC配置
- ADC固定为12位分辨率,工作模式为MODE3(工作模式内容见参考手册8.4.2章节),规则组扫描+注入组扫描模式多通道单次转换,规则组长度为3,注入组长度为0
- 每触发一次进行一次ADC转换,每次转换规则组中的3个通道。
- */
- adcConfig.clkPsc = ADC_CLK_PRESCALER_2; /*! ADC时钟分频设置,Set ADC Clk = APB时钟频率/(clkPsc + 1) = 16M/2 = 8M */
- adcConfig.scanModeEn = ENABLE; /*! 模式配置SCAN:扫描模式使能位 多通道需使能扫描模式,单通道则不需要使能*/
- adcConfig.continuousModeEn = DISABLE; /*! 模式配置CONT:连续模式使能位 0:触发一次后只转换一次,1:触发后可连续转换*/
- adcConfig.regularDiscontinuousModeEn = DISABLE; /*! 模式配置DISCEN:打开规则组间断转换模式*/
- adcConfig.injectDiscontinuousModeEn = DISABLE; /*! 模式配置IDISEN:打开注入组间断转换模式*/
- adcConfig.injectAutoModeEn = DISABLE; /*! 模式配置IAUTO:自动注入模式*/
- adcConfig.intervalModeEn = DISABLE; /*! 模式配置INTERVAL:注入组为间隔转换模式*/
- adcConfig.regularDiscontinuousNum = 0; /*! 规则组子组长度,用于Mode7和Mode8*/
- adcConfig.interruptEn = DISABLE; /*! 总中断使能*/
- adcConfig.voltageRef = ADC_VOLTAGEREF_VDDA; /*! ADC参考源选择 */
- adcConfig.regularTriggerMode = ADC_TRIGGER_INTERNAL; /*! 规则组触发源类型选择*/
- adcConfig.injectTriggerMode = ADC_TRIGGER_INTERNAL; /*! 注入组触发源类型选择*/
- adcConfig.regularSequenceLength = 3; /*! 规则组长度*/
- adcConfig.injectSequenceLength = 0; /*! 注入组长度*/
- adcConfig.dataAlign = ADC_DATA_ALIGN_RIGHT; /*! 数据右对齐*/
- adcConfig.callBack = NULL; /*! ADC回调函数*/
- adcConfig.powerMode = ADC_POWER_ON; /*! ADC上电*/
- ADC_Init(ADC0, &adcConfig); /*! ADC works Mode Config*/
- /*!
- ADC转换率计算公式:
- 总转换时间=(SPT+ 12)/ADC时钟频率+5个APB时钟周期
- 备注:
- 1.SPT为采样周期个数,具体见下面ADC_SPT_CLK_x。
- 2.ADC时钟频率 = APB时钟频率 /(分频系数+1)
- 3.7802x ADC支持的最高采样率为250Ksps(即转换时间不低于4us),如果配置采样率高于该值,可能会导致采样结果精度显著减低。
- */
- /*规则组通道转换序列和转换速率配置*/
- ADC_SetRegularGroupChannel(ADC0, ADC_CH_0, ADC_SPT_CLK_33, 0); /*! 采样&转换时间= (33+12)/8000000 + 5/16000000 ≈ 5.94us */
- ADC_SetRegularGroupChannel(ADC0, ADC_CH_1, ADC_SPT_CLK_33, 1); /*! 采样&转换时间= (33+12)/8000000 + 5/16000000 ≈ 5.94us */
- ADC_SetRegularGroupChannel(ADC0, ADC_CH_VIN, ADC_SPT_CLK_33, 2); /*! 采样&转换时间= (33+12)/8000000 + 5/16000000 ≈ 5.94us */
- /*! Bandgap或T-sensor内部通道配置*/
- ADC_SetInternalChannel(ADC0, ADC_INTERNAL_TSENSOR); /*! 内部电压信号选择(仅在使用了ADC_CH_VIN 时配置) */
- ADC_SetVBufEnableFlag(ADC0, ENABLE); /*! Bandgap和T-sensor内部通道使能(仅在使用了ADC_CH_VIN 时配置) */
- }
## 3.2 ADC值读取以及打印
- 首先使用软件方式启动ADC0转换
- 然后等待转换完成
- 最后读取转换结果并将AN0和AN1的转换结果转变为mV为单位
- 将温度读取结果转换为实际温度值
- void Adc_SwTrigger(void)
- {
- ADC_SoftwareStartRegularConvert(ADC0); /*! 软件触发规则组采样*/
- while (!ADC_GetEOCFlag(ADC0, 2)) /*! 等待规则组最后一个通道转换完成*/
- {
- /* Wait */
- }
- g_adc_RegularArray[0] = (ADC_GetRegularData(ADC0, 0) * 3300 / 4096); /*! 获取规则组0的转换值*/
- g_adc_RegularArray[1] = (ADC_GetRegularData(ADC0, 1) * 3300 / 4096); /*! 获取规则组1的转换值*/
- g_adc_RegularArray[2] = ADC_GetRegularData(ADC0, 2); /*! 获取规则组2的转换值*/
- float T_Sensor_V = ((float)g_adc_RegularArray[2] * 3.3 / 4096.0);
- printf ("-->%f\n", T_Sensor_V);
- float T_Sensor = (0.705 - T_Sensor_V) / -1.709 + 25;
- /*! 打印ADC各通道转换结果*/
- printf("ADC Regular value: MQ-5 = %04dmV VR1 = %04dmV TSENSOR = %.2fCentigrade \r\n", g_adc_RegularArray[0], g_adc_RegularArray[1], T_Sensor);
- }
## 3.3 主函数
主函数调用ADC进行转换,如下:
- Adc_Init();
- while(1)
- {
- Adc_SwTrigger();
- for (int i = 0; i < 1000; i++)
- for (int j = 0; j< 10000; j++);
- }
# 4 实验效果
下面是打印结果,第一个数字是MQ-5采集的可燃气体浓度值,第二个电位器采样值,第三个是采集的芯片内部温度。
1. 电位器采样果
2. MQ-5可燃气体采样结果:将打火机内部甲烷气体释放出来,靠近MQ-5即可进行测试,测试图以及测试结果如下: