MCS-51单片机查表程序

MCS-51单片机查表程序,第1张

16和7是查表指令时的PC与数据表格之间的字节数

MOV A ,@R0 ;取R0指向的地址中的数据到A

ANL A,#0FH ;高四位清零

ADD A,#16 ;加16

MOVC A, @A+PC ;查表,表的首地址为绝对地址PC+A

MOVC A,@A+PC就需要1个字节啊

查表指令距离表首地址的长度是字节数

用DPTR的汇编程序:

ORG 0100H

MOV 30H,#12H

MOV 31H,#34H

MOV 32H,#56H

MOV 33H,#78H

LCALL SUBRTE

ORG 1000H

SUBRTE: MOV R0,#30H ; ;置地址指针R0初值

MOV R1,#40H ; ;置地址指针R1初值

MOV R2,#4 ; ;置字节数

LOOP: MOV A,@R0 ; ;取16进制数

ANL A,#0FH ; ;屏蔽高4位

MOV DPTR,#TABLE ; ;

MOVC A,@A+DPTR ; ;查表低4位转换为ASCⅡ码

MOV @R1,A ; ;送结果

INC R1 ; ;修改指针

MOV A,@R0 ; ;从新取16进制数

SWAP A ; ;高4位与低4位互换

ANL A,#0FH ; ;取高4位

ADD A,#7

MOVC A,@A+PC ; ;查表高4位转换为ASCⅡ码

MOV @R1,A

INC R0

INC R1

DJNZ R2,LOOP

DEC R1

RET

TABLE: DB '012345678'

DB '9ABCDEF'

END

#include "reg51h"

#define data_point P0

sbit EOC=P2^0;

sbit ADDA=P2^1;

sbit ADDB=P2^2;

sbit ADDC=P2^3;

sbit OE=P2^5;

sbit START=P2^6;

sbit CLK=P2^7;

sbit ALE=P2^6;

unsigned char disp[3]={0,0,0};

char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned char t0count=0;

unsigned int temp;

double sum;

unsigned char val_Integer; //整数

unsigned int val_Decimal; //小数

sbit k1 = P1^0;

sbit k2 = P1^1;

sbit k3 = P1^2;

sbit k4 = P1^3;

void delay(unsigned char ms)

{

unsigned char i;

while(ms--)

for(i=0;i<125;i++);

}

void display()

{

disp[0]=disp[0]&0x7f;

P3= disp[0];

k1 = 1;

delay(2);

k1 = 0;

P3= disp[1];

k2 = 1;

delay(2);

k2 = 0;

P3= disp[2];

k3 = 1;

delay(2);

k3 = 0;

P3= disp[3];

k4 = 1;

delay(2);

k4 = 0;

}

unsigned char ADC0808()

{

unsigned char d;

ADDC=0;

ADDB=0;

ADDA=0;

TR1=1;

ALE=1;ALE=0;

START=1;START=0;

while(EOC==0);

OE=1;

d=data_point;

OE=0;

TR1=1;

return d;

}

void covert(unsigned char x)

{

sum=x00201378;

val_Integer=(unsigned char)sum;

val_Decimal=(unsigned int)((sum-val_Integer)1000);

disp[3]=dispcode[val_Decimal%10];

disp[2]=dispcode[val_Decimal/10%10];

disp[1]=dispcode[val_Decimal/100];

disp[0]=dispcode[val_Integer];

}

void main()

{

TMOD=0x21;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

TH1=256-2;

ET0=1;

ET1=1;

EA=1;

TR0=1;

OE=0;

START=0;

EOC=1;

while(1)

{

display();

}

}

void time0() interrupt 1

{

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

t0count++;

if(t0count==100)

{

t0count=0;

covert(ADC0808());

}

}

void time1() interrupt 3

{

CLK=~CLK;

}

KEYVAL EQU 30H

KEYTM EQU 31H

KEYSCAN EQU 32H

DAT EQU 33H

SCANLED EQU 39H

CLK EQU 77H

SEC EQU 78H

MIN EQU 79H

HOUR EQU 7AH

PAUSE BIT 00H

DOT BIT 01H

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP T0ISR ;50ms定时

ORG 001BH

LJMP T1ISR ;扫描显示

ORG 0030H

MAIN:

MOV SP,#5FH

MOV TMOD,#11H

MOV TH0,#03CH

MOV TL0,#0B0H

MOV TH1,#0ECH

MOV TL1,#078H

MOV KEYVAL,#0

MOV SCANLED,#0

MOV 33H,#10H

MOV 34H,#10H

