跪求:液晶LCD1602显示时钟的C程序!

跪求:液晶LCD1602显示时钟的C程序!,第1张

顶层文件 万年历.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

/*电子时钟源代码*/

#include<graphics.h>

#include<stdio.h>

#include<math.h>

#include<dos.h>

#define PI 3.1415926 /*定义常量*/

#define UP 0x4800 /*上移↑键:修改时间*/

#define DOWN 0x5000 /*下移↓键指歼:修改时间*/

#define ESC 0x11b /*ESC键 : 退出系统*/

#define TAB 0xf09 /*TAB键 : 移动光标*/

/*函数声明*/

int keyhandle(int,int)/*键盘按键判断,并调用相关函数唯纤冲处理*/

int timeupchange(int) /*处理上移按键*/

int timedownchange(int)/*处理下移按键*/

int digithour(double)/*将double型的小时数转换成int型*/

int digitmin(double) /*将double型的分钟数转换成int型*/

int digitsec(double) /*将double型的秒钟数转换成int型*/

void digitclock(int,int,int )/*在指定位置显示时钟或分钟或秒钟数*/

void drawcursor(int)/*绘制一个光标*/

void clearcursor(int)/*消除前一个光标*/

void clockhandle()/*时钟处理*/

double h,m,s/*全局变量:小时,分,秒*/

double x,x1,x2,y,y1,y2/*全局变量:坐标值*/

struct time t[1]/*定义一个time结构类型的数组*/

main()

{

int driver, mode=0,i,j

driver=DETECT/*自动检测显示设备*/

initgraph(&driver, &mode, "")/*初始化图形系统*/

setlinestyle(0,0,3)/*设置当前画线宽度和类型:设置三点宽实线*/

setbkcolor(0)/*用调色板设置当前背景颜色*/

setcolor(9)/*设置当前画线颜色*/

line(82,430,558,430)

line(70,62,70,418)

line(82,50,558,50)

line(570,62,570,418)

line(70,62,570,62)

line(76,56,297,56)

line(340,56,564,56) /*画主体框架的边直线*/

/*arc(int x, int y, int stangle, int endangle, int radius)*/

arc(82,62,90,180,12)

arc(558,62,0,90,12)

setlinestyle(0,0,3)

arc(82,418,180,279,12)

setlinestyle(0,0,3)

arc(558,418,270,360,12) /*画主体框架的边角弧线*/

setcolor(15)

outtextxy(300,53,"CLOCK")/*显示标题*/

setcolor(7)

rectangle(342,72,560,360)/*画一个矩形,作为时钟的框架*/

setwritemode(0)/*规定画线的方式。mode=0, 则表示画线时将所画位置的原来信息覆盖*/

setcolor(15)

outtextxy(433,75,"CLOCK")/*时钟的标题*/

setcolor(7)

line(392,310,510,310)

line(392,330,510,330)

arc(392,320,90,270,10)

arc(510,320,270,90,10)/*绘制电竖神子动画时钟下的数字时钟的边框架*/

/*绘制数字时钟的时分秒的分隔符*/

setcolor(5)

for(i=431i<=470i+=39)

for(j=317j<=324j+=7){

setlinestyle(0,0,3)

circle(i,j,1)/*以(i, y)为圆心,1为半径画圆*/

}

setcolor(15)

line(424,315,424,325)/*在运行电子时钟前先画一个光标*/

/*绘制表示小时的圆点*/

for(i=0,m=0,h=0i<=11i++,h++){

x=100*sin((h*60+m)/360*PI)+451

y=200-100*cos((h*60+m)/360*PI)

setlinestyle(0,0,3)

circle(x,y,1)

}

/*绘制表示分钟或秒钟的圆点*/

for(i=0,m=0i<=59m++,i++){

x=100*sin(m/30*PI)+451

y=200-100*cos(m/30*PI)

setlinestyle(0,0,1)

circle(x,y,1)

}

/*在电子表的左边打印帮助提示信息*/

setcolor(4)

outtextxy(184,125,"HELP")

setcolor(15)

outtextxy(182,125,"HELP")

setcolor(5)

outtextxy(140,185,"TAB : Cursor move")

outtextxy(140,225,"UP : Time ++")

outtextxy(140,265,"DOWN: Time --")

outtextxy(140,305,"ESC : Quit system!")

outtextxy(140,345,"Version : 2.0")

setcolor(12)

outtextxy(150,400,"Nothing is more important than time!")

clockhandle()/*开始调用时钟处理程序*/

closegraph()/*关闭图形系统*/

return 0/*表示程序正常结束,向 *** 作系统返回一个0值*/

}

