本文最后更新于21 天前,其中的信息可能已经过时,如有错误请发送邮件到tudougin@163.com
1. BAT内的A/D转换器
A/D转换器是将模拟输入转换为数字值的转换器,最多能控制18个模拟通道的A/D转换(15个引脚输入通道和3个内部通道)。ANI0~ANI14,PGA0,PGA1和温度传感器中选择1个通道的模拟输入,重复进行12位分辨率的A/D转换。每结束1次A/D转换,就产生中断请求(INTAD)(选择模式的情况)。
分类 | 模式 | 说明 |
---|---|---|
触发模式 | 软件触发 | 通过软件操作启动转换 |
硬件触发无等待模式 | 检测到硬件触发信号立即开始转换 | |
硬件触发等待模式 | 在A/D电源关闭的待机状态下,检测硬件触发后: 1. 自动上电 2. 等待电源稳定 3. 开始转换 | |
通道选择模式 | 选择模式 | 单个通道的模拟输入进行转换 |
扫描模式 | 顺序转换4个连续通道(可配置AN10~AN14范围内的任意连续4通道) | |
转换模式 | 单次转换模式 | 对选定通道执行单次转换 |
连续转换模式 | 持续转换选定通道,直到软件强制停止 | |
采样时间 | 5.5~255个ADC时钟周期 | 通过ADNSMP寄存器配置,默认使用13.5个转换时钟(对应频率fADfAD) |
2. ADC代码
2.1 ADC配置
调用官方库函数初始化 ADC 模块。默认会根据预设的宏定义初始化工作模式、触发方式、参考电压等。
ADC_Init();
PORT->PMC
寄存器用于将普通 IO 配置为模拟功能(ANIx)。
特别注意以下两个点:
P25
/P26
:如果使用AVREFP/AVREFM
外部参考电压时必须设置。P30
~P37
:是计划启用的模拟通道(ANI7 ~ ANI14)。
#define ADC_PORT_SETTING() do{ \
PORT->PMC2 |= 0x20U;/* Set ANI5(P25) pin: It is necessary for ADC_VREF_AVREFP_AVREFM, used as AVREFM */ \
PORT->PMC2 |= 0x40U;/* Set ANI6(P26) pin: It is necessary for ADC_VREF_AVREFP_AVREFM, used as AVREFP */ \
PORT->PMC3 |= 0x01U;/* Set ANI7(P30) pin */ \
PORT->PMC3 |= 0x02U;/* Set ANI8(P31) pin */ \
PORT->PMC3 |= 0x04U;/* Set ANI9(P32) pin */ \
PORT->PMC3 |= 0x08U;/* Set ANI10(P33) pin */ \
PORT->PMC3 |= 0x10U;/* Set ANI11(P34) pin */ \
PORT->PMC3 |= 0x20U;/* Set ANI12(P35) pin */ \
PORT->PMC3 |= 0x40U;/* Set ANI13(P36) pin */ \
PORT->PMC3 |= 0x80U;/* Set ANI14(P37) pin */ \
}while(0)
设定以下宏,会在 ADC_Init()
内部被条件编译使用,影响寄存器设置。
#define ADC_OPERMODE_SELECT /* 单通道选择模式 */
#define ADC_TRIGGER_SOFTWARE /* 软件触发 */
#define ADC_CONVMODE_ONESHOT /* 一次性转换 */
#define ADC_VREF_VDD_VSS /* 使用内部 VDD/VSS 作为参考电压 */
2.2 ADC读取
uint16_t get_value[8];
typedef enum
{
ADC_CHANNEL_0,
ADC_CHANNEL_1,
ADC_CHANNEL_2,
ADC_CHANNEL_3,
ADC_CHANNEL_4,
ADC_CHANNEL_5,
ADC_CHANNEL_6,
ADC_CHANNEL_7,
ADC_CHANNEL_8,
ADC_CHANNEL_9,
ADC_CHANNEL_10,
ADC_CHANNEL_11,
ADC_CHANNEL_12,
ADC_CHANNEL_13,
ADC_CHANNEL_14,
ADC_CHANNEL_OFF,
ADC_CHANNEL_PGA0 = 16U,
ADC_CHANNEL_PGA1 = 32U,
ADC_TEMPERSENSOR0 = 128U,
ADC_INTERREFVOLT
} adc_channel_t;
ADC_Converse(ADC_CHANNEL_2, sizeof(get_value)/sizeof(get_value[0]), get_value);
ADC_Converse
函数用于在软件触发模式下,进行指定通道的多次 ADC 转换,并将每次的结果保存在提供的缓存区中,最终返回所有采样值的平均结果。适用于轮询方式读取数据的应用场景。
3. 示例代码
3.1 读取模拟引脚电压
本示例实现通过软件触发方式读取模拟引脚 P3.7(通道 14)上的电压值,并根据 VDD = 3.3V 参考电压换算为实际电压(单位:mV)后输出。采用单次采样模式,数据精度为 12 位(0 ~ 4095)。
配置说明:
- 采样引脚:P3.7
- 模拟通道编号:ADC Channel 14
- 触发方式:软件触发(非自动/中断)
- 采样模式:单次采样(Single Conversion)
- 参考电压:VDD(正参考)、VSS(负参考)
#include "adc.h"
#define ADC_PORT_SETTING() do{ \
PORT->PMC2 |= 0x20U;/* Set ANI5(P25) pin: It is necessary for ADC_VREF_AVREFP_AVREFM, used as AVREFM */ \
PORT->PMC2 |= 0x40U;/* Set ANI6(P26) pin: It is necessary for ADC_VREF_AVREFP_AVREFM, used as AVREFP */ \
PORT->PMC3 |= 0x80U;/* Set ANI14(P37) pin */ \
}while(0)
void main(void){
ADC_Init(); //如果需更改采样模式,根据ADC_Init的代码,更改代码中的定义宏
while(1){
uint16_t get_value[8] = {0};
uint16_t adcValue = ADC_Converse(ADC_CHANNEL_14, sizeof(get_value)/sizeof(get_value[0]), get_value);
printf("adcValue = %d,Volt = %d mV",adcValue,adcValue*3300/4096);
delayMs(1000);
}
}