您的当前位置:首页正文

关于STC15F2K60S2的AD应用

2020-10-28 来源:客趣旅游网
STC15F2K60S2芯片A/D转换器的应用

1.目的

在工业控制过程中,它是控制系统与微机之间不可缺少的接口方式。要实现自动控制,就要检测有关参数,A/D转换器,把检测到的电压或电流信号(模拟量)转换成计算机能够识别的等效数字量,这些数字量经过计算机处理后输出结果,通过D/A转换器变为电压或电流信号,送到执行机构,达到控制某种过程的目的。 2.与A/D转换相关的寄存器

与STC15系列单片机A/D转换相关的寄存器列于下表所示。 符号 P1ASF ADC_CONTR 描述 P1 Analog Function Configure register ADC Control Register 地址 位地址及其符号 MSB LSB P16ASP17ASF F P15ASF P14P13P12P11P10ASASASASASF F F F F ADC_SCHCHCHTAS2 S1 S0 RT CLKS1 CLKS0 复位值 9DH 0000 0000B ADADC_POSPEEDSPEEDC_FBCH WER 1 0 LAG BDH BEH 0000 0000B ADCADC Result _RES high ADCADC Result _RESlow L CLK_DIV 时钟分频寄存PCO器 N2 Interrupt IE Enable Interrupt IP Priority Low 0000 0000B 0000 0000B MCKO_SMCKO97H 1 _S0 A8H B8H EA PPCA Tx2CLTx_ADRJ _RxKSRx 2 2 0000 x000B ELVD EADC ES ET1 PLVD PADC EXEXET0 1 0 PXPXPS PT1 PT0 1 0 0000 0000B 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 P1ASF Adess 9DH Bit Name B7 P17ASF B6 P16ASF B5 P15ASF B4 P14ASF B3 P13ASF B2 P12ASF B1 P11ASF B0 P10ASF P1ASF[7:0] P1ASF.0 = 1 P1ASF.1 = 1 P1ASF.2 = 1 P1ASF.3 = 1 P1ASF.4 = 1 P1.x的功能 P1.0口作为模拟功能A/D使用 P1.1口作为模拟功能A/D使用 P1.2口作为模拟功能A/D使用 P1.3口作为模拟功能A/D使用 P1.4口作为模拟功能A/D使用 其中P1ASF寄存器地址为:[9DH](不能进行位寻址) P1ASF.5 = 1 P1ASF.6 = 1 P1ASF.7 = 1 P1.5口作为模拟功能A/D使用 P1.6口作为模拟功能A/D使用 P1.7口作为模拟功能A/D使用 2.2. ADC_CONTR

ADC_CONTR寄存器的格式如下: ADC_CONTR:ADC控制寄存器 SFR Adess Bit B7 B6 B5 B4 name ADC_CSPEESPEEDADC_FLABCH name ADC_POWER ONTR D1 0 G B3 B2 B1 B0 ADC_STARCHS2 CHS1 CHS0 T 对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 1 1 0 0 SPEED0 1 0 1 0 A/D转换所需时间 90个时钟周期转换一次,CPU工作频率21MHz时,A/D转换速度约300MHz 180个时钟周期转换一次 360个时钟周期转换一次 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 0 0 0 0 1 1 1 1 CHS1 0 0 1 1 0 0 1 1 CHS0 0 1 0 1 0 1 0 1 Analog Channel Select 选择P1.0作为A/D输入来用 选择P1.1作为A/D输入来用 选择P1.2作为A/D输入来用 选择P1.3作为A/D输入来用 选择P1.4作为A/D输入来用 选择P1.5作为A/D输入来用 选择P1.6作为A/D输入来用 选择P1.7作为A/D输入来用 2.3.ADC转换结果调整寄存器位—ADRJ

