找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 22081|回复: 5
打印 上一主题 下一主题
收起左侧

第9章 单片机模数转换器ADC

[复制链接]
跳转到指定楼层
楼主
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();
} // 若不用串口显示,此行可设置断点仿真观察结果
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:143203 发表于 2016-11-21 11:40 | 只看该作者
1023????为何不是1024份?
回复

使用道具 举报

板凳
ID:190932 发表于 2017-4-18 18:49 | 只看该作者
Y!NG 发表于 2016-11-21 11:40
1023????为何不是1024份?

0-1023  共有1024个数字  
回复

使用道具 举报

地板
ID:143203 发表于 2017-9-12 08:02 | 只看该作者
鲜衣怒马 发表于 2017-4-18 18:49
**** 作者被禁止或删除 内容自动屏蔽 ****

既然是1024个数字那分母为什么不除去1024
回复

使用道具 举报

5#
ID:255919 发表于 2019-1-1 21:18 | 只看该作者
这个程序没有问题,通过串口助手,可以直接观察输输出电压。就是接入IIC接口的OLED屏后,不能实时显示输出的电压
回复

使用道具 举报

6#
ID:994634 发表于 2023-12-7 20:40 | 只看该作者
受益了,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表