第9章 单片机模数转换器ADC 1 A/D转换实验电路 2 使用单片机内部的10位ADC转换器 (1) ADC相关的特殊功能寄存器 (2) 实例代码 1 A/D转换实验电路 模数转换就是将电路中连续变化的模拟电压信号转换为单片机可以识别的数 字信号,简称为A/D,实现模拟信号转换成数字信号的器件称为模数转换器, 称为ADC,ADC有专用的集成电路芯片,现在的新型单片机内部一般也集成有 ADC模块。
(1) ADC相关的特殊功能寄存器 1、 P1口模拟功能控制寄存器P1ASF,各位定义如表9-1所示,如果要使用相应 口的ADC输入功能,需将P1ASF特殊功能寄存器中的相应位置为1,比如:P1ASF |= 0x02; // 开启P1.1口的ADC输入功能。 表9-1 P1ASF(复位值为0000 0000B) 位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 位名称 | P17ASF | P16ASF | P15ASF | P14ASF | P13ASF | P12ASF | P11ASF | P10ASF |
2、ADC控制寄存器ADC_CONTR,各位定义如表9-2所示。 表9-2 ADC_CONTR(复位值为0000 0000B)
① ADC_POWER:ADC电源控制位。 0:关闭ADC电源。 1:打开ADC电源。 ② SPEED1、SPEED0:ADC转换速度控制位, 如表9-3所示,当被采样信号变化 频率较高时应使用高的转换频率(比如用ADC采样电路波形实现简易的示波 器),当对功耗限制严格时应使用低的转换频率。 表9-3 ADC转换速度控制
③ ADC_FLAG:A/D转换结束标志位。 A/D转换完成后,ADC_FLAG = 1,可由该位申请产生中断,或者由软件查询该标志位判 断A/D转换是否结束,此标志只能由软件清零。 ④ ADC_START:A/D转换启动控制位,ADC_START=1,启动转换,转换结束后为0。 ⑤ CHS2、CHS1、CHS0:模拟输入通道选择,如表所示。
3、ADC转换结果寄存器 ADC_RES、ADC_RESL ADC_RES[7:0]存放高8位ADC结果,ADC_RESL[1:0]存放低2位ADC结果。 ADC转换结果计算公式如下(Vin为模拟输入电压,Vcc为单片机实际供电电压): Vin = Vcc ×(ADC_RES[7:0],ADC_RESL[1:0])/1023 9.2.2、实例代码 9.2.2、实例代码 例9.1 IAP15W4K58S4单片机A/D转换程序,查询方式,测量结果电压值发送到计算机串口 助手显示,波特率9600/22.1184MHz,当使用配套实验板时,需要将跳线帽“AD/串口2”插接 到AD处。 #include "UART.H" | // | 包含IAP15W4K58S4寄存器定义文件 | #define VCC 4.970 unsigned int ADC_P11() | // | 存放用万用表实测的单片机供电电压 | { unsigned int i; | // | 用于软件延时程序 | unsigned char status; | // | 用于判断A/D转换结束的标志 | unsigned int AD_Dat=0; | // | 10位A/D转换值 | unsigned char Tmp; | // | 临时变量用于将A/D转换出来的2个字节合成一个字节 | ADC_CONTR|=0x80; | // | 开ADC转换器电源,第一次使用时要打开内部模拟电源 | for (i=0;i<10000;i++); | // | 适当延时等待ADC转换供电稳定,一般延时1ms以内即可, | P1ASF|=0x02; | // | 选择P1.1作为ADC转换通道,0x02= 0000 0010 |
ADC_CONTR=0xE1; // 选择P1.1作为ADC转换通道,最高转换速度,清转换完成标志。 for (i=0;i<1000;i++); // 如果是多通道模拟量进行A/D转换,则更换A/D转换通道后要延时200μs ADC_CONTR|=0x08; // 启动 A/D 转换,ADC_START=1。 status=0; while(status==0) // 等待A/D转换结束。 { status=ADC_CONTR&0x10; // 判断ADC_FLAG是否等于1,0x10=0001 0000B。 } ADC_CONTR&=0xE7; // 将ADC_FLAG清0,0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。 AD_Dat = ADC_RES; // 默认高字节高8位。 AD_Dat <<= 2; Tmp = ADC_RESL; // 默认低字节低2位。 Tmp &= 0x03; // 屏蔽无关位 AD_Dat |= Tmp; // 高低字节拼接成一个10位数。 return AD_Dat; } void main(void) { float Vin; // 存放计算出来的外部输入电压 unsigned int ADvalue; // 存放A/D转换返回的结果 UART_init(); // 串口初始化9600/22.1184MHz printf("串口初始化完毕"); while(1) { ADvalue=ADC_P11(); // 采样P1.1口模拟输入电压 Vin=VCC*ADvalue/1023; // 注意是1023才正确 printf("%.3f ",Vin); delay500ms(); } // 若不用串口显示,此行可设置断点仿真观察结果 }
|