学习笔记
学习科目: |
单片机 |
学习安排: |
单片机 |
开始时间: |
2022-01-28 |
结束时间: |
2022-01-28 |
注意在这个计算器程序中,当定时器中断进行keyscan()函数时,我们不能再把P20、P21的电频拉高了(P22、P23仍需要拉高)(这一点和之前的按键功能程序不一样)。因为如果在中断里对P20、P21电频拉高,那么每隔1ms进入中断时,LCD1602的RS与RW引脚的数值都会改变,如果是单片机在运行读状态、写指令、写数据这三个函数时进入了中断,那么P20、P21引脚电频的改变会终止读状态、写指令、写数据这三个函数的运行,即使中断结束,这三条指令也不会再正常运行,导致的结果就是LCD1602连初始化都无法完成。这就需要我们在LCD1602读状态、写指令、写数据的程序运行完毕之后再对P20(RS)、P21(RW)重新赋值,确保这三条指令在运行中即使进入了中断也不会对其造成影响,但此时按键的功能会有所下降,按键的扫描会不准确(不过问题不大,我在使用时就很少出现按键扫描不准确的状况,但还是有的)。
LCD1602实现计算机功能
1、LCD1602.c文件
#include<reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS=P2^0;
sbit LCD1602_RW=P2^1;
sbit LCD1602_E=P1^2;
unsigned char i;
void LcdWaitReady()
{
unsigned char sta=0;
LCD1602_DB=0xFF;
LCD1602_RS=0;
LCD1602_RW=1;
do
{
LCD1602_E=1;
sta=LCD1602_DB;
for(i=0;i<2;i++);
LCD1602_E=0;
}
while(sta&0x80);
LCD1602_RS=1;
LCD1602_RW=1; //P20,P21ÖØD¸3Ö죬½ÃÕykeyscan£¨£©oˉêy
}
void LcdWritecmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DB=cmd;
LCD1602_E=1;
for(i=0;i<2;i++);
LCD1602_E=0;
LCD1602_RS=1;
LCD1602_RW=1; //P20,P21ÖØD¸3Ö죬½ÃÕykeyscan£¨£©oˉêy
}
void LcdWritedat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_DB=dat;
LCD1602_E=1;
for(i=0;i<2;i++);
LCD1602_E=0;
LCD1602_RS=1;
LCD1602_RW=1; //P20,P21ÖØD¸3Ö죬½ÃÕykeyscan£¨£©oˉêy
}
void LcdSetCursor(unsigned char x,unsigned char y)
{
unsigned char addr;
if(y==0)
{
addr=0x00+x;
}
else
{
addr=0x40+x;
}
LcdWritecmd(0x80+addr);
}
void LcdShowstr(unsigned char x,unsigned char y,unsigned char *str)
{
LcdSetCursor(x,y);
while(*str!='\0')
{
LcdWritedat(*str++);
}
}
void LcdAreaClean(unsigned char x,unsigned char y,unsigned char len)
{
LcdSetCursor(x,y);
while(len--)
{
LcdWritedat(' ');
}
}
void LcdFullClaen()
{
LcdWritecmd(0x01);
}
void initlcd1602()
{
LcdWritecmd(0x38);
LcdWritecmd(0x0C);
LcdWritecmd(0x06);
LcdWritecmd(0x01);
}
2、keyboard.c文件
#include<reg52.h>
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit kout1=P2^4;
sbit kout2=P2^5;
sbit kout3=P2^6;
sbit kout4=P2^7;
extern void GetResult();
extern void reset();
extern void Numkeraction(unsigned char n);
extern void Oprtkeyaction(unsigned char type);
extern void LcdShowstr(unsigned char x,unsigned char y,unsigned char *str);
unsigned char pdata keysta[4][4]={
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1} //°′¼ü×′쬼ì2a
};
unsigned char code keycodeMap[4][4]={
{'1','2','3',0x26}, //êy×Ö¼ü1£»êy×Ö¼ü2£»êy×Ö¼ü3£»ÏòéÏ ¼ó
{'4','5','6',0x25}, //êy×Ö¼ü4£»êy×Ö¼ü5£»êy×Ö¼ü6£»Ïò×ó ¼õ
{'7','8','9',0x28}, //êy×Ö¼ü7£»êy×Ö¼ü8£»êy×Ö¼ü9£»ÏòÏ 3Ë
{'0',0x1B,0x0D,0x27} //êy×Ö¼ü0£»ESC¼ü£»»Ø3μ¼ü£» Ïòóò 3y
};
void keyaction(unsigned char keycode)
{
if((keycode>='0')&&(keycode<='9'))
{
Numkeraction(keycode-'0');
}
else if(keycode==0x26)
{
Oprtkeyaction(0); //¼ó
}
else if(keycode==0x25)
{
Oprtkeyaction(1); //¼õ
}
else if(keycode==0x28)
{
Oprtkeyaction(2); //3Ë
}
else if(keycode==0x27)
{
Oprtkeyaction(3); //3y
}
else if(keycode==0x0D)
{
GetResult(); //μèóú
}
else if(keycode==0x1B)
{
reset();
LcdShowstr(15,1,"0"); //1éáã
}
}
void keydrive()
{
unsigned char i,j; //iêÇDD£¬jêÇáD
static unsigned char pdata backup[4][4]={
{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(backup[i][j]!=keysta[i][j])
{
if(backup[i][j]!=0)
{
keyaction(keycodeMap[i][j]);
}
backup[i][j]=keysta[i][j];
}
}
}
}
void keyscan()
{
static unsigned char keyout=0;
unsigned char i=0;
static unsigned char keybuf[4][4]={
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF
};
P22=123=1;
keybuf[keyout][0]=(keybuf[keyout][0]<<1)|P20;
keybuf[keyout][1]=(keybuf[keyout][1]<<1)|P21;
keybuf[keyout][2]=(keybuf[keyout][2]<<1)|P22;
keybuf[keyout][3]=(keybuf[keyout][3]<<1)|P23;
for(i=0;i<4;i++)
{
if((keybuf[keyout][i]&0x0F)==0x00)
{
keysta[keyout][i]=0;
}
else if((keybuf[keyout][i]&0x0F)==0x0F)
{
keysta[keyout][i]=1;
}
else{}
}
keyout++;
if(keyout>=4)
{
keyout=0;
}
switch(keyout)
{
case 0:kout1=1;kout4=0;break;
case 1:kout3=0;kout4=1;break;
case 2:kout2=0;kout3=1;break;
case 3:kout1=0;kout2=1;break;
default :break;
}
}
3、main.c文件
#include<reg52.h>
unsigned char T0RH=0;
unsigned char T0RL=0;
unsigned char step=0;
unsigned char oprt=0;
signed long num1=0;
signed long num2=0;
signed long result=0;
void configTimer0(unsigned int ms);
extern void LcdShowstr(unsigned char x,unsigned char y,unsigned char *str);
extern void initlcd1602();
extern void keydrive();
extern void keyscan();
extern void LcdAreaClean(unsigned char x,unsigned char y,unsigned char len);
extern void LcdFullClaen();
void main()
{
EA=1;
configTimer0(1);
initlcd1602();
LcdShowstr(15,1,"0");
while(1)
{
keydrive();
}
}
unsigned char LongToString(unsigned char *str,signed long dat) //êy×Ö×a»»Îa×Ö·û2¢óÃlen±íê¾Æä3¤¶è
{
signed char i=0;
unsigned char len=0;
unsigned char buf[12];
if(dat<0)
{
dat=-dat;
*str++='-';
len++;
}
do
{
buf[i++]=dat%10;
dat/=10;
}
while(dat>0);
len+=i;
while(i-->0)
{
*str++=buf[i]+'0';
}
*str='\0';
return len;
}
void showoprt(unsigned char y,unsigned char type) //ÔËËã·ûÏÔê¾£¬ÏÔê¾Ôú×î×ó2à
{
switch(type)
{
case 0cdShowstr(0,y,"+"); break;
case 1cdShowstr(0,y,"-"); break;
case 2cdShowstr(0,y,"*"); break;
case 3cdShowstr(0,y,"/"); break;
default:break;
}
}
void reset()
{
num1=0;
num2=0;
step=0;
LcdFullClaen();
}
void Numkeraction(unsigned char n) //êy×Ö¼ü°′ÏÂ
{
unsigned char len=0;
unsigned char str[12];
if(step>1)
{
reset();
}
if(step==0)
{
num1=num1*10+n;
len=LongToString(str,num1);
LcdShowstr(16-len,1,str); //Ôúμú¶tDD×îóò2àÏÔê¾êy×Ö1
}
else
{
num2=num2*10+n;
len=LongToString(str,num2);
LcdShowstr(16-len,1,str); //Ôúμú¶tDD×îóò2àÏÔê¾êy×Ö2
}
}
void Oprtkeyaction(unsigned char type) //ÔËËã·û¼ü°′ÏÂ
{
unsigned char len=0;
unsigned char str[12];
if(step==0)
{
len=LongToString(str,num1);
LcdAreaClean(0,0,16-len); //μúò»DD2¿·ÖÇåÆᣬ×Ö·û×ó2à2¿·Ö
LcdShowstr(16-len,0,str); //μúò»DDÏÔê¾êy×Ö1
showoprt(1,type); //ÔËËã·ûÏÔê¾Ôúμú¶tDD×ó2à
LcdAreaClean(1,1,14); //ÇåÆáÏÔê¾Æáμú¶tDDÖD¼ä1~14λáôÏÂ0oí15ÏÔê¾Î»
LcdShowstr(15,1,"0"); //μú¶tDD×îóò2àÏÔê¾×Ö·û0
oprt=type;
step=1;
}
}
void GetResult()
{
unsigned char len=0;
unsigned char str[12];
if(step==1)
{
step=2;
switch(oprt)
{
case 0:result=num1+num2;break;
case 1:result=num1-num2;break;
case 2:result=num1*num2;break;
case 3:result=num1/num2;break;
default:break;
}
len=LongToString(str,num2);
showoprt(0,oprt);
LcdAreaClean(1,0,16-1-len);
LcdShowstr(16-len,0,str); //½«μú¶tDDÏÔê¾êy¾YòÆμ½μúò»DD
len=LongToString(str,result);
LcdShowstr(0,1,"="); //μú¶tDD×î×ó2àÏÔê¾=
LcdAreaClean(1,1,16-1-len);
LcdShowstr(16-len,1,str); //μú¶tDDÏÔê¾½á1û
}
}
void configTimer0(unsigned int ms)
{
unsigned long tmp=0;
tmp=32768000/12;
tmp=(tmp*ms)/1000;
tmp=65536-tmp;
tmp = tmp + 28;
T0RH=(unsigned char)(tmp>>8);
T0RL=(unsigned char)tmp;
TMOD&=0xF0;
TMOD|=0x01;
TH0=T0RH;
TL0=T0RL;
TR0=1;
ET0=1;
}
void interruptTime() interrupt 1
{
TH0=T0RH;
TL0=T0RL;
keyscan();
}
|
|