请问简易电压表的汇编语言源程序

核心提示AD_CLK EQU P1.0 AD_DAT EQU P1.1 AD_CS EQU P3.4DISSTART EQU 30H;显示单元首地址LED_DATA EQU P0 ;数码管数据定义ORG 0000HJMP

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端产生的,这两个端口内部有门电路,与晶振形成时钟振荡,内部就有了时钟信号。时钟频率由晶振决定,图中没标晶振频率,看不出来。

 
友情链接
鄂ICP备19019357号-22