MOV 35H,#10H

MOV 36H,#10H

MOV 37H,#10H

MOV 38H,#10H

MOV SEC,#0

MOV MIN,#0

MOV HOUR,#0

MOV CLK,#0

CLR PAUSE

SETB EA

SETB ET1

SETB TR1

LOOP:

LCALL KEYSEL

MOV A,KEYVAL

CJNE A,#0FFH,LOOP1

SJMP LOOP

LOOP1:

CJNE A,#10,LOOP2 ;“ON”启动

SETB TR0

SETB ET0

SETB PAUSE

SJMP LOOP

LOOP2:

CJNE A,#11,LOOP3 ;“=”清零

MOV SEC,#0

MOV MIN,#0

MOV HOUR,#0

LCALL DISCHG

SJMP LOOP

LOOP3:

CJNE A,#15,LOOP4 ;“+”暂停

CLR TR0

CLR ET0

CLR PAUSE

SJMP LOOP

LOOP4:

CJNE A,#14,LOOP5 ;“-”清显示暂停

MOV 33H,#10H

MOV 34H,#10H

MOV 35H,#10H

MOV 36H,#10H

MOV 37H,#10H

MOV 38H,#10H

CLR TR0

CLR ET0

CLR PAUSE

SJMP LOOP

LOOP5:

CJNE A,#10,LOOP6 ;数字键

LOOP6:

JC LOOP7

LJMP LOOP

LOOP7:

JNB PAUSE,LOOP8 ;暂停状态可以输入数字键

LJMP LOOP

LOOP8:

MOV 33H,34H

MOV 34H,35H

MOV 35H,36H

MOV 36H,37H

MOV 37H,38H

MOV 38H,KEYVAL

MOV A,33H

SWAP A

ORL A,34H

LCALL BCDH

MOV HOUR,A

MOV A,35H

SWAP A

ORL A,36H

LCALL BCDH

MOV MIN,A

MOV A,37H

SWAP A

ORL A,38H

LCALL BCDH

MOV SEC,A

LJMP LOOP

;------------------

;BCD转换为十六进制

BCDH:

MOV B,#10H

DIV AB 

MOV R7,B

MOV B,#10

MUL AB 

ADD A,R7

RET 

;------------------

;十六进制转换为BCD

HBCD:

MOV B,#10

DIV AB 

SWAP A 

ORL A,B

RET 

;------------------

KEYSEL:

MOV KEYVAL,#0

MOV KEYSCAN,#0EFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS1

MOV KEYVAL,A

SJMP KEYRTN

KEYS1:

MOV KEYSCAN,#0DFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS2

CLR C

ADD A,#4

MOV KEYVAL,A

SJMP KEYRTN

KEYS2:

MOV KEYSCAN,#0BFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS3

CLR C

ADD A,#8

MOV KEYVAL,A

SJMP KEYRTN

KEYS3:

MOV KEYSCAN,#7FH

LCALL GETKEY

MOV A,KEYTM

JZ KEYRTN

CLR C

ADD A,#12

MOV KEYVAL,A

KEYRTN:

LCALL CHGKEY

RET

;--------------------

GETKEY:

MOV KEYTM,#0

MOV A,KEYSCAN

MOV P3,A

NOP

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY

MOV R2,#10

LCALL DELAY

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY

MOV A,P3

ANL A,#0FH

MOV R7,A

SF:

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JNZ SF

MOV A,R7

CJNE A,#0EH,NK1

MOV KEYTM,#1

SJMP NOKEY

NK1:

CJNE A,#0DH,NK2

MOV KEYTM,#2

SJMP NOKEY

NK2:

CJNE A,#0BH,NK3

MOV KEYTM,#3

SJMP NOKEY

NK3:

CJNE A,#07H,NOKEY

MOV KEYTM,#4

NOKEY: RET

;--------------------

DELAY:

MOV R3,#50

DELAY1:

MOV R4,#100

DJNZ R4,$

DJNZ R3,DELAY1

DJNZ R2,DELAY

RET

;--------------------

T0ISR:

PUSH ACC

CLR TR0

MOV TH0,#3CH

MOV TL0,#0B0H

SETB TR0

INC CLK

MOV A,CLK

CJNE A,#20,T0ISRE

MOV CLK,#0

INC SEC

MOV A,SEC

CJNE A,#60,T0ISRE

MOV SEC,#0

INC MIN

MOV A,MIN

CJNE A,#60,T0ISRE

MOV MIN,#0

INC HOUR

MOV A,HOUR

CJNE A,#24,T0ISRE

