ORG 0000H
LJMP MAIN
ORG 0030H
MAIN:MOV KEYBUF,#0初始键号设位0,也可以为任意值
MOV R0,#30H 显示首地址
MOV R2,#0CH 计算数据存放单元个数
CLR A
QING:MOV @R0,A将数据存放单元清零
INC R0
DJNZ R2,QING
MOV P0,#8FH 关闭显示
MOV R1,#30H 将显示首地址存放R1里
===============================================
五位无符号显示子程序
DIS1:MOV R0,#30H 把显示数据第一位放在R0里
MOV R2,#04H 把显示的位码轿塌放在R2里
MOV R3,#05H 把显示的长度放在R3里
DIS2:MOV A,@R0
ANL A,#0FH 屏蔽显示数据的高闭悉圆四位
MOV B,A
MOV A,R2
ANL A,#0FH 屏蔽位码的高四位
SWAP A
ORL A,B
MOV P0,A 送总显示数据到P0显示
LCALL DELY4ms调用延时4ms
INC R0 取下一个显示数据
DEC R2
DJNZ R3,DIS2 四位显示晚后重新开始显示
===================================================
键盘扫描子程序
WAIT:MOV P1,#0FFHP1口送高电平
CLR P1.0第一行清零
MOV A,P1读P1口
ANL A,#0F0H 低位屏蔽
XRL A,#0F0H 判断低位是否有低电平 ,即判断是否有按键按下
JZ NOKEY1 地位有低电平继续扫描,否者跳到第而行去扫描
LCALL DELY10ms 延时10ms去抖在进行判断是否有按键按下
MOV A,P1继续读P1口
ANL A,#0F0H 判断低位是否有低电平
CJNE A,#0E0H,NK1如果扫描数据不为0E0H就转到NK1
MOV KEYBUF,#0 否者判断为0号键
AJMP DK 转DK1查表程序
NK1: CJNE A,#0D0H,NK2如果扫描数据不为0D0H就转到NK2
MOV KEYBUF,#1 否者判断为1号键
AJMP DK 转DK2查表程序
NK2: CJNE A,#0B0H,NK3如果扫描数据不为0B0H就转到NK3
MOV KEYBUF,#2 否者判断为2号键
AJMP DK 转DK3查表程序
NK3: CJNE A,#70H,NK4 如果扫描数据不为70H就陆禅转到NK4
LJMP SAN_CHU
NK4: NOP
NOKEY1: MOV P1,#0FFH和上面相同
CLR P1.1
MOV A,P1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY2
LCALL DELY10MS
MOV A,p1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY2
MOV A,P1
ANL A,#0F0H
CJNE A,#0E0H,NK5
MOV KEYBUF,#3
AJMP DK
NK5: CJNE A,#0D0H,NK6
MOV KEYBUF,#4
AJMP DK
NK6: CJNE A,#0B0H,NK7
MOV KEYBUF,#5
AJMP DK
NK7: CJNE A,#70H,NK8
MOV KEYBUF,#10 否者判断为3号键
AJMP DK 转DK4查表程序
NK8: NOP
NOKEY2: MOV P1,#0FFH
CLR P1.2
MOV A,P1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY3
LCALL DELY10MS
MOV A,P1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY3
MOV A,P1
ANL A,#0F0H
CJNE A,#0E0H,NK9
MOV KEYBUF,#6
AJMP DK
NK9: CJNE A,#0D0H,NK10
MOV KEYBUF,#7
AJMP DK
NK10:CJNE A,#0B0H,NK11
MOV KEYBUF,#8
AJMP DK
NK11:CJNE A,#70H,NK12
LJMP DENG_HAO
NK12:NOP
NOKEY3: MOV P1,#0FFH
CLR P1.3
MOV A,P1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY4
LCALL DELY10MS
MOV A,P1
ANL A,#0F0H
XRL A,#0F0H
JZ NOKEY4
MOV A,P1
ANL A,#0F0H
CJNE A,#0E0H,NK13
LJMP CHU
NK13:CJNE A,#0D0H,NK14
LJMP CHENG
NK14:CJNE A,#0B0H,NK15
LJMP JIAN
NK15:CJNE A,#70H,NK16
LJMP JIA
NK16:NOP
=======================================================
查表求键值程序
DK: MOV B,#00H
MOV A,KEYBUF 查表程序 查对应的键号数据
MOV DPTR,#TABLE 把表头地址放入DPTR
MOVC A,@A+DPTR A里面存放的为键号,利用A和表头地址找到对应的键号数据
MOV B,A 把查到的数据送往显示单元
INC R1 取下一个显示单元
MOV A,R1
CJNE A,#36H,DKA1 判断显示单元是否已满
MOV R1,#35H 35H,36H单元用于更好的控制五位显示
AJMP DKA
DKA1:MOV 34H,33H 按键代码按左移显示,先按先显示
MOV 33H,32H
MOV 32H,31H
MOV 31H,30H
MOV 30H,B
DKA: MOV A,P1 读P1口
ANL A,#0F0H 屏蔽高四位
XRL A,#0F0H 地位是有低电平
JNZ DKA 如果有低电平继续读P1口,否者向下执行,查找第二行
NOKEY4: LJMP DIS1
===================================
功能按键功能设定
DENG_HAO:MOV DPTR,#JI_SUAN等号键功能通过加、减、乘、除设定的偏移量来调用子程序
MOV A,3CH3CH存放的为功能程序入口地址偏移量
JMP @A+DPTR 转移到按键功能程序
JI_SUAN: AJMP JIA1加计算子程序
AJMP JIAN1 减计算子程序
AJMP CHENG1 乘计算子程序
AJMP CHU 除计算子程序
=======删除键功能
SAN_CHU: ACALL QING_DIS
AJMP DKA
=======加键功能
JIA: MOV 3CH,#00H
ACALL CUN_SHU
ACALL QING_DIS
AJMP DKA
=======减键功能
JIAN:MOV 3CH,#02H
ACALL CUN_SHU
ACALL QING_DIS
AJMP DKA
=======乘键功能
CHENG: MOV 3CH,#04H
ACALL CUN_SHU
ACALL QING_DIS
AJMP DKA
=======除键功能
CHU: MOV 3DH,#06H
ACALL CUN_SHU
ACALL QING_DIS
AJMP DKA
=================================
存被加(减、乘、除)数,存放在37H~3BH里
CUN_SHU: MOV 37H,30H36H存放的为最低位
MOV 38H,31H
MOV 39H,32H
MOV 3AH,33H
MOV 3BH,34H3AH存放的为最高位
RET
================================
清除显示单元
QING_DIS: MOV R1,#30H
QING1:MOV @R1,#00H
INC R1
MOV A,R1
CJNE A,#36H,QING1
MOV R1,#30H
LOP1: RET
================================
十进制加法子程序
JIA1:
MOV A,37H 个位被加数
ADD A,30H 个位被加数+加数
MOV B,#10 十六进制除10转换成BCD码
DIV AB
MOV 30H,B 余数即个位存放在30H
MOV 37H,A 商存放在37H
MOV A,38H 十位被加数
ADD A,31H 十位被加数+加数
ADD A,37H 加上个位之和的进位
MOV 37H,#00H 清除37H
MOV B,#10 十六进制除10转换成BCD码
DIV AB
MOV 31H,B 余数即十位存放在31H
MOV 38H,A 商存放在38H
MOV A,39H 百位计算同十位
ADD A,32H
ADD A,38H
MOV 38H,#00H
MOV B,#10
DIV AB
MOV 32H,B
MOV 39H,A
MOV A,3AH 千位计算同十位
ADD A,33H
ADD A,39H
MOV 39H,#00H
MOV B,#10
DIV AB
MOV 33H,B
MOV 3AH,A
MOV A,3BH 万位计算同十位
ADD A,34H
ADD A,3AH
MOV 3AH,#00H
MOV B,#10
DIV AB
MOV 34H,B
MOV 3BH,#00H
AJMP DKA
=====================
JIAN1: AJMP DKA
CHENG1: AJMP DKA
CHU1:AJMP DKA
=============================================
延时程序和查表表格
DELY4ms: MOV R6,#8延时4毫秒
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DELY10ms:MOV R6,#20 延时10毫秒
D2: MOV R7,#248
DJNZ R7,$
DJNZ R6,D2
RET
TABLE: DB 07H, 04H, 01H / 本表格是以键盘为参考 7 8 9 /
DB 08H, 05H, 02H * 4 5 6 *
DB 09H, 06H, 03H - 1 2 3 -
DB 00H, 00H = + 清除 0 = +
END
//这是51hei单片机开发板让纯冲附带的一个程序,矩阵键盘接p3口,其中p3.0-p3.4为行,P3.5->p3.7为列//每按一下键数字便可显示在1602液晶上面,并且蜂鸣器会发出响声.
//全部源代码下载: http://www.51hei.com/f/jz1602.rar
#include<reg52.h>裤庆
#include <Intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6
sbit wela=P2^7
sbit rs=P2^2
sbit lcden=P2^0
sbit rw=P2^1
sbit BEEP=P2^3
uchar num,temp,date,i
uchar code table_1[]=" shu ru tiao ma "
uchar code table_2[]=" Pro_8888 "
uchar code dis_tab[17]=
{
0x30, //0在1602中的十六进制码
0x31, //1在1602中的十六进制码
0x32, //2在1602中的十六进制码
0x33, //3在1602中的十六进制码
0x34, //4在1602中的十六进制码
0x35, //5在1602中的十六进制码
0x36, //6在1602中的十六进制码
0x37, //7在1602中的十六进制码
0x38, //8在1602中的十六进制码
0x39, //9在1602中的十六进制码
0x41, //A在1602中的十六进制码
0x42, //B在1602中的十六进制码
0x43, //C在1602中的十六进制码
0x44, //D在1602中的十六进制码
0x2A, //*在1602中的十六进制码
0x23, //#在1602中的十六进制码
0x20, // 在1602中的十六进制码
}
void delay(uint z)
{
uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
void beep()
{
uchar i
for (i=0i<50i++)
{
delay(4)
BEEP=0 //BEEP取反
}
BEEP=1 //关闭蜂鸣器
delay(100) //延时
}
void lcd_wait_busy() //1602忙检测函数
{
P0=0xff //数据口全部置1,为读状态做准备
rs=0 //选择指令寄存器
rw=1 //选择读
lcden=1 //使能线电平变化
while((P0&0x80)==0x80)//读忙状态,不忙时退出
lcden=0 //恢复使能线电平
}
// 1602写命令函数
void lcd_write_com(unsigned char combuf)
{
rs=0 //选择指令寄存器
rw=0 //选择写
P0=combuf //把命令字送入P2
lcden=1 //使能线电平变化,命令送入1602的8位数据口
_nop_()
lcden=0 //恢复使能线坦歼电平
}
// 1602写命令函数(带忙检测)
void lcd_write_com_busy(unsigned char combuf)
{
lcd_wait_busy() //调用忙检测函数
lcd_write_com(combuf) //调用写命令函数
}
// 1602写数据函数(带忙检测)
void lcd_write_data(unsigned char databuf)
{
lcd_wait_busy() //调用忙检测函数
rs=1 //选择数据寄存器
rw=0 //选择写
P0=databuf //把数据字送入P2
lcden=1 //使能线电平变化,命令送入1602的8位数据口
_nop_()
lcden=0 //恢复使能线电平
}
// 1602显示地址写函数
void lcd_write_address(unsigned char x,unsigned char y)
{
y&=0x01 //行地址限制在0-1
if(y==0x00)
lcd_write_com_busy(x|0x80) //第一行的列地址写入
else
lcd_write_com_busy((x+0x40)|0x80) //第二行的列地址写入
}
// 指定地址写入函数
void lcd_write_char(unsigned char x,unsigned char y,unsigned char buf)
{
lcd_write_address(x,y)//写入地址
lcd_write_data(buf) //写入显示数据
}
// 液晶初始化指令
void lcd_init()
{
uchar num
dula=0
wela=0
lcden=0
lcd_write_com_busy(0x38)//设置16*2显示,5*7点阵,8位数据接口
lcd_write_com_busy(0x0d)//关显示 显示光标 光标闪烁
lcd_write_com_busy(0x06)//当读或写一个字符后地址指针加一,且光标加一,写一个字符,整屏显示移动
lcd_write_com_busy(0x01)//显示清屏:1,数据指针清零 2,所有显示清零
lcd_write_com_busy(0x80)//80h+地址码(0-27h,40h-67h) 设置数据地址指针
for(num=0num<16num++)
{
lcd_write_data(table_1[num])
delay(5)
}
lcd_write_com_busy(0x80+0x40)
}
void key_wdat(uchar i) //按键写数据
{
// dula=0
// wela=0
// lcden=0
//液晶初始化指令
// write_com(0x38)//设置16*2显示,5*7点阵,8位数据接口
// write_com(0x0d)//关显示 显示光标 光标闪烁
// write_com(0x06)//当读或写一个字符后地址指针加一,且光标加一,写一个字符,整屏显示移动
// write_com(0x01)//显示清屏:1,数据指针清零 2,所有显示清零
// write_com(0x80+0x40)//80h+地址码(0-27h,40h-67h) 设置数据地址指针
lcd_wait_busy()
lcd_write_data(i)
delay(100)
}
// 删除液晶第1或2行全部数据
void clear(uchar t)
{
if(t==1)
{
lcd_write_com_busy(0x80)
}
if(t==2)
{
lcd_write_com_busy(0x80+0x40)
}
for(i=0i<15i++)
{
lcd_write_data(dis_tab[16])
}
lcd_write_com_busy(0x80+0x40)
}
// 产品显示函数 待写 如何从键盘输入中提取出三位的产品号码???????????????????
/*
void display_product()
{
}
*/
// 4*4矩阵键盘检测
void keyscan()
{
lcden=1//???
//
P3=0xfe
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
delay(5)
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xee:key_wdat(dis_tab[7])beep() // 7
break
case 0xde:key_wdat(dis_tab[8])beep() // 8
break
case 0xbe:key_wdat(dis_tab[9])beep() // 9
break
case 0x7e:key_wdat(dis_tab[17])beep() //
break
}
while(temp!=0xf0)
{
temp=P3
temp=temp&0xf0
}
}
}
//
P3=0xfd
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
delay(5)
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xed:key_wdat(dis_tab[4])beep() // 4
break
case 0xdd:key_wdat(dis_tab[5])beep() // 5
break
case 0xbd:key_wdat(dis_tab[6])beep() // 6
break
case 0x7d:key_wdat(dis_tab[17])beep() //
break
}
while(temp!=0xf0)
{
temp=P3
temp=temp&0xf0
}
}
}
//
P3=0xfb
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
delay(5)
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xeb:key_wdat(dis_tab[1])beep() // 1
break
case 0xdb:key_wdat(dis_tab[2])beep() // 2
break
case 0xbb:key_wdat(dis_tab[3])beep() // 3
break
case 0x7b:key_wdat(dis_tab[17])beep() //
break
}
while(temp!=0xf0)
{
temp=P3
temp=temp&0xf0
}
}
}
//
P3=0xf7
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
delay(5)
temp=P3
temp=temp&0xf0
while(temp!=0xf0)
{
temp=P3
switch(temp)
{
case 0xe7:key_wdat(dis_tab[0])beep() // 0
break
case 0xd7:key_wdat(dis_tab[17])beep() //
break
case 0xb7:clear(2)beep() // 删除液晶第二行
break
case 0x77:beep() // enter
break
}
while(temp!=0xf0)
{
temp=P3
temp=temp&0xf0
}
}
}
}
//
void main()
{
lcd_init()
while(1)
{
keyscan()
}
while(1)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)