void clockhandle()

{

int k=0,count

setcolor(15)

gettime(t)/*取得系统时间,保存在time结构类型的数组变量中*/

h=t[0].ti_hour

m=t[0].ti_min

x=50*sin((h*60+m)/360*PI)+451/*时针的x坐标值*/

y=200-50*cos((h*60+m)/360*PI)/*时针的y坐标值*/

line(451,200,x,y)/*在电子表中绘制时针*/

x1=80*sin(m/30*PI)+451/*分针的x坐标值*/

y1=200-80*cos(m/30*PI)/*分针的y坐标值*/

line(451,200,x1,y1)/*在电子表中绘制分针*/

digitclock(408,318,digithour(h))/*在数字时钟中,显示当前的小时值*/

digitclock(446,318,digitmin(m))/*在数字时钟中,显示当前的分钟值*/

setwritemode(1)

/*规定画线的方式,如果mode=1,则表示画线时用现在特性的线

与所画之处原有的线进行异或(XOR) *** 作,实际上画出的线是原有线与现在规定

的线进行异或后的结果。因此, 当线的特性不变, 进行两次画线 *** 作相当于没有

画线,即在当前位置处清除了原来的画线*/

for(count=2k!=ESC){ /*开始循环,直至用户按下ESC键结束循环*/

setcolor(12)/*淡红色*/

sound(500)/*以指定频率打开PC扬声器,这里频率为500Hz*/

delay(700)/*发一个频率为500Hz的音调,维持700毫秒*/

sound(200)/*以指定频率打开PC扬声器,这里频率为200Hz*/

delay(300)

/*以上两种不同频率的音调,可仿真钟表转动时的嘀哒声*/

nosound()/*关闭PC扬声器*/

s=t[0].ti_sec

m=t[0].ti_min

h=t[0].ti_hour

x2=98*sin(s/30*PI)+451/*秒针的x坐标值*/

y2=200-98*cos(s/30*PI)/*秒针的y坐标值*/

line(451,200,x2,y2)

/*绘制秒针*/

/*利用此循环,延时一秒*/

while(t[0].ti_sec==s&&t[0].ti_min==m&&t[0].ti_hour==h)

{ gettime(t)/*取得系统时间*/

if(bioskey(1)!=0){

k=bioskey(0)

count=keyhandle(k,count)

if(count==5) count=1

}

}

setcolor(15)

digitclock(485,318,digitsec(s)+1)/*数字时钟增加1秒*/

setcolor(12)/*淡红色*/

x2=98*sin(s/30*PI)+451

y2=200-98*cos(s/30*PI)

line(451,200,x2,y2)

/*用原来的颜色在原来位置处再绘制秒针,以达到清除当前秒针的目的*/

/*分钟处理*/

if(t[0].ti_min!=m){ /*若分钟有变化*/

/*消除当前分针*/

setcolor(15)/*白色*/

x1=80*sin(m/30*PI)+451

y1=200-80*cos(m/30*PI)

line(451,200,x1,y1)

/*绘制新的分针*/

m=t[0].ti_min

digitclock(446,318,digitmin(m))/*在数字时钟中显示新的分钟值*/

x1=80*sin(m/30*PI)+451

y1=200-80*cos(m/30*PI)

line(451,200,x1,y1)

}

/*小时处理*/

if((t[0].ti_hour*60+t[0].ti_min)!=(h*60+m)){ /*若小时数有变化*/

/*消除当前时针*/

setcolor(15)/*白色*/

x=50*sin((h*60+m)/360*PI)+451/*50:时钟的长度(单位:像素),451:圆心的x坐标值*/

y=200-50*cos((h*60+m)/360*PI)

line(451,200,x,y)

/*绘制新的时针*/

h=t[0].ti_hour

digitclock(408,318,digithour(h))

x=50*sin((h*60+m)/360*PI)+451

y=200-50*cos((h*60+m)/360*PI)

line(451,200,x,y)

}

}

}

int keyhandle(int key,int count) /*键盘控制 */

