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转换,自己试试吧
单片机原理一个简易数字电压表
我这个程序是用1602显示的,ADC0832做的AD,给你看一下。
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define channel_0 0x02 //单通道0输入选择
#define channel_1 0x03 //单通道1输入选择
//sfr AUXR=0x8E;
//sfr WDT_ConTR=0xe1;
sbit csad=P1^1;
sbit adclk=P1^2;
sbit scl=P1^3;
sbit sda=P1^4;
sbit dawr=P3^6;
sbit csda=P1^0;
sbit cs485=P1^5;
sbit key1=P1^6;
sbit key2=P1^7;
sbit key3=P2^0;
sbit key4=P2^1;
sbit DS=P2^2;
sbit lcrs=P3^7;//数据/命令
sbit lcwr=P3^5;//读/写
sbit lcden=P3^4;//使能
//sbit lcrs=P3^4;
//sbit lcden=P3^5;
//sbit lcwr=P3^7;
sbit ACC0=ACC^0; //通道与输入方式控制字
sbit ACC1=ACC^1; //通道与输入方式控制字
uchar code table[]={48,49,50,51,52,53,54,55,56,57};
uchar data dis[]=

{'A','D','-','d','a','t','e',' ',0x00,'.',0x00,0x00,'V'}; //定义3个显示数据单元
uchar table3[]={"CHANG DA CE KONG"};
ADC_start()
{
csad=1; //一个转换周期开始
sda=0;
_nop_();
adclk=0;
_nop_();
csad=0; //CS置0,片选有效
_nop_();
sda=1; //DI置1,起始位
_nop_();
adclk=1; //第一个脉冲
_nop_();
sda=0; //在负跳变之前加一个DI反转操作
_nop_();
adclk=0;
_nop_();
}
ADC_read(uchar mode)
{
uchar i;
ADC_start(); //启动转换开始
ACC=mode;
sda=ACC1; //输出控制位1,DI=1,单通道输入,DI=0,差分输入。
adclk=1; //第二个脉冲
_nop_();
sda=0;
adclk=0;
_nop_();
sda=ACC0; //输出控制位0,DI=0,通道0输入,DI=1,通道1输入。
adclk=1; //第三个脉冲
_nop_();
sda=1;
adclk=0; //输入模式和通道号已经选择完。
adclk=1; //第四个脉冲
ACC=0;
for(i=8;i>0;i--) //读取8位数据
{
adclk=0; //脉冲下降沿
ACC=ACC<<1;
ACC0=sda; //读取DO端数据
_nop_();
_nop_();
adclk=1;
}
csad=1; //CS=1,片选无效
sda=0;
adclk=0;
return(ACC);
}
//////1062/////////
void ydelay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
void write_com(uchar com)
{
P0=com;
lcwr=0;
lcrs=0;
lcden=0;
ydelay(10);
lcden=1;
ydelay(10);
lcden=0;
lcwr=1;
}
void write_date(uchar date)//写数据
{
P0=date;
lcwr=0;
lcrs=1;
lcden=0;
ydelay(10);
lcden=1;
ydelay(10);
lcden=0;
lcwr=1;
}
void init1602()//初始化
{
write_com(0x38);//设置显示模式
ydelay(20);
write_com(0x0c);//开显示
ydelay(20);
write_com(0x06);//指针和光标自动加一
ydelay(20);
write_com(0x01);//清屏指令
ydelay(20);
}
void delay(uchar count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
//////////////显示函数/////////////////
void display(uchar date)
{
uchar a=0,b=0,c=0,k;
uint d;
a=date/51;
d=date%51;
d=d*10;
b=d/51;
d=d%51;
d=d*10;
c=d/51;
dis[8]=table[a];
dis[10]=table[b];
dis[11]=table[c];
write_com(0x82);
delay(2);
for(k=0;k<13;k++)
{
write_date(dis[k]);
delay(2);
}
write_com(0xc0);
for(a=0;a<16;a++)
{
write_date(table3[a]);
delay(2);
}
}
///////主函数/////////////////
void main()
{
uchar i;
init1602();
while(1)
{
i=ADC_read(channel_0);
display(i);
csda=0;
dawr=0;
P0=i;

csda=1;
dawr=1;
}
}
这个电路的时钟信号是由晶振CRYSTAL通过XTAL1端和XTAL2端产生的,这两个端口内部有门电路,与晶振形成时钟振荡,内部就有了时钟信号。时钟频率由晶振决定,图中没标晶振频率,看不出来。