MOV SEC,#0

MOV MIN,#0

MOV HOUR,#0

T0ISRE:

LCALL DISCHG

POP ACC

RETI

;--------------------

DISCHG:

MOV A,HOUR

LCALL HBCD

PUSH ACC

ANL A,#0FH

MOV 34H,A

POP ACC

ANL A,#0F0H

SWAP A

MOV 33H,A

MOV A,MIN

LCALL HBCD

PUSH ACC

ANL A,#0FH

MOV 36H,A

POP ACC

ANL A,#0F0H

SWAP A

MOV 35H,A

MOV A,SEC

LCALL HBCD

PUSH ACC

ANL A,#0FH

MOV 38H,A

POP ACC

ANL A,#0F0H

SWAP A

MOV 37H,A

RET

;--------------------

T1ISR:

PUSH ACC

CLR TR1

MOV TH1,#0ECH

MOV TL1,#78H

SETB TR1

MOV DPTR,#LEDTAB

T100:

MOV R0,#DAT

MOV A,SCANLED

ADD A,R0

MOV R0,A

MOV A,SCANLED

JNZ T101

MOV P2,#01H

CLR DOT

SJMP T1DIS

T101:

DEC A

JNZ T102

MOV P2,#02H

SETB DOT

SJMP T1DIS

T102:

DEC A

JNZ T103

MOV P2,#04H

CLR DOT

SJMP T1DIS

T103:

DEC A

JNZ T104

MOV P2,#08H

SETB DOT

SJMP T1DIS

T104:

DEC A

JNZ T105

MOV P2,#10H

CLR DOT

SJMP T1DIS

T105:

MOV P2,#20H

CLR DOT

T1DIS:

MOV A,@R0

MOVC A,@A+DPTR

JNB DOT,T1DIS1

ORL A,#01H

T1DIS1:

CPL A

MOV P0,A

INC SCANLED

MOV A,SCANLED

CJNE A,#6,T1END

MOV SCANLED,#0

T1END:

POP ACC

RETI

;--------------------

CHGKEY:

MOV A,KEYVAL

JZ KV16

DEC A

JNZ KV01

MOV KEYVAL,#7

RET

KV01:

DEC A

JNZ KV02

MOV KEYVAL,#4

RET

KV02:

DEC A

JNZ KV03

MOV KEYVAL,#1

RET

KV03:

DEC A

JNZ KV04

MOV KEYVAL,#10

RET

KV04:

DEC A

JNZ KV05

MOV KEYVAL,#8

RET

KV05:

DEC A

JNZ KV06

MOV KEYVAL,#5

RET

KV06:

DEC A

JNZ KV07

MOV KEYVAL,#2

RET

KV07:

DEC A

JNZ KV08

MOV KEYVAL,#0

RET

KV08:

DEC A

JNZ KV09

MOV KEYVAL,#9

RET

KV09:

DEC A

JNZ KV10

MOV KEYVAL,#6

RET

KV10:

DEC A

JNZ KV11

MOV KEYVAL,#3

RET

KV11:

DEC A

JNZ KV12

MOV KEYVAL,#11

RET

KV12:

DEC A

JNZ KV13

MOV KEYVAL,#12

RET

KV13:

DEC A

JNZ KV14

MOV KEYVAL,#13

RET

KV14:

DEC A

JNZ KV15

MOV KEYVAL,#14

RET

KV15:

DEC A

JNZ KV16

MOV KEYVAL,#15

RET

KV16:

MOV KEYVAL,#0FFH

RET

;--------------------

LEDTAB: DB 0FCH ;"0" 00H

DB 60H ;"1" 01H

DB 0DAH ;"2" 02H

DB 0F2H ;"3" 03H

DB 66H ;"4" 04H

DB 0B6H ;"5" 05H

DB 0BEH ;"6" 06H

DB 0E0H ;"7" 07H

DB 0FEH ;"8" 08H

DB 0F6H ;"9" 09H

DB 0EEH ;"A" 0AH

DB 3EH ;"B" 0BH

DB 9CH ;"C" 0CH

DB 7AH ;"D" 0DH

DB 9EH ;"E" 0EH

DB 8EH ;"F" 0FH

DB 00H ;" " 10H

;--------------------

END

#include "reg51h"

#define data_point P0

sbit EOC=P2^0;

sbit ADDA=P2^1;

sbit ADDB=P2^2;

sbit ADDC=P2^3;

sbit OE=P2^5;

sbit START=P2^6;

sbit CLK=P2^7;

sbit ALE=P2^6;