{ switch(key)

{case UP: timeupchange(count-1)/*因为count的初始值为2,所以此处减1*/

break

case DOWN:timedownchange(count-1)/*因为count的初始值为2,所以此处减1*/

break

case TAB:setcolor(15)

clearcursor(count)/*清除原来的光标*/

drawcursor(count) /*显示一个新的光标*/

count++

break

}

return count

}

int timeupchange(int count) /*处理光标上移的按键*/

{

if(count==1){

t[0].ti_hour++

if(t[0].ti_hour==24) t[0].ti_hour=0

settime(t)/*设置新的系统时间*/

}

if(count==2){

t[0].ti_min++

if(t[0].ti_min==60) t[0].ti_min=0

settime(t)/*设置新的系统时间*/

}

if(count==3){

t[0].ti_sec++

if(t[0].ti_sec==60) t[0].ti_sec=0

settime(t)/*设置新的系统时间*/

}

}

int timedownchange(int count) /*处理光标下移的按键*/

{

if(count==1) {

t[0].ti_hour--

if(t[0].ti_hour==0) t[0].ti_hour=23

settime(t)/*设置新的系统时间*/

}

if(count==2) {

t[0].ti_min--

if(t[0].ti_min==0) t[0].ti_min=59

settime(t)/*设置新的系统时间*/

}

if(count==3) {

t[0].ti_sec--

if(t[0].ti_sec==0) t[0].ti_sec=59

settime(t)/*设置新的系统时间*/

}

}

int digithour(double h)/*将double型的小时数转换成int型*/

{int i

for(i=0i<=23i++)

}

int digitmin(double m)/*将double型的分钟数转换成int型*/

{int i

for(i=0i<=59i++)

}

int digitsec(double s) /*将double型的秒钟数转换成int型*/

{int i

for(i=0i<=59i++)

}

void digitclock(int x,int y,int clock)/*在指定位置显示数字时钟:时\分\秒*/

{char buffer1[10]

setfillstyle(0,2)

bar(x,y,x+15,328)

if(clock==60) clock=0

sprintf(buffer1,"%d",clock)

outtextxy(x,y,buffer1)

}

void drawcursor(int count)/*根据count的值,画一个光标*/

{switch(count)

{

case 1:line(424,315,424,325)break

case 2:line(465,315,465,325)break

case 3:line(505,315,505,325)break

}

}

void clearcursor(int count)/*根据count的值,清除前一个光标*/

{switch(count)

{

case 2:line(424,315,424,325)break

case 3:line(465,315,465,325)break

case 1:line(505,315,505,325)break

}

}

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

uchar a,miao,shi,fen,ri,yue,nian,week,flag,key1n,temp

#define yh 0x80

#define er 0x80+0x40//液晶屏的与 C51 之间的引脚连接定义

sbit rs=P2^5

sbit en=P2^7

sbit rw=P2^6//如果硬件上 rw 接地,就不用写这句和后面的 rw=0

//DS1302 时钟芯片与 C51 之间的引脚连接定义

sbit IO=P3^6

sbit SCLK=P3^5

sbit RST=P3^7

sbit ACC0=ACC^0

sbit ACC7=ACC^7//校时按键与 C51 的引脚连接定义

sbit key1=P3^2//设置键

sbit key2=P3^3//加键

sbit key3=P3^4//减键

uchar code tab1[]={"20//////////"}//年显示的固定字符

uchar code tab2[]={"LOVE ::::::"}//时间显示的固定字符

//延时函数,后面经常调用

void delay(uint xms)//延时函数,有参函数

{

uint x,y

for(x=xmsx>0x--)

for(y=110y>0y--)

}

/********液晶写入慧伏指令函数与写入数据函数,以后可调用**************/

write_1602com(uchar com) //****液晶写入指令函数****

{

rs=0 //数据/指令选择置为指令

rw=0 //读写选择 置为写

P0=com //送入数据

delay(1)

en=1 //拉高使能端,为制造有效的下降沿做准备

delay(1)

en=0

//en 由高变低,产生下降沿,液晶执行命令

}

write_1602dat(uchar dat) //***液晶写入数据函数****

{

rs=1 //数据/指令选择置为数据

rw=0 //读写选择置为写

P0=dat //送入数据

delay(1)

en=1 //en 置高电平,为制造下降纳胡沿做准备

delay(1)

en=0 //en 由高变低,产生下降沿,液晶执行命令

}

