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

#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); //每次的都写入
    }
}

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个基于51单片机的LCD实现时间显示可调时间闹钟的C语言程序: ```c #include <reg51.h> #define LCD_Data_Port P2 #define LCD_Command_Port P3 sbit RS = P0^0; sbit RW = P0^1; sbit EN = P0^2; unsigned char second = 0; unsigned char minute = 0; unsigned char hour = 0; unsigned char alarm_hour = 0; unsigned char alarm_minute = 0; unsigned char alarm_flag = 0; void delay(unsigned int time) { unsigned int i, j; for(i = 0; i < time; i++) { for(j = 0; j < 1275; j++); } } void lcd_write_command(unsigned char command) { LCD_Data_Port = command; RS = 0; RW = 0; EN = 1; delay(1); EN = 0; } void lcd_write_data(unsigned char data) { LCD_Data_Port = data; RS = 1; RW = 0; EN = 1; delay(1); EN = 0; } void lcd_init() { lcd_write_command(0x38); // 8-bit data, 2-line display, 5x7 font lcd_write_command(0x0C); // Display on, cursor off, blink off lcd_write_command(0x01); // Clear display lcd_write_command(0x06); // Entry mode: increment, no shift lcd_write_command(0x80); // Set DDRAM address to 0 } void display_time() { lcd_write_command(0x80); // Set DDRAM address to 0 lcd_write_data(hour / 10 + '0'); lcd_write_data(hour % 10 + '0'); lcd_write_data(':'); lcd_write_data(minute / 10 + '0'); lcd_write_data(minute % 10 + '0'); lcd_write_data(':'); lcd_write_data(second / 10 + '0'); lcd_write_data(second % 10 + '0'); } void display_alarm() { lcd_write_command(0xC0); // Set DDRAM address to 40 lcd_write_data('A'); lcd_write_data('L'); lcd_write_data('A'); lcd_write_data('R'); lcd_write_data('M'); lcd_write_data(':'); lcd_write_data(alarm_hour / 10 + '0'); lcd_write_data(alarm_hour % 10 + '0'); lcd_write_data(':'); lcd_write_data(alarm_minute / 10 + '0'); lcd_write_data(alarm_minute % 10 + '0'); } void interrupt timer0_isr() interrupt 1 { TH0 = 0xFC; TL0 = 0x67; second++; if(second == 60) { second = 0; minute++; if(minute == 60) { minute = 0; hour++; if(hour == 24) { hour = 0; } } } } void main() { TMOD = 0x01; // Timer0 mode 1: 16-bit timer TH0 = 0xFC; // Initialize timer0 to generate interrupt every 500ms TL0 = 0x67; TR0 = 1; // Start timer0 ET0 = 1; // Enable timer0 interrupt EA = 1; // Enable global interrupt lcd_init(); while(1) { display_time(); if(alarm_flag == 1 && hour == alarm_hour && minute == alarm_minute) { lcd_init(); display_alarm(); while(1); // Wait for reset } if(P1_0 == 0) { // Increment hour delay(20); if(P1_0 == 0) { hour++; if(hour == 24) { hour = 0; } while(P1_0 == 0); } } if(P1_1 == 0) { // Increment minute delay(20); if(P1_1 == 0) { minute++; if(minute == 60) { minute = 0; } while(P1_1 == 0); } } if(P1_2 == 0) { // Set alarm delay(20); if(P1_2 == 0) { alarm_hour = hour; alarm_minute = minute; alarm_flag = 1; lcd_init(); display_alarm(); while(P1_2 == 0); } } } } ``` 该程序使用定时器0以1秒为单位跟踪时间,并且可以通过按下按钮来增加小时和分钟,以设置时间闹钟。如果闹钟时间到达,LCD显示“ALARM: HH:MM”,并且程序将停止,直到被重置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值