unsigned char disp[3]={0,0,0};

char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned char t0count=0;

unsigned int temp;

double sum;

unsigned char val_Integer; //整数

unsigned int val_Decimal; //小数

sbit k1 = P1^0;

sbit k2 = P1^1;

sbit k3 = P1^2;

sbit k4 = P1^3;

void delay(unsigned char ms)

{

unsigned char i;

while(ms--)

for(i=0;i<125;i++);

}

void display()

{

disp[0]=disp[0]&0x7f;

P3= disp[0];

k1 = 1;

delay(2);

k1 = 0;

P3= disp[1];

k2 = 1;

delay(2);

k2 = 0;

P3= disp[2];

k3 = 1;

delay(2);

k3 = 0;

P3= disp[3];

k4 = 1;

delay(2);

k4 = 0;

}

unsigned char ADC0808()

{

unsigned char d;

ADDC=0;

ADDB=0;

ADDA=0;

TR1=1;

ALE=1;ALE=0;

START=1;START=0;

while(EOC==0);

OE=1;

d=data_point;

OE=0;

TR1=1;

return d;

}

void covert(unsigned char x)

{

sum=x00201378;

val_Integer=(unsigned char)sum;

val_Decimal=(unsigned int)((sum-val_Integer)1000);

disp[3]=dispcode[val_Decimal%10];

disp[2]=dispcode[val_Decimal/10%10];

disp[1]=dispcode[val_Decimal/100];

disp[0]=dispcode[val_Integer];

}

void main()

{

TMOD=0x21;

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

TH1=256-2;

ET0=1;

ET1=1;

EA=1;

TR0=1;

OE=0;

START=0;

EOC=1;

while(1)

{

display();

}

}

void time0() interrupt 1

{

TH0=(65536-10000)/256;

TL0=(65536-10000)%256;

t0count++;

if(t0count==100)

{

t0count=0;

covert(ADC0808());

}

}

void time1() interrupt 3

{

CLK=~CLK;

}

从程序中可以看出,LTB2是一个子程序的地址标号。当其它程序调用这个子程序时,首先要做的第一件事,是将以TAB2为标号的常数表首地址装入DPTR,即“MOVDPTR,#TAB2”,接下来子程序运行到RET处返回。

/头文件包含/

#include<reg51h> //51单片机寄存器地址

#include<intrinsh> //程序中没有用到,一些位 *** 作函数

#include<stdioh>//基本输入输出,没用

#define uint unsigned int //宏定义

#define uchar unsigned char

//start IO definition

sbit CLK=P2^0;

sbit ST=P2^1;

sbit EOC=P2^2;

sbit OE=P2^3;

sbit ADDA=P2^5;

sbit ADDB=P2^6;

sbit ADDC=P2^7;

sbit X1=P3^4;

sbit X2=P3^5;

sbit X3=P3^6;

sbit P07=P0^7;

//end IO definition

/Global Variables/

uint temp;

uchar getdata;

uchar b;

uchar s;

uchar g;

