矩阵键盘可调时间,可调闹钟(LCD显示)

来源:互联网 发布:淘宝网登陆界面异常 编辑:程序博客网 时间:2024/04/30 04:48
#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 P1char 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); //每次的都写入    }}

0 0