【GD32F310G-START评测】评测3: GD32F301开发板 ADC模块
[复制链接]
本帖最后由 cjwmusic 于 2022-6-21 04:09 编辑
概述
- 逐次逼近方式
- 12 位分辨率(可配置12,10, 8, 6位)
- 看门狗检测
- 16个外部通道、2个内部通道、电池电压通道
- 转换模式:单次、连续、扫描、间断
- 转换结果:16位,左对齐/右对齐
- 硬件过采样机制
实验
本次ADC实验,采用一个 10K的 3296封装的滑动变阻器来模拟外部的、可变的模拟信号输入量,输入 GD32 的模拟输入引脚,在内部转换后,将转换的数字结果显示在 LCD 上。
模拟部分电路原理图
RV1 为最大阻值为100K 的滑动变阻器,引脚2输出可变电压到 GD32 单片机模拟引脚,
R1 为阻值为10K 的电阻,起到限流的作用。
这里为了实验方便,电路比较简单,实际的ADC采样电路还需要添加滤波放大等电路,
并且要将模拟供电电源尽量和数字分开,本实验中使用的是同一个 3.3v 的电源。
面包板搭建的实验电路
实验电路的验证
在完成实验电路的搭建后,一边转动滑动变阻器调节旋钮,一边采用示波器测量滑动变阻器 2 引脚的电压,发现电压波形随着调节在逐渐变化,说明模拟部分的电路搭建没有问题。
软件编写
- ADC时钟配置
- ADC GPIO配置
- ADC 配置
ADC 时钟配置
从用户手册的时钟树上我们可以看到 ADC 的时钟可以有三个来源:
- APB2 的时钟经过分频得到
- AHB 的时钟经过分频得到
- IRC 28M 时钟分频得到
通过设置配置寄存器2(RCU_CFG2) 的 ADCSEL 位来选择ADC时钟源,
在使用库函数编程时,通过 rcu_adc_clock_config 方法来配置。
具体的ADC 时钟配置代码如下:
// ADC 时钟使能
rcu_periph_clock_enable(RCU_ADC);
//ADC 时钟通过APB2时钟6分频获得
rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
GPIO 配置
ADC 外部输入通道与 GPIO 引脚的对应关系
ADC 引脚 |
GPIO 引脚 |
ADC_IN0 - ADC_IN7 |
PA0 - PA7 |
ADC_IN8 - ADC_IN9 |
PB0 - PB1 |
由于PA引脚用于驱动 LCD, 所以本实验中使用 PB0 引脚作为模拟输入。
ADC 引脚需要配置成输入模式,并且无上拉下拉电阻,
具体配置代码如下:
gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);
ADC 配置
ADC的配置主要有:
转换模式 |
单次 |
转换结果对齐方式 |
右对齐 |
转换通道个数 |
1 |
外部触发配置 |
无需外部触发 |
ADC 采样精度 |
12位采样精度 |
ADC 采样时间配置 |
55.5个时钟周期 |
ADC 中断配置 |
转换完成触发中断 |
具体代码如下:
// 单通道用连续转换模式
adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
// 转换结果转换右对齐
adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
// 转换通道1个
adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
// 不用外部触发转换,软件开启即可
adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
// ADC 采样精度配置
adc_resolution_config(ADC_RESOLUTION_12B);
// 使能ADC
adc_enable();
delay_1ms(1);
// 使能ADC校准
adc_calibration_enable();
// ADC 采样通道、采样时间
adc_regular_channel_config(0, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
// 使能 ADC 中断
nvic_irq_enable(ADC_CMP_IRQn, 1, 1);
// 清除 ADC 规则组转换结束中断标志
adc_interrupt_flag_clear(ADC_INT_FLAG_EOC);
// 使能 ADC 规则组转换结束中断
adc_interrupt_enable(ADC_INT_EOC);
// 软件触发ADC转换
adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
中断代码:
void ADC_CMP_IRQHandler(void)
{
// 清除中断标志位
adc_interrupt_flag_clear(ADC_INT_FLAG_EOC);
// 读取转换结果
adcValue = adc_regular_data_read();
LCD_write_english_string(0, 10, "ADC Value:");
LCD_write_number(20, 20, adcValue);
}
最终实验效果
全部的代码,我上传到了 github, 大家有兴趣的可以下载使用:
https://github.com/jwkongkong/GD32-NOKIA-5110
欢迎大家交流和指正~
|