1.目的
在工业控制过程中,它是控制系统与微机之间不可缺少的接口方式。要实现自动控制,就要检测有关参数,A/D转换器,把检测到的电压或电流信号(模拟量)转换成计算机能够识别的等效数字量,这些数字量经过计算机处理后输出结果,通过D/A转换器变为电压或电流信号,送到执行机构,达到控制某种过程的目的。
2.与A/D转换相关的寄存器
与STC15系列单片机A/D转换相关的寄存器列于下表所示。
符号 | 描述 | 地址 | 位地址及其符号 MSB LSB | 复位值 | |||||||
P1ASF | P1 Analog Function Configure register | 9DH | P17ASF | P16ASF | P15ASF | P14ASF | P13ASF | P12ASF | P11ASF | P10ASF | 0000 0000B |
ADC_CONTR | ADC Control Register | BCH | ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0 | 0000 0000B |
ADC_RES | ADC Result high | BDH | 0000 0000B | ||||||||
ADC_RESL | ADC Result low | BEH | 0000 0000B | ||||||||
CLK_DIV PCON2 | 时钟分频寄存器 | 97H | MCKO_S1 | MCKO_S0 | ADRJ | Tx_Rx | Tx2_Rx2 | CLKS2 | CLKS1 | CLKS0 | 0000 x000B |
IE | Interrupt Enable | A8H | EA | ELVD | EADC | ES | ET1 | EX1 | ET0 | EX0 | 0000 0000B |
IP | Interrupt Priority Low | B8H | PPCA | PLVD | PADC | PS | PT1 | PX1 | PT0 | PX0 | 0000 0000B |
2.1.P1口模拟功能控制寄存器P1ASF
STC15系列单片机的A/D转换口在P1口(P1.7-P1.0),有8路10位高速A/D转换器,速度可达到300KHz(30万次/秒)。8路电压输入型A/D,可做温度检测、电池电压检测、按键扫描、频谱检测等。上电复位后P1口为弱上拉型I/O口,用户可以通过软件设置将8路中的任何一路设置为A/D装换,不需作为A/D使用的P1口可继续作为I/O口使用(建议只作为输入)。需作为A/D使用的口需先将P1ASF特殊功能寄存器中的相应位置为‘1’,将相应的口设置为模拟功能。P1ASF寄存器的格式如下:
P1ASF:P1口模拟功能控制寄存器(该寄存器是只写寄存器,读无效)
SFR name | Adess | Bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
P1ASF | 9DH | Name | P17ASF | P16ASF | P15ASF | P14ASF | P13ASF | P12ASF | P11ASF | P10ASF |
P1ASF[7:0] | P1.x的功能 | 其中P1ASF寄存器地址为:[9DH](不能进行位寻址) |
P1ASF.0 = 1 | P1.0口作为模拟功能A/D使用 | |
P1ASF.1 = 1 | P1.1口作为模拟功能A/D使用 | |
P1ASF.2 = 1 | P1.2口作为模拟功能A/D使用 | |
P1ASF.3 = 1 | P1.3口作为模拟功能A/D使用 | |
P1ASF.4 = 1 | P1.4口作为模拟功能A/D使用 | |
P1ASF.5 = 1 | P1.5口作为模拟功能A/D使用 | |
P1ASF.6 = 1 | P1.6口作为模拟功能A/D使用 | |
P1ASF.7 = 1 | P1.7口作为模拟功能A/D使用 |
2.2. ADC_CONTR
ADC_CONTR寄存器的格式如下:
ADC_CONTR:ADC控制寄存器
SFR name | Adess | Bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
ADC_CONTR | BCH | name | ADC_POWER | SPEED1 | SPEED0 | ADC_FLAG | ADC_START | CHS2 | CHS1 | CHS0 |
对ADC_CONTR寄存器进行操作,建议直接用MOV赋值语句,不要用‘与’和‘或’语句。
ADC_POWER:ADC电源控制位。
0:关闭ADC电源;
1:打开A/D转换器电源。
建议进入空闲模式和掉电模式前,将ADC电源关闭,即ADC_POWER = 0,可降低功耗。启动A/D转换前一定要确认A/D电源已打开,A/D转换结束后关闭A/D电源可降低功耗,也可不关闭。初次打开内部A/D转换模拟电源,需适当延时,等内部模拟电源稳定后,再启动A/D转换。
建议启动A/D转换后,在A/D转换结束之前,不改变任何I/O口的状态,有利于高精度A/D转换,如能将定时器/串行口/中断系统关闭更好。
SPEED1,SPEED0:模数转换器转换速度控制位
SPEED1 | SPEED0 | A/D转换所需时间 |
1 | 1 | 90个时钟周期转换一次,CPU工作频率21MHz时,A/D转换速度约300MHz |
1 | 0 | 180个时钟周期转换一次 |
0 | 1 | 360个时钟周期转换一次 |
0 | 0 | 540个时钟周期转换一次 |
ADC_FLAG:模数转换器转换结束标志位,当A/D转换完成后,ADC_FLAG = 1,要由软件清0。不管是A/D转换完成后由该位申请产生中断,还是由软件查询该标志位A/D转换是否结束,当A/D转换完成后,ADC_FLAG = 1,一定要软件清0。
ADC_START:模数转换器(ADC)转换启动控制位,设置为“1”时,开始转换,转换结束后为0。
CHS2/CHS1/CHS0:模拟输入通道选择,CHS2/CHS1/CHS0
CHS2 | CHS1 | CHS0 | Analog Channel Select |
0 | 0 | 0 | 选择P1.0作为A/D输入来用 |
0 | 0 | 1 | 选择P1.1作为A/D输入来用 |
0 | 1 | 0 | 选择P1.2作为A/D输入来用 |
0 | 1 | 1 | 选择P1.3作为A/D输入来用 |
1 | 0 | 0 | 选择P1.4作为A/D输入来用 |
1 | 0 | 1 | 选择P1.5作为A/D输入来用 |
1 | 1 | 0 | 选择P1.6作为A/D输入来用 |
1 | 1 | 1 | 选择P1.7作为A/D输入来用 |
2.3.ADC转换结果调整寄存器位—ADRJ
ADC转换结果调整控制位——ADRJ位于寄存器CLK_DIV/PCON中,用于控制ADC转换结果存放的位置。
Mnemonic | Add | Name | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | Reset Value |
CLK_DIV | 98H | 时钟寄存器 | MCKO_S1 | MCKO_S0 | ADRJ | Tx_Rx | Tx2_Rx2 | CLKS2 | CLKS1 | CLKS0 | 0000,x000 |
ADRJ:ADC转换结果调整
0:ADC_RES[7:0]存放高8位ADC结果,ADC_RESL[1:0]存放低2位ADC结果
1:ADC_RES[1:0]存放高2位ADC结果,ADC_RESL[7:0]存放低8位ADC结果
Mnemonic | Add | Name | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
ADC_RES | BDh | A/D转换结果寄存器高 | ||||||||
ADC_RES | BDh | A/D转换结果寄存器低 | ||||||||
CLK_DIV | 97H | 时钟分频寄存器 | MCKO_S1 | MCKO_S0 | ADRJ | Tx_Rx | TX2_Rx2 | CLKS2 | CLKS1 | CLKS0 |
2.4.A/D转换结果寄存器ADC_RES、ADC_RESL
特殊功能寄存器ADC_RES和ADC_RESL寄存器用于保存A/D转换结果,其格式如下:
AUXRI寄存器的ADRJ位是A/D转换结果寄存器(ADC_RES、ADC_RESL)的数据格式调整控制位。
当ADRJ = 0时,10位A/D转换结果的高8位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中。
Mnemonic | Add | Name | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
ADC_RES | BDh | A/D转换结果寄存器高8位 | ADC_RES7 | ADC_RES6 | ADC_RES5 | ADC_RES4 | ADC_RES3 | ADC_RES2 | ADC_RES3 | ADC_RES2 |
ADC_RES | BDh | A/D转换结果寄存器低2位 | - | - | - | - | - | - | ADC_RES1 | ADC_RES0 |
CLK_DIV | 97H | 时钟分频寄存器 | ADRJ = 0 |
此时,如果用户需取完整10位结果,按下面公式计算:
10-bit A/D ConversionResult:(ADC_RES[7:0],ADC_RESL1:0]) = 1024*Vin/Vcc
如果用户只需取8位结果,按下面公式计算:
8-bit A/D ConversionResult:(ADC_RES[7:0]) = 256*Vin/Vcc
式中,Vin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作
电压作为模拟参考电压。
当ADRJ = 1时,10位A/D转换结果的高2位存放在ADC_RES的低2位中,低8位存放在ADC_RESL中。
Mnemonic | Add | Name | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
ADC_RES | BDh | A/D转换结果寄存器高2位 | - | - | - | - | - | - | ADC_RES9 | ADC_RES8 |
ADC_RES | BDh | A/D转换结果寄存器低8位 | ADC_RES7 | ADC_RES6 | ADC_RES5 | ADC_RES4 | ADC_RES3 | ADC_RES2 | ADC_RES1 | ADC_RES0 |
CLK_DIV | 97H | 时钟分频寄存器 | ADRJ = 1 |
此时,如果用户需取完整10位结果,按下面公式计算:
10-bit A/D ConversionResult:(ADC_RES[1:0],ADC_RESL[7:0]) = 1024*Vin/Vcc
式中,Vin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作电压作为模拟参考电压。
2.5.中断允许寄存器IE
IE:中断允许寄存器(可位寻址)
SFR name | Adess | Bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
IE | A8H | Name | EA | ELVD | EADC | ES | ET1 | EX1 | ET0 | EX0 |
EA:CPU的中断开放标志
EA = 1,CPU开放中断,
EA = 0,CPU屏蔽所有的中断申请。
EA的作用是使中断允许形成多级控制。即各中断源首先受EA控制;其次还受各中断源自己的中断允许控制位控制。
EADC:A/D转换中断允许位
EADC = 1,允许A/D转换中断,
EADC = 0,禁止A/D转换中断。
2.6.中断优先级控制寄存器IP
IP:中断优先级控制寄存器(可位寻址)
SFR name | Adess | Bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
IP | B8H | Name | PPCA | PLVD | PADC | PS | PT1 | PX1 | PT0 | PX0 |
PADC:A/D转换中断优先级控制位。
当PADC = 0时,A/D转换中断为最低优先级中断(优先级0)
当PADC = 1时,A/D转换中断为最高优先级中断(优先级1)
3.A/D转换器的结构
4.程序
/****************************************************/
//利用STC12C5A60S2AD转换,实现温度计
//函数名:main.c
/****************************************************/
#include
#include"10bit_adc.c"
#define uchar unsigned char /*宏定义用uchar 代替unsignedchar*/
#define uint unsigned int /*宏定义用uint 代替 unsignedint*/
code uchar seven_seg[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar cp0;
uint cp1,AD_DAT;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
sbit P3_6 = P3^6;
/************Timer0中断服务函数***************/
void timer0_isr(void) interrupt 1
{
TH0= (65536 - 1000) / 256; //重装初值
TL0= (65536 - 1000) % 256; //重装初值
cp1++; //中断1次,变量加1
if(cp1>= 1000) //1秒到了
{
cp1= 0;
AD_DAT= get_adc();
AD_DAT= (790 - AD_DAT) * 0.095;
}
P2= 0xff;
P3= 0xff;
switch(cp0)
{
case0: P2 = seven_seg[AD_DAT % 100 % 10]; P3_6 = 0;break;
case1: P2 = seven_seg[AD_DAT % 100 / 10]; P3_5 = 0;;break;
case2: P2 = seven_seg[AD_DAT / 100]; P3_4 = 0;break;
}
cp0++;
if(cp0>=3)cp0 = 0;
}
/*********************Timer0初始化函数***********************/
void timer0_init(void)
{
TMOD= 0x01; //T0工作方式1
TH0= (65536 - 1000) / 256; //对机器脉冲计数1000个计满溢出引发中断
TL0= (65536 - 1000) % 256;
EA= 1; //开总中断
ET0= 1; //开T0中断
TR0= 1; //启动定时器T0
}
/**************************主函数****************************/
void main(void)
{
timer0_init();
adc_init();
while(1); //等待中断
}
/****************************************************/
//利用STC12C5A60S2AD转换,实现温度计
//函数名:10bit_adc.c
/****************************************************/
#include
#include
#define nop _nop_()
#define ADC_POWER 0x80
#define ADC_START 0x08
#define ADC_FLAG 0x10
#define ADC_SPEEDH 0x40 //转换速度为180个时钟周期
#define ADRJ 0x20 //ADRJ = 1;
#define AD_P1_0 0x00 //P1.0为AD输入;
sfr ADC_CONTR = 0xbc;
sfr ADC_RES = 0xbd;
sfr ADC_RESL = 0xbE;
sfr P1ASF = 0x9D;
sfr PCON2 = 0x97;
void adc_init(void)
{
P1ASF= 0x01; //设置P1为模拟输入端口
PCON2= PCON2 | ADRJ; //ADRJ = 1;
ADC_CONTR= ADC_POWER | ADC_SPEEDH | AD_P1_0;
//设置A/D电源开启、转换速度设置、A/D输入端口;
nop;nop;nop;nop;//等待电源稳定;
}
unsigned int get_adc(void)
{
unsignedint i,j;
ADC_CONTR= ADC_CONTR | ADC_START; //开始转换
while((ADC_CONTR& ADC_FLAG) != ADC_FLAG); //等待转换标志置位
i= ADC_RES;
j= ADC_RESL;
i= i << 8;
i= i | j;
ADC_CONTR= ADC_CONTR & ~ADC_FLAG ; //清零转换标志位
ADC_RES= 0;
ADC_RESL= 0;
return(i);
}
上一篇:STC 12C5A60S2串口2通信主要代码示例
下一篇:STC15F2K60S2芯片PWM的应用
推荐阅读最新更新时间:2024-03-16 16:06
设计资源 培训 开发板 精华推荐
- 有奖评测:50套来自恩智浦全新快速物联网原型设计套件(价值350元)
- 答题赢奖:日图科技低功耗测试系统介绍
- 【世健的ADI之路主题游】 第三站:了解物联网前沿器件与方案,打卡赢Kindle、《新概念模拟电路》
- 一天一个Webench设计,看谁能撑30天?
- 【世健的ADI之路主题游】 第三站:了解物联网前沿器件与方案,打卡赢Kindle、《新概念模拟电路》
- 如何加快你的FPGA设计步伐
- TI“无线”风光可穿戴现场培训直播,诚邀参与,预注册赢好礼
- 直播已结束|浅谈Microchip的FPGA产品与智能嵌入式视觉解决方案
- 雷柏、京造的无线充电鼠标垫,等你拆开看——EEWorld邀你来玩拆解(第三期)
- EEWORLD社区版主公开招募ing