lcd_init() //***液晶初始化函数****//

{

write_1602com(0x38) //设置液晶工作模式,意思:16*2 行显示,5*7 点阵,8 位数据

write_1602com(0x0c) //开显示不显示光标

write_1602com(0x06) //整屏不移动,光标自动右移

write_1602com(0x01) //清显示

write_1602com(yh+1) //日历显示固定符号从第一行第 1 个位置之后开始显示

for(a=0a<14a++)

{

write_1602dat(tab1[a])//向液晶屏写日历显示的固定符号部分

}

write_1602com(er+1)//时间显示固定符号写入位置,从第 2 个位置后开始显示

for(a=0a<12a++)

{

write_1602dat(tab2[a])//写显前茄携示时间固定符号,两个冒号

}

}

/***************DS1302 有关子函数********************/

void write_byte(uchar dat)//写一个字节

{

ACC=dat

RST=1

for(a=8a>0a--)

{

IO=ACC0//相当于汇编中的 RRC

SCLK=0

SCLK=1

ACC=ACC>>1

}

}

uchar read_byte() //读一个字节

{

RST=1

for(a=8a>0a--)

{

ACC7=IO

SCLK=1

SCLK=0

ACC=ACC>>1

}

return (ACC)

}

//----------------------------------------//

void write_1302(uchar add,uchar dat) //向 1302 芯片写函数,指定写入地址,数据

{

RST=0

SCLK=0

RST=1

write_byte(add)

write_byte(dat)

SCLK=1

RST=0

}

uchar read_1302(uchar add) //从 1302 读数据函数,指定读取数据来源地址

{

uchar temp

RST=0

SCLK=0

RST=1

write_byte(add)

temp=read_byte()

SCLK=1

RST=0

return(temp)

}

uchar BCD_Decimal(uchar bcd)//BCD 码转十进制函数,输入 BCD,返回十进制

{

uchar Decimal

Decimal=bcd>>4

return(Decimal=Decimal*10+(bcd&=0x0F))

}

//--------------------------------------//

void ds1302_init()//1302 芯片初始化子函数(2010-01-07,12:00:00,week4)

{

RST=0

SCLK=0

write_1302(0x8e,0x00)//允许写,禁止写保护

write_1302(0x8e,0x80)//打开写保护

}

//时分秒显示子函数

void write_sfm(uchar add,uchar dat)//向 LCD 写时分秒,有显示位置加、现示数据,两个参数

{

uchar gw,sw

gw=dat%10//取得个位数字

sw=dat/10//取得十位数字

write_1602com(er+add)//er 是头文件规定的值 0x80+0x40

write_1602dat(0x30+sw)//数字+30 得到该数字的 LCD1602 显示码

write_1602dat(0x30+gw)//数字+30 得到该数字的 LCD1602 显示码

}

//年月日显示子函数

void write_nyr(uchar add,uchar dat)//向 LCD 写年月日,有显示位置加数、显示数据,两个参数

{

uchar gw,sw

gw=dat%10//取得个位数字

sw=dat/10//取得十位数字

write_1602com(yh+add)//设定显示位置为第一个位置+add

write_1602dat(0x30+sw)//数字+30 得到该数字的 LCD1602 显示码

write_1602dat(0x30+gw)//数字+30 得到该数字的 LCD1602 显示码

}

void write_week(uchar week)//写星期函数

{

write_1602com(yh+0x0c)//星期字符的显示位置

switch(week)

{

case 1:write_1602dat('M')//星期数为一时,显示

write_1602dat('o')

write_1602dat('n')break

case 2:write_1602dat('T')//星期数据为二时显示

write_1602dat('u')

write_1602dat('e')break

case 3:write_1602dat('W')//星期数据为三时显示

write_1602dat('e')

write_1602dat('d')break

case 4:write_1602dat('T')//星期数据为四是显示

write_1602dat('h')

write_1602dat('u')break

case 5:write_1602dat('F')//星期数据为五时显示

write_1602dat('r')

write_1602dat('i')break

case 6:write_1602dat('S')//星期数据为六时显示

write_1602dat('t')

write_1602dat('a')break

case 7:write_1602dat('S')//星期数据为日时显示

write_1602dat('u')

write_1602dat('n')break

}

}

