#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
sbit SPK=P3^0;
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
uchar Display_Buffer[16]=" ";
uchar Count,hour=12,min=12,sec=12;
bit flag,H_or_M;
uchar display[]="This is colck";
void _delay_ms(uint x)
{
uchar i;
while(x--)
{
for(i=0;i<120;i++);
}
}
/**********************************************************************
*函數名稱:LCD_Write_Command
*輸 入:uchar cmd
*輸 出:無
*功 能:向LCD1602寫指令
**********************************************************************/
void LCD_Write_Command(uchar cmd)
{
LCD_RS=0;//根據規定,RS和R/W同時為低電平時,可以寫入指令
LCD_RW=0;
LCD_EN=0;//EN置低電平
P0=cmd;//將數據送入P2口,即寫入指令或地址
LCD_EN=1;//EN置高電平
_delay_ms(1);//稍延時,給硬件反應時間
LCD_EN=0;//當EN由高電平跳變成低電平時,液晶模塊開始執行命令
}
/**********************************************************************
*函數名稱:LCD_Write_Data
*輸 入:uchar dat
*輸 出:無
*功 能:向LCD1602寫數據
**********************************************************************/
void LCD_Write_Data(uchar dat)
{
LCD_RS=1;//RS為高電平,RW為低電平時,可以寫入數據
LCD_RW=0;
LCD_EN=0;//EN置低電平
P0=dat;//將數據送入P0口,即將數據寫入液晶模塊
LCD_EN=1;//EN置高電平
_delay_ms(1);//稍延時,給硬件反應時間
LCD_EN=0;//當EN由高電平跳變成低電平時,液晶模塊開始執行命令
}
/**********************************************************************
*函數名稱:Init_LCD
*輸 入:無
*輸 出:無
*功 能:初始化LCD1602
**********************************************************************/
void Init_LCD(void)
{
LCD_Write_Command(0x38);//顯示模式設置:16×2顯示,5×7點陣,8位數據接口
_delay_ms(1);
LCD_Write_Command(0x06);//顯示模式設置:光標右移,字符不移
_delay_ms(1);
LCD_Write_Command(0x0c);//顯示模式設置:顯示開,無光標,光標不閃爍
_delay_ms(1);
LCD_Write_Command(0x01);//清屏幕指令,將以前的顯示內容清除
_delay_ms(1);
}
/**********************************************************************
*函數名稱:LCD_POS
*輸 入:uchar pos
*輸 出:無
*功 能:字符顯示位置
**********************************************************************/
void LCD_POS(uchar pos)
{
LCD_Write_Command(0x80|pos);//顯示位置的確定方法規定為"80H+地址碼x"
}
/**********************************************************************
*函數名稱:Show_String
*輸 入:uchar *str
*輸 出:無
*功 能:LCD1602顯示字符串處理函數
**********************************************************************/
void Show_String(uchar *str)
{
while(*str!='\0')//只要沒有寫到結束標誌,就繼續寫
LCD_Write_Data(*str++);//將字符常量寫入LCD,並指向下壹個字符
}
void song(void)
{
uchar i,j,k;
for(i=0;i<200;i++)
{
SPK=~SPK;
for(k=0;k<50;k++);
for(j=0;j<50;j++);
}
}
/////lcd1602液晶顯示//////
void Display_Time(uchar Hour,uchar Min,uchar Sec)
{
Display_Buffer[0]=Hour/10+'0';//小時十位
Display_Buffer[1]=Hour%10+'0';//小時個位
Display_Buffer[2]=':';//顯示:號
Display_Buffer[3]=Min/10+'0';//顯示分鐘十位
Display_Buffer[4]=Min%10+'0';//顯示分鐘個位
Display_Buffer[5]=':';//顯示:號
Display_Buffer[6]=Sec/10+'0';//顯示秒十位
Display_Buffer[7]=Sec%10+'0';//顯示秒個位
LCD_POS(0x40);//顯示在液晶第1行第0列
Show_String(Display_Buffer);
}
/////按鍵處理//////
void Set_time(void)
{
flag=0;
if(key1==0||key2==0||key3==0)//若key1,key2,key3其中有鍵按下,則為真
{
TR0=0;//定時器0停止
flag=1;//按鍵標誌位為真
}
while(flag)//判斷那壹個按鍵按下
{
if(key1==0)//判斷key1是否按下
{
while(!key1);//等待釋放
H_or_M=!H_or_M;//選擇是修改時還是分鐘
}
else if(key2==0)//判斷key2是否被按下
{
while(!key2);//等待釋放
if(H_or_M)//若H_OR_M為真,則修改小時
{
if(++hour==24)//若小時=24,則小時=0
hour=0;//小時加1
}
else//否則修改分鐘
{
if(++min==60)//若分鐘等於60,則分鐘等於0
min=0;//分鐘加1
}
}
else if(key3==0)//判斷key3是否被按下
{
while(!key3);//等待釋放
if(H_or_M)//若H_OR_M為真,則修改小時
{
if(--hour==0xff) //小時減1,若小時等於-1,則小時等於23
hour=23;
}
else//否則修改分鐘
{
if(--min==0xff)//分鐘減1,若分鐘等於-1,則分鐘等於59
min=59;
}
}
else if(key4==0)//判斷key4是否被按下
{
while(!key4);//等待釋放
flag=0;//按鍵標誌清零
TR0=1;//定時器0啟動
}
Display_Time(hour,min,sec);//傳H,M,S值顯示到液晶
}
}
void timer0_init(void)//定時器0初始化
{
TMOD=0x01;//定時器0,方式1
ET0=1;//
EA=1;//總中斷允許
TR0=1;//啟動定時器0
TH0=(65535-50000)/256;//裝高8位初值
TL0=(65535-50000)%256;//裝低8位初值
}
void main(void)//主函數
{
//P0=0xff;
P1=0xff;//端口初始化
P3=0xff;
Init_LCD();//液晶初始化
timer0_init();//定時器0初始化
LCD_POS(0);//顯示在液晶第1行第0列
Show_String(display);
while(1)//無限循環
{
Display_Time(hour,min,sec);//液晶顯示時間
//_delay_ms(500);//延時
Set_time();//時間調整
}
}
void timer0() interrupt 1//定時器0中斷
{
TH0=(65535-50000)/256;//重裝定時器0高8位
TL0=(65535-50000)%256;//重裝定時器0低8位
Count++;//計數加1
if(Count==20)//如果COUNT等於20
{
Count=0;//計數清零
sec++;//秒加1
if(sec==60)//判斷秒是否等於60
{
sec=0;//秒清零
min++;//分鐘加1
if(min==60)//判斷分鐘是否等於60
{
min=0;//若等於60,則清零分鐘
hour++;//小時加1
if(hour==24)//判斷小時是否等於24
{
hour=0;//若小時等於24,則清零小時,分鐘,秒
min=0;
sec=0;
}
song();
}
}
}
}