这个程序是单片机将ad0809结果显示在数码管上!ad0809采用查询方式,单片机定时刷新数码管
#include
unsigned char code dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};//没看过硬件,应该是控制数码管的
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x00};//数码管显示1-16
unsigned char dispbuf[8]={10,10,10,10,10,0,0,0};
unsigned char dispcount;
sbit ST="P3"^0;
sbit OE="P3"^1;
sbit EOC="P3"^2;
unsigned char channel="0xbc";//IN3 ad转换通道
unsigned char getdata;
void main(void)
{
TMOD=0x01;//定时模式1
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;
TR0=1;
ET0=1;
EA=1;
P3=channel;
while(1)
{
ST=0;
ST=1;//启动转换
ST=0;
while(EOC==0);//查询eoc,是否转换完成
OE=1;//输出使能
getdata=P0;//读取P0口 ad转换数据
OE=0;
dispbuf[2]=getdata/100;//取数据百位
getdata=getdata%10;//取数据十位
dispbuf[1]=getdata/10;
dispbuf[0]=getdata%10;//取数据个位
}
}
void t0(void) interrupt 1 using 0//定时中断服务子程序
{
TH0=(65536-4000)/256;
TL0=(65536-4000)%256;//装在定时数据
P1=dispcode[dispbuf[dispcount]];//这个应该是数码管的控制口
P2=dispbitcode[dispcount];//这个应该是数码管的数据口
dispcount++;
if(dispcount==8)
{
dispcount=0;
}
}
AD_CLK
EQU
P1.0
AD_DAT
EQU
P1.1
AD_CS
EQU
P3.4
DISSTART
EQU
30H
;显示单元首地址
LED_DATA
EQU
P0
;数码管数据定义
ORG
0000H
JMP
START
;--------------------------------------------------------
START:
MOV
SP,#60H
MOV
A,#00H
MOV
20H,A
MOV
P0,#0FFH
MOV
P2,#0FFH
START1:
CALL
AD_CONV
CALL
AD_CHULI
CALL
QUSHU
CALL
ADPLAY
JMP
START1
;---------------------------------------------------------
AD_CONV:
;ADC0832初始化
SETB
AD_CS
;一个转换周期开始
CLR
AD_CLK
CLR
AD_CS
;CS置0,片选有效
SETB
AD_DAT
;DI置1,起始位
SETB
AD_CLK
;第一个脉冲
CLR
AD_DAT
;在负跳变之前加一个DI反转操作
CLR
AD_CLK
SETB
AD_DAT
;DI置1,设为单通道
SETB
AD_CLK
;第二个脉冲
CLR
AD_DAT
;***
CLR
AD_CLK
;
CLR
AD_DAT
;DI置0,选择通道0
SETB
AD_CLK
;第三个脉冲
SETB
AD_DAT
;***
CLR
AD_CLK
NOP
SETB
AD_CLK
;
第四个脉冲
MOV
R1,#08H
;计数器初值,读取8位数据,
AD_READ:
CLR
AD_CLK
;下降沿
MOV
C,AD_DAT
;读取DO端数据
RLC
A
;C移入A,高位在前
SETB
AD_CLK
;下一个脉冲
DJNZ
R1,AD_READ
;没读完继续
SETB
AD_CS
MOV
20H,A
;转换结果发给20H
RET
;------------------------------------------------------
AD_CHULI:
CLR
C
MOV
R5,#00H
;十进制转换的低位寄存器
MOV
R4,#00H
;十进制转换的高位寄存器
MOV
R3,#08H
;十进制调整的次数
MOV
A,20H
AD_CHULI1:
RLC
A
MOV
R2,A
MOV
A,R5
ADDC
A,R5
DA
A
MOV
R5,A
MOV
A,R4
ADDC
A,R4
MOV
R4,A
MOV
A,R2
DJNZ
R3,AD_CHULI1
MOV
A,R5
ADD
A,R5
DA
A
MOV
R5,A
MOV
A,R4
ADDC
A,R4
DA
A
MOV
R4,A
RET
;-------------------------------------------------
QUSHU:
MOV
A,R5
ANL
A,#0FH
MOV
DISSTART,A
MOV
A,R5
ANL
A,#0F0H
SWAP
A
MOV
DISSTART+1,A
MOV
A,R4
ANL
A,#0FH
MOV
DISSTART+2,A
MOV
A,R4
ANL
A,#0F0H
MOV
DISSTART+3,A
RET
;---------------------------------------------------
ADPLAY:
PUSH
PSW
CLR
PSW.3
SETB
PSW.4
MOV
R0,#DISSTART
;开始填充显示单元
MOV
R2,#03H
;共计填充
3
位
DISP1:
MOV
A,@R0
;获得当前位地址
MOV
DPTR,#TAB_NU
;获得表头
MOVC
A,@A+DPTR
;获得编码数据
MOV
@R0,A
;保存编码数据
INC
R0
;指向下一个带转换数据
DJNZ
R2,DISP1
;继续转换,直到完成
MOV
R0,#DISSTART
;获得显示单元首地址
MOV
R1,#07FH
;从第一个数码管开始
MOV
R2,#03H
;共显示3位数码管
DISP2:
MOV
LED_DATA,@R0
;读取显示单元数据
MOV
P2,R1
;开始显示当前位
MOV
A,R1
;准备显示下一位
RR
A
;
MOV
R1,A
;下一位
INC
R0
;取下一个单元地址
JNB
ACC.5,DISP3
;第三位数码管加小数点
JMP
DISP4
DISP3:
MOV
A,@R0
ANL
A,#7FH
MOV
@R0,A
DISP4:
LCALL
DELAY5MS
;延时
2
MS
DJNZ
R2,DISP2
;重复显示下一个
POP
PSW
RET
;显示完成,返回
;---------------------------------------------------
DELAY5MS:
MOV
R6,#10
DEL1:
MOV
R7,#100
DJNZ
R7,$
DJNZ
R6,DEL1
RET
;-------------------------------------------------
TAB_NU:
DB
0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
DB
80H,90H,88H,83H,0C6H,0A1H,86H,8EH
END
这是用ADC0832做AD转换的数字电压表程序,供参考