#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include "i2c.h"
//sbit LATCH1=P2^2; //定义锁存使能端口 段锁存
//sbit LATCH2=P2^3; //位锁存
sbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;
sbit SPK = P2^7;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
#define KeyPort P1
bit KeyPressFlag;//定义按键标志位
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char second;
unsigned char minute;
unsigned char hours;
unsigned char dat[3] = 0;
/*------------------------------------------------
uS延时函数
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
外部中断0初始化
------------------------------------------------*/
void Init_INT0(void)
{
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=1; //边沿触发
}
/*------------------------------------------------
外部中断0程序
------------------------------------------------*/
void ISR_INT0(void) interrupt 0
{
KeyPressFlag=1; //表明按键有动作,可以进行按键扫描
}
/*------------------------------------------------
按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法
{
unsigned char Val;
KeyPort=0xf0;//高四位置高,低四位拉低
if(KeyPort!=0xf0)//表示有按键按下
{
DelayMs(10); //去抖
if(KeyPort!=0xf0)
{ //表示有按键按下
KeyPort=0xfe; //检测第一行
if(KeyPort!=0xfe)
{
Val=KeyPort&0xf0;
Val+=0x0e;
while(KeyPort!=0xfe);
DelayMs(10); //去抖
while(KeyPort!=0xfe);
return Val;
}
KeyPort=0xfd; //检测第二行
if(KeyPort!=0xfd)
{
Val=KeyPort&0xf0;
Val+=0x0d;
while(KeyPort!=0xfd);
DelayMs(10); //去抖
while(KeyPort!=0xfd);
return Val;
}
KeyPort=0xfb; //检测第三行
if(KeyPort!=0xfb)
{
Val=KeyPort&0xf0;
Val+=0x0b;
while(KeyPort!=0xfb);
DelayMs(10); //去抖
while(KeyPort!=0xfb);
return Val;
}
KeyPort=0xf7; //检测第四行
if(KeyPort!=0xf7)
{
Val=KeyPort&0xf0;
Val+=0x07;
while(KeyPort!=0xf7);
DelayMs(10); //去抖
while(KeyPort!=0xf7);
return Val;
}
}
}
return 0xff;
}
/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:
{
sec++;
if(sec == 60)
{
sec = 0;
}
break;
}
case 0x7d:
{
min++;
if(min == 60)
{
min = 0;
}
break;
}
case 0x7b:
{
hour++;
if(hour == 24)
{
hour =0 ;
}
break;
}
case 0x77:
{
second++;
if(second == 60)
{
second = 0;
}
break;
}
case 0xbe:
{
minute++;
if(minute == 60)
{
minute = 0;
}
break;
}
case 0xbd:
{
hours++;
if(hours == 24)
{
hours = 0;
}
break;
}
/* case 0xbb:;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f*/
default:return 0xff;break;
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
// while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
//while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
void ISR_time0() interrupt 1
{
unsigned char i;
EA = 0;
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
i++;
if(i == 20)
{
i = 0;
sec++;
}
EA = 1;
}
void time_add()
{
if(sec == 60)
{
sec = 0;
min++;
}
if(min == 60)
{
min = 0;
hour++;
}
if(hour == 24)
{
hour = 0;
}
if(sec == second && min == minute && hour == hours)
{
SPK = !SPK;
DelayMs(5);
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
IRcvStr(0xae,80,dat,16);
sec = dat[0];
min = dat[1];
hour = dat[2];
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
TR0 = 1;
EA = 1;
ET0 = 1;
Init_INT0();
LCD_Init();
LCD_Clear();//清屏
DelayMs(5);
while (1)
{
time_add();
KeyPort=0xf0; // 赋值用于中断检测
if(KeyPressFlag==1)
{
KeyPressFlag=0; //按键标志清零,以便下次检测
KeyPro();
}
LCD_Write_Char(7,0,'0' + sec%10);
LCD_Write_Char(6,0,'0' + sec/10);
dat[0] = sec;
LCD_Write_Char(5,0,0x3a);
LCD_Write_Char(4,0,'0' + min%10);
LCD_Write_Char(3,0,'0' + min/10);
dat[1] = min;
LCD_Write_Char(2,0,0x3a);
LCD_Write_Char(1,0,'0' + hour%10);
LCD_Write_Char(0,0,'0' + hour/10);
dat[2] = hour;
LCD_Write_Char(0,1,'a');
LCD_Write_Char(1,1,'l');
LCD_Write_Char(2,1,'a');
LCD_Write_Char(3,1,'r');
LCD_Write_Char(4,1,'m');
LCD_Write_Char(5,1,0x3a);
LCD_Write_Char(6,1,'0' + second%10);
LCD_Write_Char(7,1,'0' + second/10);
LCD_Write_Char(8,1,0x3a);
LCD_Write_Char(9,1,'0' + minute%10);
LCD_Write_Char(10,1,'0' + minute/10);
LCD_Write_Char(11,1,0x3a);
LCD_Write_Char(12,1,'0' + hours%10);
LCD_Write_Char(13,1,'0' + hours/10);
ISendStr(0xae,80,dat,16);
}
}
可调闹钟lcd时钟
最新推荐文章于 2021-09-13 17:23:03 发布