STC15F2K60S2芯片A/D转换器的应用

STC15F2K60S2芯片A/D转换器的应用

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<reg51.h>

#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<reg51.h>

#include<intrins.h>

#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);

}

 

 

  • 11
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值