//****************键盘扫描有关函数**********************

void keyscan()

{

if(key1==0)//key1 为功能键(设置键)

{

delay(9)//延时,用于消抖动

if(key1==0)//延时后再次确认按键按下

{

delay(20)

while(!key1)

key1n++

if(key1n==9)

key1n=1//设置按键共有秒、分、时、星期、日、月、年、返回,8 个功能循环

switch(key1n)

{

case 1:TR0=0//关闭定时器

write_1602com(er+0x0E)//设置按键按动一次,秒位置显示光标

write_1602com(0x0f)//设置光标为闪烁

temp=(miao)/10*16+(miao)%10//秒数据写入 DS1302

write_1302(0x8e,0x00)

write_1302(0x80,0x80|temp)//miao

write_1302(0x8e,0x80)break

case 2:write_1602com(er+11)//按 2 次 fen 位置显示光标

break

case 3:write_1602com(er+8)//按动 3 次,shi

break

case 4:write_1602com(yh+0x0e)//按动 4 次,week

break

case 5:write_1602com(yh+0x0a)//按动 5 次,ri

break

case 6:write_1602com(yh+0x07)//按动 6 次,yue

break

case 7:write_1602com(yh+0x04)//按动 7 次,nian

break

case 8:write_1602com(0x0c)//按动到第 8 次,设置光标不闪烁

TR0=1//打开定时器

TR0=1

temp=(miao)/10*16+(miao)%10

write_1302(0x8e,0x00)

write_1302(0x80,0x00|temp)//miao 数据写入 DS1302

write_1302(0x8e,0x80)break

}

}

}

//------------------------------加键 key2----------------------------//

if(key1n!=0)//当 key1 按下以下。再按以下键才有效(按键次数不等于零)

{

if(key2==0)//上调键

{

delay(10)

if(key2==0)

{

delay(20)

while(!key2)

switch(key1n)

{

case 1:miao++//设置键按动 1 次,调秒

if(miao==60)

miao=0

write_sfm(0x0D,miao)

temp=(miao)/10*16+(miao)%10

write_1302(0x8e,0x00)

write_1302(0x80,temp)

write_1302(0x8e,0x80)

write_1602com(er+0x0E)

break

case 2:fen++

if(fen==60)

fen=0

write_sfm(0x0A,fen)

temp=(fen)/10*16+(fen)%10

write_1302(0x8e,0x00)

write_1302(0x82,temp)

write_1302(0x8e,0x80)

write_1602com(er+11)

break

case 3:shi++

if(shi==24)

shi=0

write_sfm(7,shi)

temp=(shi)/10*16+(shi)%10

write_1302(0x8e,0x00)

write_1302(0x84,temp)

write_1302(0x8e,0x80)

write_1602com(er+8)

break

case 4:week++

if(week==8)

week=1

write_1602com(yh+0x0C)

write_week(week)

temp=(week)/10*16+(week)%10

write_1302(0x8e,0x00)

write_1302(0x8a,temp)

write_1302(0x8e,0x80)

write_1602com(yh+0x0e)

break

case 5:ri++

if(ri==32)

ri=1

write_nyr(9,ri)

temp=(ri)/10*16+(ri)%10

write_1302(0x8e,0x00)

write_1302(0x86,temp)

write_1302(0x8e,0x80)

write_1602com(yh+10)

break

case 6:yue++

if(yue==13)

yue=1

write_nyr(6,yue)

temp=(yue)/10*16+(yue)%10

write_1302(0x8e,0x00)

write_1302(0x88,temp)

write_1302(0x8e,0x80)

write_1602com(yh+7)

break

case 7:nian++

if(nian==100)

nian=0

write_nyr(3,nian)

temp=(nian)/10*16+(nian)%10

write_1302(0x8e,0x00)

write_1302(0x8c,temp)

write_1302(0x8e,0x80)

write_1602com(yh+4)

break

}

}

}

//------------------减键 key3,各句功能参照'加键'注释---------------

if(key3==0)

{

delay(10)

//调延时,消抖动

if(key3==0)

{

delay(20)

while(!key3)

switch(key1n)

{

case 1:miao--

if(miao==-1)

miao=59

write_sfm(0x0D,miao)

temp=(miao)/10*16+(miao)%10

write_1302(0x8e,0x00)

write_1302(0x80,temp)

write_1302(0x8e,0x80)

write_1602com(er+0x0E)

break

case 2:fen--

if(fen==-1)

fen=59

write_sfm(10,fen)

temp=(fen)/10*16+(fen)%10

write_1302(0x8e,0x00)

write_1302(0x82,temp)

write_1302(0x8e,0x80)

write_1602com(er+11)

break

case 3:shi--

if(shi==-1)

shi=23

write_sfm(7,shi)

temp=(shi)/10*16+(shi)%10

write_1302(0x8e,0x00)

write_1302(0x84,temp)

write_1302(0x8e,0x80)

write_1602com(er+8)

break

case 4:week--

if(week==0)

week=7

write_1602com(yh+0x0C)

write_week(week)

temp=(week)/10*16+(week)%10

write_1302(0x8e,0x00)

write_1302(0x8a,temp)

write_1302(0x8e,0x80)

write_1602com(yh+0x0e)

break

case 5:ri--

if(ri==0)

ri=31

write_nyr(9,ri)

temp=(ri)/10*16+(ri)%10//十进制转换成 DS1302 要求的 DCB 码

write_1302(0x8e,0x00)//允许写,禁止写保护

write_1302(0x86,temp)//向 DS1302 内写日期寄存器 86H 写入调整后的日期数据 BCD 码

write_1302(0x8e,0x80)//打开写保护

write_1602com(yh+10)//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位

break

case 6:yue--

if(yue==0)

yue=12

write_nyr(6,yue)

temp=(yue)/10*16+(yue)%10 //十进制转换成 DS1302 要求的 DCB 码

write_1302(0x8e,0x00) //允许写,禁止写保护

write_1302(0x88,temp) //向 DS1302 内写月份寄存器 88H 写入调整后的月份数据 BCD 码

write_1302(0x8e,0x80) //打开写保护

write_1602com(yh+7) //因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位

break

case 7:nian--

if(nian==-1)

nian=99

write_nyr(3,nian)

temp=(nian)/10*16+(nian)%10 //十进制转换成 DS1302 要求的 DCB 码

write_1302(0x8e,0x00) //允许写,禁止写保护

write_1302(0x8c,temp) //向 DS1302 内写年份寄存器 8cH 写入调整后的年份数据 BCD 码

write_1302(0x8e,0x80) //打开写保护

write_1602com(yh+4) //因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位

break

}

}

}

}

}

