#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<intrins.h>
#include "i2c.h"
sbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;
sbit spk = P2^5;
bit KeyPressFlag;
#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
#define KeyPort P1
char dat[5] = 0;
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char flag;
unsigned char c_hour;
unsigned char c_min;
unsigned char Keyreturn();
void Init_INT0(void);
void clock_change();
/*------------------------------------------------
uS延时函数
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
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_time1() interrupt 1
{
unsigned char i;
ET0 = 0;
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
i++;
if(i == 20)
{
i = 0;
sec++;
}
ET0 = 1;
}
void time_add()
{
unsigned char KeyPro;
KeyPort = 0xf0;
if(sec == 60)
{
sec = 0;
min++;
flag = 0;
}
if(min == 60)
{
min = 0;
hour++;
}
if(hour == 24)
{
hour = 0;
//flag = 1;
}
if(KeyPressFlag == 1) //检测到有键按下后
{
KeyPressFlag = 0;
KeyPro = Keyreturn();
if(KeyPro == 0)
{
sec++;
}
if(KeyPro == 1)
{
min++;
}
if(KeyPro == 2)
{
hour++;
}
if(KeyPro == 3)
{
ET0 = ~ET0;
}
if(KeyPro == 4)
{
c_hour++;
if(c_hour == 24)
{
c_hour = 0;
}
}
if(KeyPro == 5)
{
c_min++;
if(c_min == 60)
{
c_min = 0;
}
}
}
}
/*------------------------------------------------
矩阵键盘
-------------------------------------------------*/
unsigned char Key()
{
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 Keyreturn()
{
switch(Key())
{
case 0x7e:return 0;break;//s1,调秒
case 0x7d:return 1;break;//s5,调分
case 0x7b:return 2;break;//s6,调时
case 0x77:return 3;break;//s7,暂停和开始
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;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;
}
}
/*------------------------------------------------
外部中断0初始化
------------------------------------------------*/
void Init_INT0(void)
{
EA=1; //全局中断开
EX0=1; //外部中断0开
IT0=1; //边沿触发
}
/*------------------------------------------------
外部中断0程序
------------------------------------------------*/
void ISR_INT0(void) interrupt 0
{
KeyPressFlag=1; //表明按键有动作,可以进行按键扫描
}
/*------------------------------------------------
主函数
------------------------------------------------ */
void main(void)
{
//ISendStr(0xae,80,dat,8);
Init_INT0();
IRcvStr(0xae,80,dat,8); //读出
sec = dat[0];
min = dat[1];
hour = dat[2];
c_hour = dat[3];
c_min = dat[4];
TMOD = 0x01;
TR0 = 1;
EA = 1;
TH0 = 0x3c;
TL0 = 0xb0;
ET0 = 1;
LCD_Init();
LCD_Clear();//清屏
DelayMs(5);
while (1)
{
time_add();
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_String(0,1,"Ring:");
LCD_Write_Char(7,1,'0' + c_hour/10);
LCD_Write_Char(8,1,'0' + c_hour%10);
dat[3] = c_hour;
LCD_Write_Char(9,1,0x3a);
LCD_Write_Char(10,1,'0' + c_min/10);
LCD_Write_Char(11,1,'0' + c_min%10);
dat[4] = c_min;
if(min == c_min && hour == c_hour )
{
spk = !spk;
}
ISendStr(0xae,80,dat,8); //每次的都写入
}
}
矩阵键盘可调时间,可调闹钟(LCD显示)
最新推荐文章于 2023-12-20 18:27:26 发布