uchar code table[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管显示数据

void delayus(uchar us){ //延时

uchar i;

while(us--)

for(i=0;i<120;i++)

;

}

/void delayms(uchar ms){

uchar i;

while(ms--){

for(i=120;i>0;i--);

}

}

/

void init(){

TMOD=0x01; //开定时器1

TH0=(65536-200)/256;//200us定时

TL0=(65536-200)%256;

ET0=1;//开定时器1中断

EA=1;//开总中断

TR0=1;//开定时器1

}

void timer0()interrupt 1//中断函数

{ TH0=(65535-200)/256; //重新赋值

TL0=(65535-200)%256;

CLK=~CLK;//CLK端口取反

}

void disp(){//显示

X1=1;

X2=0;

X3=0;

P0=table[b];//数码管显示数据(下同)

P07=0;

X1=1;

X2=0;

X3=0;

delayus(5);

P0=0XFF;//消隐

P0=table[s];

X1=0;

X2=1;

X3=0;

delayus(5);

P0=0XFF;

P0=table[g];

X1=0;

X2=0;

X3=1;

delayus(5);

P0=0XFF;

}

void main(){

P1=0XFF;

init();//initialization

P2=0XFF;

ADDA=0;

ADDB=0;

ADDC=0;

while(1){

ST=0;

OE=0;

ST=1;

ST=0;

while(EOC==0);//等待AD采样结束还是什么的,看不清

OE=1;

getdata=P1;

OE=0;

temp=getdata10/255500;

b=temp/100;//采集到的值送去显示

s=temp/10%10;

g=temp%10;

disp();

}

}

哎哟你妹的累死我了,中英文之间来回切换!

CRLF MACRO;定义宏

MOV DL,0DH;调用DOS中断字符输出,输出字符ASCLL是0DH,即换行符

MOV AH,02H;中断功能号02H

INT 21H;DOS中断,21H

MOV DL,0AH;调用DOS中断字符输出,输出字符ASCLL是0AH,即回车

MOV,AH,02H;中断功能号02H

INT 21H;;DOS中断,21H

ENDM ;宏定义结束

DATA SEGMENT ;数据段

DATA1 DB 33H,39H,31H,37H,34H

DATA2 DB 36H,35H,30H,38H,32H

DATA ENDS;数据段结束

STACK SEGMENT堆栈段

STA DB 20 DUP()

TOP EQU LENGTH STA ;预定义TOP为STA的长度

STACK ENDS;堆栈段结束

CODE SEGMENT;代码段

ASSUME CS:CODE,DS:STACK,ES:DATA ;指定相关段

START: MOV AX,DATA;把DATA段的段地址赋予AX

MOV DS,AX;通过AX把DATA段地址赋予DS

MOV AX,STACK;把STACK段的段地址赋予AX

MOV SS,AX;通过AX把STACK段地址赋予SS

MOV AX,TOP;把TOP赋予AX

MOV SP,AX;把AX的值赋予栈指针,即让SP指向堆栈段段尾

MOV SI,OFFSET DATA2;把变量DATA2的偏移地址赋予SI

MOV BX,05;把BX赋值为05

CALL DISPL;调用子程序DISPL

CRLF;宏CRLF,即输出换行符

MOV SI,OFFSET DATA1;把变量DATA1的偏移地址赋予SI

MOV BX,05;把BX赋值为05

CALL DISPL;调用子程序DISPL

CRLF;宏CRLF,即输出换行符

MOV DI,OFFSET DATA2;把变量DATA2的偏移地址赋予DI

CALL ADDA;调用子程序ADDA

MOV SI,OFFSET DATA1;把变量DATA1的偏移地址赋予DI

MOV BX,05;把BX赋值为05

CALL DISPL;调用子程序DISPL

CRLF;宏CRLF,即输出换行符

MOV AX,4C00H ;准备调用DOS终端结束程序,功能号4CH,返回值0

INT 21H;调用DOS中断

DISPL PROC NEAR ;子程序DISPL

DS1:MOV AH,02 ;准备调用DOS中断,功能好02,即字符输出

MOV DL,[SI+BX-1];字符的ASCLL代码在[SI+BX-1]中

INT 21H;调用中断

DEC BX;BX值减1

JNZ DS1;条件跳转到DS1,即重复5次

RET;子程序返回

DISPL ENDP;子程序结束

ADDA PROC NEAR;子程序NEAR

MOV DX,SI;SI值赋予DI

MOV BP,DI;DI值赋予BP

MOV BX,05;把BX赋值为05

AD1:SUB BYTE PTR[SI+BX-1],30H;[SI+BX-1]中的数值减30H

SUB BYTE PTR[DI+BX-1],30H;[DI+BX-1]中的数值减30H

DEC BX ;BX值减1

JNZ AD1;条件跳转,即循环5次

MOV SI,DX;把DX的值赋予SI

MOV DI,BP;把BP的值赋予DI

MOV CX,05;把CX赋值为05

CLC;CF标识符清零

AD2: MOV AL,[SI];把[SI]中的值赋予AL

MOV BL,[DI];把[DI]中的值赋予BL

ADC AL,BL;AL=AL+BL

AAA;非压缩BCD码调整

MOV [SI],AL;AL的值赋予[SI]

INC SI;SI=SI+1

INC DI;DI=DI+1

LOOP AD2;循环跳转AD2

MOV SI,DX;SI赋值为DX的值

MOV DI,BP;DI赋值为BP的值

MOV BX,05;BX赋值为05

AD3:ADD BYTE PTR[SI+BX-1],30H;[SI+BX-1]中的数值加30H

ADD BYTE PTR[DI+BX-1],30H;[DI+BX-1]中的数值加30H

DEC BX;BX=BX-1

JNZ AD3;条件跳转到AD3

RET;子程序返回

ADDA ENDP;子程序结束

CODE ENDS;代码段结束

END START;程序结束

以上就是关于MCS-51单片机查表程序全部的内容,包括:MCS-51单片机查表程序、adc8080的ad转换单片机程序、用51单片机编写程序实现数码管的时钟数字显示等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9722542.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存