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单片机编写程序实现数码管的时钟数字显示等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)