void init()

//定时器、计数器设置函数

{

TMOD=0x11

//指定定时/计数器的工作方式为 3

TH0=0

//定时器 T0 的高四位=0

TL0=0

//定时器 T0 的低四位=0

EA=1

//系统允许有开放的中断

ET0=1

//允许 T0 中断

TR0=1

//开启中断,启动定时器

}

//*******************主函数**************************

void main()

{

lcd_init() //调用液晶屏初始化子函数

ds1302_init() //调用 DS1302 时钟的初始化子函数

init()//调用定时计数器的设置子函数

delay(80)

while(1)

//无限循环下面的语句:

{

keyscan()

//调用键盘扫描子函数

}

}

void timer0() interrupt 1//取得并显示日历和时间

{//读取秒时分周日月年七个数据(DS1302 的读寄存器与写寄存器不一样)

miao = BCD_Decimal(read_1302(0x81))

fen = BCD_Decimal(read_1302(0x83))

shi = BCD_Decimal(read_1302(0x85))

ri = BCD_Decimal(read_1302(0x87))

yue = BCD_Decimal(read_1302(0x89))

nian=BCD_Decimal(read_1302(0x8d))

week=BCD_Decimal(read_1302(0x8b))

//显示秒、时、分数据:

write_sfm(13,miao) //秒,从第二行第 8 个字后开始显示(调用时分秒显示子函数)

write_sfm(10,fen) //分,从第二行第 5 个字符后开始显示

write_sfm(7,shi) //小时,从第二行第 2 个字符后开始显示

//显示日、月、年数据:

write_nyr(9,ri) //日期,从第二行第 9 个字符后开始显示

write_nyr(6,yue) //月份,从第二行第 6 个字符后开始显示

write_nyr(3,nian) //年,从第二行第 3 个字符后开始显示

write_week(week)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12258774.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存