STC15单片机的A/D转换口在P1.0~P1.7,有8路10位A/D转换器。

一.所用寄存器

1.P1ASF P1口模拟功能控制寄存器(不可位寻址)

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
P1ASF 9DH name P17ASF P16ASF P15ASF P14ASF P13ASF P12ASF P11ASF P10ASF

位号 P1.x功能
P17ASF=1 P1.7口作为模拟A/D使用
P16ASF=1 P1.6口作为模拟A/D使用
P15ASF=1 P1.5口作为模拟A/D使用
P14ASF=1 P1.4口作为模拟A/D使用
P13ASF=1 P1.3口作为模拟A/D使用
P12ASF=1 P1.2口作为模拟A/D使用
P11ASF=1 P1.1口作为模拟A/D使用
P10ASF=1 P1.0口作为模拟A/D使用

2.ADC_CONTR ADC控制寄存器

SFR name Address 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_POWER: ADC电源控制位。0—关闭,1—打开;

SPEED1、SPEED0:

SPEED1 SPEED0 A/D转换所需时间
0 0 90个时钟周期转换一次
0 1 180个时钟周期转换一次
1 0 360个时钟周期转换一次
1 1 540个时钟周期转换一次

ADC_FLAG: 数模转换器转换结束标记位。A/D转换完成后,硬件自动置1,需要软件清0;

ADC_START: 数模转换器转换启动控制位。置1后开始转换,转换结束后自动清0;

CHS2、CHS1、CHS0:

CHS2 CHS1 CHS0 模拟输入通道选择
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输入

3.ADRJ ADC转换结果调整寄存器位

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
CLK_DIV 97H name ADRJ

ADRJ: 0—ADC_RES[7:0]存放高8位,ADC_RESL[1:0]存放低2位;1—ADC_RES[1:0]存放高2位,ADC_RESL[7:0]存放低8位;

4.ADC_RES、ADC_RESL A/D转换结果寄存器

5.IE中断允许寄存器

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
IE A8H name EA EADC

EA: 总中断;

EADC: A/D中断允许位。0—不允许,1—允许;

6.IP中断优先级控制寄存器

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
IP B8H name PADC

PADC: A/D转换中断优先级控制位。

二.代码

/***********************************************
stc15单片机内部adc转换,P1.0口用于采样
***********************************************/

#include "stc15.h"
#include "intrins.h"

#define ADC_POWER 0x80		//ADC电源控制位
#define ADC_FLAG  0x10		//ADC完成标志
#define ADC_START 0x08		//ADC起始控制位

#define ADC_SPEEDLL  0x00	//540个时钟
#define ADC_SPEEDL	 0x20	//360个时钟
#define ADC_SPEEDH   0x40	//180个时钟
#define ADC_SPEEDHH  0x60	//90个时钟

unsigned char code smg_duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

unsigned char display[5];
unsigned int res; //adc读取值

void ADC_Init()
{
	CLK_DIV=0x20;	//设置RES的低二位为数据高二位,RESL为数据低八位
	P1ASF=0x01;	//P1.0为A/D模式
	ADC_RES=0;	//A/D转换结果存储寄存器初始化
	ADC_RESL=0;	
}

//定时器0初始化1ms
void Timer0Init(void)		//1ms@11.0592MHz
{
	AUXR |= 0x80;		
	TMOD &= 0xF0;		
	TL0 = 0xCD;		
	TH0 = 0xD4;		
	TF0 = 0;		
	TR0 = 1;		
}

//数码管显示函数
void smg_display()
{
	static unsigned char i=0;
	
	P2=(P2&0x1f)|0xe0;
	P0=0xff;
	P2&=0x1f;
	
	P2=(P2&0x1f)|0xe0;
	P0=display[i];
	P2&=0x1f;
	
	P2=(P2&0x1f)|0xc0;
	P0=smg_wei[i];
	P2&=0x1f;
	
	i++;
	if(i==5)
		i=0;
}

void main(void)
{
	ADC_Init();
	Timer0Init();
	
	EA=1;
	ET0=1;
	EADC=1;	//使能ADC中断
	
	PT0=0;	//定时器0优先级为1
	PADC=1;	//ADC中断优先级为0
	
	P1M1=0x01;	//共同配置P1.0口为开漏模式
	P1M0=0x01;	
	
	
	while(1)
	{
		display[0]=~smg_duan[light/10000];		
		display[1]=~smg_duan[light/1000%10];
		display[2]=~smg_duan[light/100%10];
		display[3]=~smg_duan[light/10%10];
		display[4]=~smg_duan[light%10];
	}
}

//ADC中断,获取A/D转换结果
void Adc_Int() interrupt 5 using 1
{
	ADC_CONTR&=!ADC_FLAG;	//清楚A/D中断标志位
	res=ADC_RES<<8;
	res|=ADC_RESL;
}

//定时器0中断
void Time0_Int() interrupt 1 using 1
{
	static unsigned char count=0;
	count++;
	smg_display();
	if(count==200)
	{
		count=0;
		ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START;	//ADC电源打开,设置速度,打开ADC,通道默认为0
		_nop_();_nop_();_nop_();_nop_();		
	}
}