ADC转换结果调整控制位——ADRJ位于寄存器CLK_DIV/PCON中,用于控制ADC转换结果存放的位置。 Mnemonic Add Name B7 B6 B5 B4 B3 B2 时钟MCKOMCKOTx2_RxCLKCLK_DIV 98H 寄存ADRJ Tx_Rx _S1 _S0 2 S2 器 B1 CLKS1 B0 CLKS0 Reset Value 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 ADC_RES ADC_RES CLK_DIV Name B7 B6 B5 B4 B3 B2 B1 B0 A/D转换结BDh 果寄存器 高 A/D转换结BDh 果寄存器 低 时钟分频MCKO_MCKTx_RTX2_97H ADRJ CLKS2 CLKS1 CLKS0 寄存器 S1 O_S0 x Rx2 Add 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_REA/D转换结果ADC_ADC_RADC_ADC_ADC_RADC_RADC_RADC_REBDh S 寄存器高8位 RES7 ES6 RES5 RES4 ES3 ES2 ES3 S2 ADC_REA/D转换结果ADC_RADC_REBDh - - - - - - S 寄存器低2位 ES1 S0 时钟分频寄存ADRJ CLK_DIV 97H 器 = 0 此时,如果用户需取完整10位结果,按下面公式计算: Vin

10-bit A/D Conversion Result:(ADC_RES[7:0],ADC_RESL1:0]) = 1024*

Vcc

如果用户只需取8位结果,按下面公式计算:

Vin

8-bit A/D Conversion Result:(ADC_RES[7:0]) = 256*

Vcc

式中,Vin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作 电压作为模拟参考电压。 当ADRJ = 1时,10位A/D转换结果的高2位存放在ADC_RES的低2位中,低8位存放在ADC_RESL中。

Mnemonic Add Name B7 B6 B5 B4 B3 B2 BDA/D转换结果寄ADC_RES - - - - - - h 存器高2位 BDA/D转换结果寄ADC_RADC_READC_RADC_RADC_RADC_ADC_RES h 存器低8位 ES7 S6 ES5 ES4 ES3 RES2 ADRJ = CLK_DIV 97H 时钟分频寄存器 1 B1 B0 ADC_ADC_RRES9 ES8 ADC_ADC_RRES1 ES0 此时,如果用户需取完整10位结果,按下面公式计算:

Vin

10-bit A/D Conversion Result:(ADC_RES[1:0],ADC_RESL[7:0]) = 1024*

Vcc

式中,Vin为模拟输入通道输入电压,Vcc为单片机实际工作电压,用单片机工作电压作为模拟参考电压。 2.5.中断允许寄存器IE

IE:中断允许寄存器(可位寻址) SFR name IE Adess A8H Bit Name B7 EA B6 ELVD B5 EADC B4 ES B3 ET1 B2 EX1 B1 ET0 B0 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 IP Adess B8H Bit Name B7 PPCA B6 PLVD B5 PADC B4 PS B3 PT1 B2 PX1 B1 PT0 B0 PX0 PADC:A/D转换中断优先级控制位。 当PADC = 0时,A/D转换中断为最低优先级中断(优先级0) 当PADC = 1时,A/D转换中断为最高优先级中断(优先级1) 3.A/D转换器的结构

ADC_POWERSPEED1SPEED0ADC_FLAG ADC_STARTCHS2CHS1CHS0模拟输入信号通道选择开关CHS2/CHS1/CHS0 ADC7/P1.7ADC6/P1.6ADC5/P1.5ADC4/P1.4ADC3/P1.3ADC2/P1.2ADC1/P1.1ADC0/P1.0A/D转换结果寄存器: ADC_RESandADC_RESL 逐次比较寄存器比较器10-Bit DAC

4.程序

/****************************************************/ //利用STC12C5A60S2AD转换,实现温度计 //函数名:main.c

/****************************************************/ #include #include\"10bit_adc.c\"

#define uchar unsigned char /*宏定义用uchar 代替unsigned char*/ #define uint unsigned int /*宏定义用uint 代替 unsigned int*/

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) { case 0: P2 = seven_seg[AD_DAT % 100 % 10]; P3_6 = 0;break; case 1: P2 = seven_seg[AD_DAT % 100 / 10]; P3_5 = 0;;break; case 2: 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) { unsigned int 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); }

因篇幅问题不能全部显示,请点此查看更多更全内容