电路图比较简单,是一个51最小系统,没有采用总线方式,而简单的连线方式,上有4*4矩阵键盘,一数码管,89S51单片机,串口下载线,数码管显示锁存芯片\蜂鸣器\1602液晶.
因为最近考试太多,刚刚考试完又课程设计,桌子上太混乱,原理图没有找到.所以就先贴上代码.
此代码已经调试成功过,可以实现时间的调整.4*4矩阵键盘,第一排前三列是实现小时\分钟\秒的加.第二排前三列是实现小时\分钟\秒的减.当然还可以通过设置矩阵键盘的键值,来实现加\减\乘\除四则运算,由数码管显示参与运算的数字以及最终的运算结果.其他的不多说了,等下次我把图贴上,大家勉强可以拿去研究下.其实硬件很简单,不详细说问题也不大的.
#include
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar temp1;
void displayListChar(unsigned char X, unsigned char Y, uchar DData);
uchar dispbuf[]={'0','1','2','3','4','5','6','7','8','9',':'};
uchar second;
uchar minute;
uchar hour;
uint tcnt,g;
uchar flag;
void dlms(void);
uchar kbscan(void);
void Show_Time(void);
void delay5ms(void);
void dlms(void);
void Settime(uchar verify);//verify 在这里为调整的意思
void delay400ms(void) ;
///#define busy 0x80 file://用/于检测LCD状态字中的Busy标识
///#define RSaddr 0x1000
///#define RWaddr 0x2000
///#define CSaddr 0x0400
#define wc 0x8fff
#define wd 0xdfff
#define rc 0xbfff
void waitLcd() //just wait until 液晶不忙为止
{
char temp;
bit flag=1;
while(flag==1)
{
temp=XBYTE[rc];
if (temp>>7==0) flag=0;
P1=temp;
}
P1=0xff;
}
//just wait until 液晶不忙为止
void WriteCommand_Lcd(bit isCheck,char c)
{
if (isCheck==1) waitLcd();
XBYTE[wc]=c;
}
void writedata(char c)
{
waitLcd();
XBYTE[wd]=c;
}
void LcdInit()
{
delay5ms();
delay5ms();
delay5ms();
WriteCommand_Lcd(0,0x38); //三次显示模式设置,不检测忙信号
delay5ms();
WriteCommand_Lcd(0,0x38);
delay5ms();
WriteCommand_Lcd(0,0x38);
delay5ms();
WriteCommand_Lcd(1,0x38); //显示模式设置,开始要求每次检测忙信号,8位2行5*7
WriteCommand_Lcd(1,0x08); //关闭显示
WriteCommand_Lcd(1,0x01); //清显示
WriteCommand_Lcd(1,0x06); // 文字不动,光标右移
WriteCommand_Lcd(1,0x0C); // 显示开及光标设置
}
void displayListChar(unsigned char X, unsigned char Y, uchar DData)
{
Y &= 0x1;
X &= 0xF;
if (X {
Y &= 0x1;
X &= 0xF;
if (Y) X |= 0x40;
X |= 0x80;
WriteCommand_Lcd(0,X);
writedata(dispbuf[DData]);
}
}
void Show_Time(unit k)
{
displayListChar(0,0,hour/10);
displayListChar(1,0,hour%10);
displayListChar(2,0,10);
displayListChar(3,0,minute/10);
displayListChar(4,0,minute%10);
displayListChar(5,0,10);
displayListChar(6,0,second/10);
displayListChar(7,0,second%10);
switch(k)
{
case 1: displayListChar(0,1,1);
case 2: displayListChar(0,1,2);
case 3: displayListChar(0,1,3);
case 4: displayListChar(0,1,4);
case 5: displayListChar(0,1,5);
case 6: displayListChar(0,1,6);
case 7: displayListChar(0,1,7);
case 8: displayListChar(0,1,8);
case 9: displayListChar(0,1,9);
case 10:displayListChar(0,1,10);
case 11:displayListChar(0,1,11);
case 12:displayListChar(0,1,12);
case 13:displayListChar(0,1,13);
case 14:displayListChar(0,1,14);
case 15:displayListChar(0,1,15);
case 16:displayListChar(0,1,16);
}
void Settime(uchar verify)
{
//键盘设置
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe +
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd -
// 7 8 9 *
// 0 CLR = /
////hour+的代码
if(flag)
{
if (verify==0xee)
{
dlms();
if (verify==0xee)
{
hour++;
if(hour==24)
{
hour=0;
}
//while(verify==0xee);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
///minute +的代码
else if (verify==0xde)
{
dlms();
if (verify==0xde)
{
minute++;
if(minute==60)
{
minute=0;
}
//while(verify==0xde);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
//////second++的代码
else if (verify==0xbe)
{
dlms();
if (verify==0xbe)
{
second++;
if(second==60)
{
second=0;
}
// while(verify==0xbe);
verify=0x00;
}
// 1 /hour+ (0xee) 2/minute+ 0xde 3/second+ 0xbe
}
//////hour- (0xed) 的代码
else if (verify==0xed)
{
dlms();
if (verify==0xed)
{
if(hour==0)
{hour=24;
}
hour--;
// if(hour==0)
// {
// hour=23;
//}
//while(verify==0xed);
verify=0x00;
}
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
///下面为minute -的代码
else if (verify==0xdd)
{
dlms();
if (verify==0xdd)
{ if(minute==0)
{minute=60;}
minute--;
//if(minute==0)
//{
// minute=59;
//}
//while(verify==0xdd);
verify=0x00;
}
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
///下面为second -的代码
else if (verify==0xbd)
{
dlms();
if (verify==0xbd)
{ if(second==0)
{second=60;}
second--;
//if(second==0)
//{
// second=59;
//}
// while(verify==0xbd);
verify=0x00;
}
// 4/hour- 0xed 5/ minute- 0xdd 6/second- 0xbd
}
}
}
void main(void)
{
TMOD=0x02; //置自动重装载模式
TH0=0x06; //设初值
TL0=0x06; //设初值
TR0=1; //开始计数
ET0=1; //开定时器/计数器
EA=1; //中断开
delay400ms();//启动等待,等LCM讲入工作状态
LcdInit(); //LCM初始化
while(1)
{
uchar key;
key=kbscan();
dlms();
Show_Time();
// if ((key==0xee)||(key==0xbe)||(key==0xde)||(key==0xed)||(key==0xdd)||(key==0xbd))
if (key!=0)
{
if (key==0x7e)
{
dlms();
if (key==0x7e)
{
EA=0;
flag=1;
}
//while(verify==0xee);
key=0x00;
}
if (key==0x7d)
{
dlms();
if (key==0x7d)
{
EA=1;
flag=0;
}
//while(verify==0xee);
key=0x00;
}
Settime( key );
delay400ms();
}
}
}
void delay5ms(void)
{
unsigned int TempCya = 277;
while(--TempCya);
}
//延时400ms
void delay400ms(void)
{
unsigned int TempCya = 22160;
while(--TempCya);
}
//延时400ms
void timer0(void) interrupt 1 using 1
{
tcnt++;
if(tcnt==2000)
{
tcnt=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
}
//键盘扫描
uchar kbscan(void)
{
uchar sccode;
P1=0xf0;
if( (P1&0xf0)!=0xf0 )
{
dlms();
if((P1&0xf0)!=0xf0)
{
sccode=0xfe;
while ((sccode&0x10)!=0)
{
P1=sccode;
if ((P1&0xf0)!=0xf0)
{
temp1=P1;
return temp1;
}
else
{
sccode=(sccode }
}
}
}
return (0);
}
void dlms(void)
{
g=554;
while(g--); //延时10mS钟
}