顶层文件 万年历.C #include<reg51.h>#include "LCD1602.h" #include "DS1302.h" #define uchar unsigned char #define uint unsigned int sbit speaker=P2^4bit key_flag1=0,key_flag2=0SYSTEMTIME adjusteduchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0uchar data_alarm[7]={0}/************键盘控制******************************/ int key_scan() //扫描是否有键按下 { int i=0uint tempP1=0xf0temp=P1if(temp!=0xf0) i=1else i=0return i} uchar key_value() //确定按键的值 { uint m=0,n=0,tempuchar valueuchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} P1=0xfetemp=P1if(temp!=0xfe)m=0P1=0xfdtemp=P1 if(temp!=0xfd)m=1P1=0xfbtemp=P1 if(temp!=0xfb)m=2P1=0xf7temp=P1 if(temp!=0xf7)m=3P1=0xeftemp=P1 if(temp!=0xef)n=0P1=0xdftemp=P1 if(temp!=0xdf)n=1P1=0xbftemp=P1 if(temp!=0xbf)n=2value=v[m][n]return value} /***************************设置闹铃
函数*******************************/ void naoling(void) { uchar i=0,l=0,jinit1602()while(key_flag2&&i<12) if(key_scan()){j=key_value()write_data(j)if(i%2==0)data_alarm[l]=(j-'0')*10else {data_alarm[l]+=(j-'0')l++}i++delay(600)} write_com(0x01)} uchar according(void) { uchar kif(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second) k=1else k=0return k} void speak(void) {uint i=50while(i) {speaker=0delay(1)speaker=1delay(1)i--} } void alarm(void) {uint i=10while(i) { speak()delay(10)i--} } /**************************修改时间 *** 作********************************/ void reset(void) { sec_add=0min_add=0hou_add=0day_add=0mon_add=0yea_add=0 } void adjust(void) { if(key_scan()&&key_flag1) switch(key_value()) {case '0':sec_add++breakcase '1':min_add++breakcase '2':hou_add++breakcase '3':day_add++breakcase '4':mon_add++breakcase '5':yea_add++breakcase 'b':reset()breakdefault: break} adjusted.Second+=sec_addadjusted.Minute+=min_addadjusted.Hour+=hou_addadjusted.Day+=day_addadjusted.Month+=mon_addadjusted.Year+=yea_addif(adjusted.Second>59) adjusted.Second=adjusted.Second%60if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24if(adjusted.Day>31) adjusted.Day=adjusted.Day%31if(adjusted.Month>12) adjusted.Month=adjusted.Month%12if(adjusted.Year>100) adjusted.Year=adjusted.Year%100} /**************************中断处理函数*********************************/ void changing(void) interrupt 0 using 0 //需要修改时间和日期,或者停止修改 { if(key_flag1)key_flag1=0else key_flag1=1} void alarming(void) interrupt 3 using 0 //需要设置闹铃或者停止设置 { if(key_flag2)key_flag2=0else key_flag2=1} /********************************主函数***********************************/ main() {uint iuchar *luchar p1[]="D:",p2[]="T:"SYSTEMTIME TEA=1EX0=1IT0=1EA=1EX1=1IT1=1init1602()Initial_DS1302() while(1) { write_com(0x80)write_string(p1,2)write_com(0xc0)write_string(p2,2)DS1302_GetTime(&T) adjusted.Second=T.Secondadjusted.Minute=T.Minuteadjusted.Hour=T.Houradjusted.Week=T.Weekadjusted.Day=T.Dayadjusted.Month=T.Monthadjusted.Year=T.Yearfor(i=0i<9i++) { adjusted.DateString[i]=T.DateString[i]adjusted.TimeString[i]=T.TimeString[i]} adjust()if(key_flag2)naoling()if(according())alarm()DateToStr(&adjusted)TimeToStr(&adjusted)write_com(0x82)write_string(adjusted.DateString,8)write_com(0xc2)write_string(adjusted.TimeString,8)delay(10)} (二)头文件1 显示模块 LCD1602.H #ifndef LCD_CHAR_1602_2009_5_9 #define LCD_CHAR_1602_2009_5_9 #define uchar unsigned char #define uint unsigned int sbit lcdrs = P2^0sbit lcdrw = P2^1sbit lcden = P2^2void delay(uint z) // 延时 { uint x,yfor(x=zx>0x--) for(y=110y>0y--)} void write_com(uchar com) // 写入指令
数据到 lcd { lcdrw=0lcdrs=0P0=comdelay(5)lcden=1delay(5)lcden=0} void write_data(uchar date) // 写入字符显示数据到 lcd { lcdrw=0lcdrs=1P0=datedelay(5)lcden=1delay(5)lcden=0} void init1602() // 初始化设定 { lcdrw=0lcden=0write_com(0x3C)write_com(0x0c)write_com(0x06)write_com(0x01)write_com(0x80)} void write_string(uchar *pp,uint n) { int ifor(i=0i<ni++) write_data(pp[i])} #endif (三)头文件2
时钟模块 DS1302.H #ifndef _REAL_TIMER_DS1302_2009_5_20_ #define _REAL_TIMER_DS1302_2003_5_20_ sbit DS1302_CLK = P2^6//实时时钟时钟线引脚 sbit DS1302_IO = P2^7//实时时钟数据线引脚 sbit DS1302_RST = P2^5//实时时钟复位线引脚 sbit ACC0 = ACC^0sbit ACC7 = ACC^7typedef struct SYSTEM_TIME { unsigned char Secondunsigned char Minuteunsigned char Hourunsigned char Weekunsigned char Dayunsigned char Monthunsigned char Yearunsigned char DateString[9]//用这两个字符串来放置读取的时间 unsigned char TimeString[9]}SYSTEMTIME//定义的时间类型 #define AM(X) X #define PM(X) (X+12) // 转成24小时制 #define DS1302_SECOND 0x80 #define DS1302_MINUTE 0x82 #define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A #define DS1302_DAY 0x86 #define DS1302_MONTH 0x88 #define DS1302_YEAR 0x8C #define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏 /******内部指令**********/ void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) { unsigned char iACC = dfor(i=8i>0i--) { DS1302_IO = ACC0DS1302_CLK = 1DS1302_CLK = 0ACC = ACC >>1//因为在前面已经定义了ACC0 = ACC^0以便再次利用DS1302_IO = ACC0} } unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) { unsigned char ifor(i=8i>0i--) { ACC = ACC >>1ACC7 = DS1302_IODS1302_CLK = 1DS1302_CLK = 0} return(ACC)} /********************************/ void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据 { DS1302_RST = 0DS1302_CLK = 0DS1302_RST = 1DS1302InputByte(ucAddr)// 地址,命令 DS1302InputByte(ucDa)// 写1Byte数据 DS1302_CLK = 1DS1302_RST = 0} unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据 { unsigned char ucDataDS1302_RST = 0DS1302_CLK = 0DS1302_RST = 1DS1302InputByte(ucAddr|0x01)// 地址,命令 ucData = DS1302OutputByte()// 读1Byte数据 DS1302_CLK = 1DS1302_RST = 0return(ucData)} void DS1302_SetProtect(bit flag) //是否写保护 { if(flag) Write1302(0x8E,0x10)else Write1302(0x8E,0x00)} void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数 { DS1302_SetProtect(0)Write1302(Address, ((Value/10)<<4 | (Value%10)))//将十进制数转换为BCD码 } //在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式 void DS1302_GetTime(SYSTEMTIME *Time) { unsigned char ReadValueReadValue = Read1302(DS1302_SECOND)Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)//将BCD码转换为十进制数 ReadValue = Read1302(DS1302_MINUTE)Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_HOUR)Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_DAY)Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_WEEK)Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_MONTH)Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)ReadValue = Read1302(DS1302_YEAR)Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F)} unsigned char *DataToBCD(SYSTEMTIME *Time) { unsigned char D[8]D[0]=Time->Second/10<<4+Time->Second%10D[1]=Time->Minute/10<<4+Time->Minute%10D[2]=Time->Hour/10<<4+Time->Hour%10D[3]=Time->Day/10<<4+Time->Day%10D[4]=Time->Month/10<<4+Time->Month%10D[5]=Time->Week/10<<4+Time->Week%10D[6]=Time->Year/10<<4+Time->Year%10return D} void DateToStr(SYSTEMTIME *Time) { //将十进制数转换为液晶显示的ASCII值 Time->DateString[0] = Time->Year/10 + '0'Time->DateString[1] = Time->Year%10 + '0'Time->DateString[2] = '-'Time->DateString[3] = Time->Month/10 + '0'Time->DateString[4] = Time->Month%10 + '0'Time->DateString[5] = '-'Time->DateString[6] = Time->Day/10 + '0'Time->DateString[7] = Time->Day%10 + '0'Time->DateString[8] = '\0'} void TimeToStr(SYSTEMTIME *Time) { //将十进制数转换为液晶显示的ASCII值 Time->TimeString[0] = Time->Hour/10 + '0'Time->TimeString[1] = Time->Hour%10 + '0'Time->TimeString[2] = ':'Time->TimeString[3] = Time->Minute/10 + '0'Time->TimeString[4] = Time->Minute%10 + '0'Time->TimeString[5] = ':'Time->TimeString[6] = Time->Second/10 + '0'Time->TimeString[7] = Time->Second%10 + '0'Time->DateString[8] = '\0'} void Initial_DS1302(void) { unsigned char SecondSecond=Read1302(DS1302_SECOND)if(Second&0x80) //初始化时间 DS1302_SetTime(DS1302_SECOND,0)} void DS1302_TimeStop(bit flag) // 是否将时钟停止 { unsigned char DataData=Read1302(DS1302_SECOND)DS1302_SetProtect(0)if(flag) Write1302(DS1302_SECOND, Data|0x80)else Write1302(DS1302_SECOND, Data&0x7F)} #endifzftzbpujjj1134358763,jaiezwwysu6517560870,2012-2-15 11:08:28下面是一个用AT89S52做的LCD1602显示的电子钟,可以调时间!\x0d\x0a\x0d\x0a#include\x0d\x0a#define uchar unsigned char \x0d\x0a#define uint unsigned int\x0d\x0a\x0d\x0asbit rs= P2^0\x0d\x0asbit rw = P2^1\x0d\x0asbit ep = P2^2\x0d\x0asbit k1=P1^0//时,分选择键\x0d\x0asbit k2=P1^1//加\x0d\x0asbit k3=P1^2//减\x0d\x0achar i,j,shi,fen,miao\x0d\x0auchar num,count,con\x0d\x0a\x0d\x0a//uchar SJ[]={\x0d\x0a//0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,//年\x0d\x0a//0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11,//月\x0d\x0a//0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00//日\x0d\x0a//}\x0d\x0a\x0d\x0auchar code table1[]={'2','0','1','0','-','1','1','-','0','4',' ',' ','T','H','U'}\x0d\x0auchar code table2[]="00:00 00"\x0d\x0a//uchar code table3[]=" 15899576222"\x0d\x0a \x0d\x0avoid lcd_com(uchar com)\x0d\x0avoid jia()\x0d\x0avoid jian()\x0d\x0avoid keyscan()\x0d\x0avoid lcd_date(uchar date)\x0d\x0avoid lcd_init()\x0d\x0avoid lcd_sfm(uchar add,uchar date)\x0d\x0a\x0d\x0avoid delay(uint t)\x0d\x0a{\x0d\x0a uint i,j\x0d\x0a for(i=0i=12)\x0d\x0a{\x0d\x0a// lcd_sfm(1,"PM")\x0d\x0a}\x0d\x0aif(shi==24)\x0d\x0a{\x0d\x0a shi=0\x0d\x0a}\x0d\x0alcd_sfm(4,shi)\x0d\x0a }\x0d\x0a lcd_sfm(7,fen)\x0d\x0a }\x0d\x0a lcd_sfm(10,miao)\x0d\x0a } \x0d\x0a}#include <reg52.h>
#include<stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_FLAG
#define LCD1602_PORT P0
sbit lcd1602_rs=P2^0
sbit lcd1602_e=P2^2
sbit lcd1602_rw=P2^1
sbit lcd1602_busy=P0^7
sbit key_ch=P3^5
sbit key_add=P3^6
sbit key_minus=P3^7
uchar i,sec,min,h,date,month,flag
uint year
uchar *chgstr[7]={" ","sec","min","hour","date","min","year"}
uchar j,k,m,n,o,p
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71}
uchar timestr[10],datestr[10]
void init()
void delay(uint)
void time_display()
void date_display()
void control()
void time()
/*
************************************
* 函数名称:lcd1602_CheckBusy()
* 函数功能:状态查询
************************************
*/
void lcd1602_CheckBusy()
{
do
{
lcd1602_busy=1
lcd1602_rs=0
lcd1602_rw=1
lcd1602_e=0
lcd1602_e=1
}
while(lcd1602_busy)
}
/*
***************************************
* 函数名称: lcd1602_WriteCmd()
* 函数功能:写命令
* 入口参数:命令字
* 出口参数:无
***************************************
*/
void lcd1602_WriteCmd(const uchar cmd)
{
lcd1602_CheckBusy()
lcd1602_rs=0
lcd1602_rw=0
lcd1602_e=1
LCD1602_PORT=cmd
lcd1602_e=0
}
/*
*******************************************
* 函数名称:lcd1602_WriteData()
* 函数功能:写数据
* 入口参数:c--待写数据
* 出口参数:无
*********************************************
*/
void lcd1602_WriteData(const uchar c)
{
lcd1602_CheckBusy()
lcd1602_rs=1
lcd1602_rw=0
lcd1602_e=1
LCD1602_PORT=c
lcd1602_e=0
}
/*
***********************************************
* 函数名称:lcd1602_Init()
* 函数功能:初始化LCD
* 入口参数:无
* 出口参数:无
***********************************************
*/
void lcd1602_Init()
{
lcd1602_WriteCmd(0x38) //显示模式为8位2行5*7点阵
lcd1602_WriteCmd(0x0c) //display enable,flag enable,flash enable,
lcd1602_WriteCmd(0x06) //flag move to right,screen don't move
lcd1602_WriteCmd(0x01) //clear screen
}
/*
************************************************
* 函数名称:lcd1602_Display()
* 函数功能: 字符显示
* 入口参数:ptr--字符或字符串指针
* 出口参数:无
* 说 明:用户可通过以下方式来调用:
* 1)lcd1602_Display("Hello,world!")
* 2) INT8U 存储类型 txt[]="要显示的字符串"
* 或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'}
* INT8U *ptr
* ptr=&txt
* lcd1602_Display(ptr)
* 或 lcd1602_Display(txt)
* 或 lcd1602_Display(&txt)
************************************************
*/
void lcd1602_Display(const uchar *ptr,uchar line,uchar xaddr)
{
uchar data i=0
uchar *data q
q=ptr
switch(line)
{
case 0:
lcd1602_WriteCmd(0x80+xaddr)
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q)
q++
i++
}
break
case 1:
lcd1602_WriteCmd(0xc0+xaddr)
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q)
q++
i++
}
break
}
}
void main()
{
lcd1602_Init()
init()
while(1)
{
time_display()
date_display()
control()
}
}
void init()
{
i=0
sec=0
min=30
h=7
date=17
month=10
year=2017
flag=0
EA=1
ET0=1
TMOD=0x01
TH0=(65536-50000)/256
TL0=(65536-50000)%256
TR0=1
}
void delay(uint z)
{
uint x,y
for(x=zx>0x--)
for(y=110y>0y--)
}
void time_display()
{
timestr[7]=0x30+sec%10
timestr[6]=0x30+sec/10
timestr[5]=':'
timestr[4]=0x30+min%10
timestr[3]=0x30+min/10
timestr[2]=':'
timestr[1]=0x30+h%10
timestr[0]=0x30+h/10
timestr[8]=0
lcd1602_Display(timestr,1,3)
}
void date_display()
{
datestr[9]=0x30+date%10
datestr[8]=0x30+date/10
datestr[7]=':'
datestr[6]=0x30+month%10
datestr[5]=0x30+month/10
datestr[4]=':'
datestr[3]=0x30+year%10
datestr[2]=0x30+year/10%10
datestr[1]=0x30+year/100%10
datestr[0]=0x30+year/1000
lcd1602_Display(datestr,0,2)
}
void control()
{
if(!key_ch)
{
delay(5)
if(!key_ch)
{
flag++
TR0=0
if(flag==7)
{flag=0TR0=1lcd1602_Init()}
lcd1602_Display(chgstr[flag],1,12)
}
}
while(!key_ch)
if(flag==1&&key_add==0)
{
while(!key_add)
sec++
if(sec==60)
sec=0
}
if(flag==1&&key_minus==0)
{
while(!key_minus)
sec--
if(sec==-1)
sec=59
}
if(flag==2&&key_add==0)
{
while(!key_add)
min++
if(min==60)
min=0
}
if(flag==2&&key_minus==0)
{
while(!key_minus)
min--
if(min==-1)
min=59
}
if(flag==3&&key_add==0)
{
while(!key_add)
h++
if(h==24)
h=0
}
if(flag==3&&key_minus==0)
{
while(!key_minus)
h--
if(h==-1)
h=23
}
if(flag==4&&key_add==0)
{
while(!key_add)
date++
if(date==29)
if((year%4!=0)&&(month==2))
date=1
if(date==30)
if((year%4==0)&&(month==2))
date=1
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
date=1
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
date=1
}
if(flag==4&&key_minus==0)
{
while(!key_minus)
if(date>1)date--
}
if(flag==5&&key_add==0)
{
while(!key_add)
month++
if(month==13)
month=1
}
if(flag==5&&key_minus==0)
{
while(!key_minus)
month--
if(month==0)
month=12
}
if(flag==6&&key_add==0)
{
while(!key_add)
year++
if(year==99)
year=1
}
if(flag==6&&key_minus==0)
{
while(!key_minus)
year--
if(year==0)
year=99
}
}
void T0_rpt() interrupt 1
{
TH0=(65536-50000)/256
TL0=(65536-50000)%256
i++
time()
}
void time()
{
if(i==20)
{
i=0
sec++
if(sec==60)
{
sec=0
min++
if(min==60)
{
min=0
h++
if(h==24)
{
h=0
min=0
sec=0
date++
if(date==29)
if((year%4!=0)&&(month==2))
{
date=1
month++
if(month==13)
{
month=1
year++
}
}
if(date==30)
if((year%4==0)&&(month==2))
{
date=1
month++
if(month==13)
{
month=1
year++
}
}
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
{
date=1
month++
if(month==13)
{
month=1
year++
}
}
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
{
date=1
month++
if(month==13)
{
month=1
year++
}
}
}
}
}
}
}
评论列表(0条)