51单片机c语言知识电子万年历完整编辑程序

合集下载

51单片机12864万年历(图片+主要程序C语言)

51单片机12864万年历(图片+主要程序C语言)

51单片机做的12864万年历这是我花了一个星期时间做的万年历;一开始是一些图片,后面是这个制作的C语言源程序;希望大家稀饭:Main.c#include "reg52.h"#include "macroconst.h"#include "keyscan.h"#include "screen.h"#include "18b20.h"#include "ds1302.h"#include "atao_12864.h"#include "24c02.h"idata unsigned char state1[1];unsigned char screennum=1;//屏幕号#define time_task_sec 200 //节拍200Hz#define clock 24000000 //晶振#define max_task 4 //最大任务数idata unsigned char task_delay[4];#define task_delay0 time_task_sec/1 //2赫兹18b20 #define task_delay1 time_task_sec/5 //10赫兹屏幕#define task_delay2 time_task_sec/3 //4赫兹1302 #define task_delay3 time_task_sec/20 //20赫兹键盘void init(){unsigned char i;init18b20();ds1302_init();initina1(); //---------------------------LCD字库初始化程序RdFromROM(state1,8,1);state[0]=state1[0]; //-------界面RdFromROM(state1,15,1);state[1]=state1[0];//------- 闹钟RdFromROM(state1,11,1);key_sound=state1[0];//-------按键音// state[2]=state1[2];// state[3]=state1[3];screennum=1;//------默认一号屏for(i=0;i<max_task;i++)//清除任务延时{task_delay[i]=0;}TMOD=0x11;EA=1;TH0=255-clock/time_task_sec/12/526;TL0=255-clock/time_task_sec/12%526;ET0=1;TR0=1;}void main(){init();while(1){ if(task_delay[0]==0){readtemp(); task_delay[0]=task_delay0;} if(task_delay[3]==0){MenuCheckKey();task_delay[3]=task_delay1;}if(task_delay[1]==0){screen_select(screennum);task_delay[1]=task_delay1;} if(task_delay[2]==0){ds1302_read_time(); task_delay[2]=task_delay0;} }}void timer0() interrupt 1{uchar i=0;TH0=255-clock/time_task_sec/12/526;TH1=255-clock/time_task_sec/12%526;for(i=0;i<max_task;i++)if(task_delay[i]) task_delay[i]--; // miao=21,fen=33,xiaomiao=94;if(ma_start==1){tt++;if(tt==8){tt=0;xiaomiao++;if(xiaomiao==99){xiaomiao=0;miao++;if(miao==60){miao=0;fen++;if(fen==99){fen=0;}}}}}}Screen.c:#include "reg52.h"#include "macroconst.h"#include "delay.h"#include "18b20.h"#include "atao_12864.h"#include "ds1302.h"#include "24c02.h"#include "festival.h"#include "keyscan.h"idata unsigned char miao=0,fen=78,xiaomiao=0,tt=0;idata unsigned char bai,shi,ge,shinian,genian,shiyue,geyue,shiri,geri,shishi,geshi,shifen,gefen,shimi ao,gemiao;idata unsigned char Number[4];unsigned char code mainmenu[]={" 主菜单""3.查询 4.温度""1.调时 2.秒表""5.设置 6.返回"};unsigned char code setmenu[]={" 设置""3.查温 4.按键""1.界面 2.闹铃""5.报时 6.返回"};void gettime(){shinian=(time_buf1[1]%100)/10;genian=(time_buf1[1]%100)%10;shiyue=(time_buf1[2])/10;geyue=(time_buf1[2])%10;shiri=(time_buf1[3])/10;geri=(time_buf1[3])%10;shishi=(time_buf1[4])/10;geshi=(time_buf1[4])%10;shifen=(time_buf1[5])/10;gefen=(time_buf1[5])%10;shimiao=(time_buf1[6])/10;gemiao=(time_buf1[6])%10;}void screen_select(uchar num){// initina1();gettime() ;if(num==1) //----------主界面{Lcd_Set_Post(1,0);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);TransferData('/',1);TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);TransferData('/',1);TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);Lcd_Set_Post(1,4);if(state[1]==1)//----------------闹铃的状态图标{TransferData(' ',1);TransferData(14,1);}Lcd_Set_Post(1,5);if(key_sound==1){TransferData(13,1);}if(state[0]==0){Lcd_Set_Post(1,7); //----------------农历年nian(0);Lcd_Set_Post(2,0);//----------------------- 农历日月LCD_WRITE_CHAR("农历");Conversion(0,time_buf[1],time_buf[2],time_buf[3]);TransferData(month_moon/16+'0',1);TransferData(month_moon%16+'0',1);TransferData('/',1);TransferData(day_moon/16+'0',1);TransferData(day_moon%16+'0',1);}if(state[0]==1){Lcd_Set_Post(3,5);}else {Lcd_Set_Post(2,5);}LCD_WRITE_CHAR("星期");//----------------------星期if(time_buf1[7]==7) {LCD_WRITE_CHAR("日");}if(time_buf1[7]==6) {LCD_WRITE_CHAR("六");}if(time_buf1[7]==5) {LCD_WRITE_CHAR("五");}if(time_buf1[7]==4) {LCD_WRITE_CHAR("四");}if(time_buf1[7]==3) {LCD_WRITE_CHAR("三");}if(time_buf1[7]==2) {LCD_WRITE_CHAR("二");}if(time_buf1[7]==1) {LCD_WRITE_CHAR("一");}Lcd_Set_Post(3,0);TransferData(shishi+48,1);//----------------------时TransferData(geshi+48,1);TransferData(58,1);TransferData(shifen+48,1);//----------------------分TransferData(gefen+48,1);TransferData(58,1);TransferData(shimiao+48,1);//----------------------秒TransferData(gemiao+48,1);if(state[0]==0){bai=(temph/100); //---------------------------------温度shi=(temph%100)/10;ge=(temph%100)%10;Lcd_Set_Post(3,4);if(zerotemp==0){TransferData(' ',1);TransferData(' ',1);} Lcd_Set_Post(3,5);TransferData(shi+48,1);TransferData(ge+48,1);TransferData('.',1);TransferData(templ+48,1);TransferData(0xa1,1);TransferData(0xe6,1);Lcd_Set_Post(4,0);festival(time_buf[2],time_buf[3],time_buf[4]);//农历}}if(num==3)//----------主菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(mainmenu);}if(num==4)//----------设置菜单{Lcd_Set_Post(1,0);//--------设置显示位置LCD_WRITE_CHAR(setmenu);}if(num==5)//----------时间设置{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("时间设置");Lcd_Set_Post(2,1);TransferData(shinian+48,1);//----------------------年TransferData(genian+48,1);LCD_WRITE_CHAR("年");TransferData(shiyue+48,1);//----------------------月TransferData(geyue+48,1);LCD_WRITE_CHAR("月");TransferData(shiri+48,1);//----------------------日TransferData(geri+48,1);LCD_WRITE_CHAR("日");TransferData(time_buf1[7]+48,1);//---------------星期Lcd_Set_Post(3,2);TransferData(shishi+48,1);//--------------------时TransferData(geshi+48,1);LCD_WRITE_CHAR("时");TransferData(shifen+48,1);//---------------------分TransferData(gefen+48,1);LCD_WRITE_CHAR("分");TransferData(shimiao+48,1);//--------------------秒TransferData(gemiao+48,1);}if(num==6)//----------秒表{uchar shi1,shi2,shi3,ge1,ge2,ge3;Lcd_Set_Post(1,3);//--------设置显示位置LCD_WRITE_CHAR("秒表");Lcd_Set_Post(3,2);shi1=fen/10;ge1=fen%10;TransferData(shi1+48,1);TransferData(ge1+48,1);TransferData(':',1);shi2=miao/10;ge2=miao%10;TransferData(shi2+48,1);TransferData(ge2+48,1);TransferData(':',1);shi3=xiaomiao/10;ge3=xiaomiao%10;TransferData(shi3+48,1);TransferData(ge3+48,1);}if(num==8){Lcd_Set_Post(1,2);//--------农历查询LCD_WRITE_CHAR("温度查询");Lcd_Set_Post(3,0);//--------农历查询LCD_WRITE_CHAR("最高温度"); TransferData(':',1);RdFromROM(Number,0,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(3,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); Lcd_Set_Post(4,0);//--------农历查询LCD_WRITE_CHAR("最低温度"); TransferData(':',1);RdFromROM(Number,4,4);if(Number[3]==0){TransferData('-',1);}Lcd_Set_Post(4,5);TransferData(Number[0]+48,1); TransferData(Number[1]+48,1); TransferData('.',1);TransferData(Number[2]+48,1); TransferData(0xa1,1);TransferData(0xe6,1); }if(num==9)//----------界面菜单{Lcd_Set_Post(1,2);//--------设置显示位置LCD_WRITE_CHAR("界面选择");Lcd_Set_Post(2,0);TransferData(1+48,1);TransferData('.',1);LCD_WRITE_CHAR("多功能界面");Lcd_Set_Post(3,0);TransferData(2+48,1);TransferData('.',1);LCD_WRITE_CHAR("简洁界面");}。

单片机万年历C语言程序完整

单片机万年历C语言程序完整
sbit out = P2^3; //立刻跳出调整模式按钮
sbit DQ = P3^0;
char done,count,temp,flag,up_flag,down_flag,t_value;
uchar TempBuffer[5],week_value[2];
void show_time(); //液晶显示程序
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[11];
unsigned char TimeString[9];
}SYSTEMTIME;//定义的时间类型
#define AM(X)X
#define PM(X)(X+12)//转成24小时制
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); //地址,命令
ucData = DS1302OutputByte(); //读1Byte数据
DS1302_CLK = 1;
#define DS1302_SECOND0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE0x82
#define DS1302_HOUR0x84
#define DS1302_WEEK0x8A
#define DS1302_DAY0x86
#define DS1302_MONTH0x88
#define uchar unsigned char

基于51单片机的12864万年历

基于51单片机的12864万年历

#include <reg51.h> // 该程序具有显示日期、月份、日期和时间功能#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define sint signed int#define disp_off 0x3e //显示关#define disp_on 0x3f //显示开#define disp_x 0xb8 //页地址为0页#define disp_z 0xc0 //行地址为0行#define disp_y 0x40 //列地址为0列#define comm 0 //命令标志位#define dat1 1 //数据标志位#define data_ora P0 //液晶12864的数据端与单片机的P0相连sbit di =P2^0; //Data or Instrument Select,H:写数据,L:写指令sbit rw =P2^1; //Write or Read,H:read,L:writesbit e =P2^4; //读写使能sbit cs1=P2^2; //cs1=H,选择左半屏sbit cs2=P2^3; //cs2=H,选择右半屏sbit clk=P1^0; //8563 clksbit dat=P1^1; //8563 datauchar fen=0x42,miao=0x38,shi=0x17,riqi=0x02,//设置时间用yuefen=0x09,xingqi=0x00,nian=0x07,zhongduan;//设置时间用uchar code tabma[10][16]=//阴码点阵格式、取模方式为列行式、逆向取模(低位在前),//十六进制输出,中文16*16,英文8*16 宋体{//0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9){0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00}, /*"0",0*/{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, /*"1",1*/{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00}, /*"2",2*/{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00}, /*"3",3*/{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00}, /*"4",4*/{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00}, /*"5",5*/{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00}, /*"6",6*/{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, /*"7",7*/{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00}, /*"8",8*/{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}, /*"9",9*/ };uchar code tab2ma[7][32]=// 日(0) 一(1) 二(2) 三(3) 四(4) 五(5) 六(6){{0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00}, /*"日",0*/{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /*"一",1*/{0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x06,0x04,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00}, /*"二",2*/{0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x04,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00}, /*"三",3*/{0x00,0xFE,0x02,0x02,0x02,0xFE,0x02,0x02,0xFE,0x02,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x7F,0x28,0x24,0x23,0x20,0x20,0x20,0x21,0x22,0x22,0x22,0x22,0x7F,0x00,0x00}, /*"四",4*/{0x00,0x02,0x82,0x82,0x82,0x82,0xFE,0x82,0x82,0x82,0xC2,0x82,0x02,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x30,0x20,0x00}, /*"五",5*/{0x10,0x10,0x10,0x10,0x10,0x91,0x12,0x1E,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x00,0x00,0x01,0x02,0x0C,0x78,0x30,0x00,0x00}, /*"六",6*/ };uchar code nianma[]=//年(0) 月(1) 日(2) 星(3) 期(4){0x40,0x20,0x10,0x0C,0xE3,0x22,0x22,0x22,0xFE,0x22,0x22,0x22,0x22,0x02,0x00,0x00,0x04,0x04,0x04,0x04,0x07,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00}; /*"年",0*/ uchar code yuema[]={0x00,0x00,0x00,0x00,0x00,0xFF,0x11,0x11,0x11,0x11,0x11,0xFF,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x0C,0x03,0x01,0x01,0x01,0x21,0x41,0x3F,0x00,0x00,0x00,0x00}; /*"月",1*/ uchar code rima[]={0x00,0x00,0x00,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3F,0x00,0x00,0x00,0x00}; /*"日",2*/ uchar code xingqima[]={0x00,0x00,0x00,0xBE,0x2A,0x2A,0x2A,0xEA,0x2A,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x48,0x46,0x41,0x49,0x49,0x49,0x7F,0x49,0x49,0x49,0x49,0x49,0x41,0x40,0x00, /*"星",3*/0x00,0x04,0xFF,0x54,0x54,0x54,0xFF,0x04,0x00,0xFE,0x22,0x22,0x22,0xFE,0x00,0x00,0x42,0x22,0x1B,0x02,0x02,0x0A,0x33,0x62,0x18,0x07,0x02,0x22,0x42,0x3F,0x00,0x00}; /*"期",4*///时(0) 分(1) 秒(2)uchar code shima[]={0x00,0xFC,0x44,0x44,0x44,0xFC,0x10,0x90,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x00,0x00,0x07,0x04,0x04,0x04,0x07,0x00,0x00,0x03,0x40,0x80,0x7F,0x00,0x00,0x00,0x00}; /*"时",0*/uchar code fenma[]={0x80,0x40,0x20,0x98,0x87,0x82,0x80,0x80,0x83,0x84,0x98,0x30,0x60,0xC0,0x40,0x00,0x00,0x80,0x40,0x20,0x10,0x0F,0x00,0x00,0x20,0x40,0x3F,0x00,0x00,0x00,0x00,0x00}; /*"分",1*/uchar code miaoma[]={0x12,0x12,0xD2,0xFE,0x91,0x11,0xC0,0x38,0x10,0x00,0xFF,0x00,0x08,0x10,0x60,0x00,0x04,0x03,0x00,0xFF,0x00,0x83,0x80,0x40,0x40,0x20,0x23,0x10,0x08,0x04,0x03,0x00}; /*"秒",2*/void delay(sint n); //延时程序void xie_start(); //开始条件void xie_stop(); //停止条件bit xie1(uchar shu); //向8563中写入1个字uchar du1(); //从8563中读出1个字uchar du(); //从8563中读出时间和日期uchar xie(); //向8563中设置时间和日期//uchar xie_dingshi(); //8563定时器设置//uchar xie_fangbo_dingshi(); //8563的方波设置void delay1 (uint ms); //延时void wr_lcd (uchar dat_comm,uchar content); //向12864中写命令//uchar rd_lcd (); //读12864数据void chk_busy (); //忙闲检测void lat_disp (uchar data1,uchar data2); //写点钟//void img_disp (uchar code *img) ; //显示图像void chn_disp (uchar x,uchar y,uchar xl,uchar yl,uchar row_xl,uchar row_yl,uchar code *chn);//显示汉字void init_lcd (); //12864初始化void disp(); //128显示程序//-------------主函数--------------------void main(){uchar ml=0;init_lcd (); //LCD初始化lat_disp(0x00,0x00);xie(); //预设时间用,设置好时间后可以屏蔽for(;;){du(); //读8563的时间lat_disp(0x00,0x00);disp(); //显示时间delay1(100);}}//-------------------延时---------------------------//void delay(sint n){for(n;n>0;n--);}/////////////////////以下是PCF8563读写/////////////////////以下是PCF8563读写/* I2C的起始条件,在时钟端SCK为高电平时,数据端SDA发生由高到低的变化,为起始条件,启动I2C总线。

#51单片机12864万年历C语言

#51单片机12864万年历C语言

51单片机做的12864万年历Main.c#include "reg52.h"#include "macroconst.h"#include "keyscan.h"#include "screen.h"#include "18b20.h"#include "ds1302.h"#include "atao_12864.h"#include "24c02.h"idata unsigned char state1[1]。

unsigned char screennum=1。

//屏幕号#define time_task_sec 200 //节拍200Hz#define clock 24000000 //晶振#define max_task 4 //最大任务数idata unsigned char task_delay[4]。

#define task_delay0 time_task_sec/1 //2赫兹18b20 #define task_delay1 time_task_sec/5 //10赫兹屏幕#define task_delay2 time_task_sec/3 //4赫兹1302 #define task_delay3 time_task_sec/20 //20赫兹键盘void init(>{unsigned char i。

init18b20(>。

ds1302_init(>。

initina1(>。

//---------------------------LCD字库初始化程序 RdFromROM(state1,8,1>。

state[0]=state1[0]。

//-------界面RdFromROM(state1,15,1>。

51单片机实现万年历程序文件

51单片机实现万年历程序文件

51单片机实现万年历利用AT89S52单片机的P0口来和另外几个口来控制1602液晶的显示和P1口还有其它口来控制ds12887时钟芯片。

设置四个按键,1个定义为时间设置功能键,一个定义为闹钟设置功能键,另外两个用来调节时间的增减。

原理图:pcb图:源程序:#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit beep=P2^0;//蜂鸣器控制口sbit timeadd=P2^1;//调节时间加sbit timesub=P2^2;//调节时间减sbit timeclk=P2^3;//闹钟设定键sbit timefun=P2^4;//时间设定键sbit lcdrs=P2^5;//液晶的命令和数据控制口sbit ledrw=P2^6;//液晶的写数据口sbit lcden=P2^7;//液晶显示模块的使能端sbit timeds=P3^3;//时钟芯片地址闸sbit timerw=P3^4;//时钟芯片读写sbit timeas=P3^5;//时钟芯片地址闸sbit timeen=P3^6;//时钟芯片片选uchar code table[]="20 - - week ";uchar code table1[]=" : : ";//要显示的字符串char num,shi,fen,miao,nian=2000,yue,ri,week,numfun,anumfun,flag,flag1; uchar leap;void delay(uint x){uchar i,j;for(i=x;i>0;i--)for(j=110;j>0;j--);}void didi(){beep=0;delay(1000);beep=1;delay(1000);}void write_(uchar ){lcdrs=0;P0=;delay(5);lcden=1;delay(20);lcden=0;}void write_date(uchar date){lcdrs=1;P0=date;delay(5);lcden=1;delay(20);lcden=0;}void write_sfm(uchar add,uchar date){ uchar shi,ge;shi=date/10;ge=date%10;write_(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(uchar add,uchar date){ uchar shi,ge;shi=date/10;ge=date%10;write_(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void write_zhou(uchar add,uchar date) {write_(0x80+add);write_date(0x30+date);}void write_ds(uchar add,uchar date){ timeen=0;timeas=1;timeds=1;timerw=1;P1=add;timeas=0;timerw=0;P1=date;timerw=1;timeas=1;timeen=1;}uchar read_ds(uchar add){uchar ds_date;timeas=1;timeds=1;timerw=1;timeen=0;P1=add;timeas=0;timeds=0;P1=0xff;ds_date=P1;timeds=1;timeas=1;timeen=1;return ds_date;}void keyscan(){if(flag1==1)//用来关闭闹钟铃声{if(timeadd==0){delay(5);if(timeadd==0){while(!timeadd==0);flag1=0;}}if(timesub==0){delay(5);if(timesub==0){while(!timesub==0);flag1=0;}}}if(timefun==0){delay(5);if(timefun==0){while(!timefun);flag=1;numfun++;if(numfun==1){write_(0x80+0x40+0x0a);write_(0x0f);}if(numfun==2){write_(0x80+0x40+0x07);write_(0x0f);}if(numfun==3){write_(0x80+0x40+0x04);write_(0x0f);}if(numfun==4){write_(0x80+0x0f);write_(0x0f);}if(numfun==5){write_(0x80+0x09);write_(0x0f);}if(numfun==6){write_(0x80+0x06);write_(0x0f);}if(numfun==7){write_(0x80+0x03);write_(0x0f);}if(numfun==8){numfun=0;flag=0;}}}if(numfun!=0){if(timeadd==0){delay(5);while(!timeadd);if(numfun==1){miao++;if(miao==60)miao=0;write_sfm(9,miao);write_(0x80+0x40+9);write_ds(0,miao);}if(numfun==2){fen++;if(fen==60)fen=0;write_sfm(6,fen);write_(0x80+0x40+6);write_ds(2,fen);}if(numfun==3){shi++;if(shi==24)shi=0;write_sfm(3,shi);write_(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week++;if(week==8)week=1;write_zhou(0x0f,week);write_(0x80+0x0f);write_ds(6,week);}if(numfun==5){if(nian==0){switch(yue){case 1:ri++;if(ri==32) ri=1;break;case 2:ri++;if(ri==30) ri=1;break;case 3:ri++;if(ri==32) ri=1;break;case 4:ri++;if(ri==31) ri=1;break;case 5:ri++;if(ri==32) ri=1;break;case 6:ri++;if(ri==31) ri=1;break;case 7:ri++;if(ri==32) ri=1;break;case 8:ri++;if(ri==32) ri=1;break;case 9:ri++;if(ri==31)ri=1;break;case 10:ri++;if(ri==32)ri=1;break;case 11:ri++;if(ri==31)ri=1;break;case 12:ri++;if(ri==32)ri=1;break;}}else if(leap&&yue==2){ri++;if(ri==30)ri=1;}else if(yue==2&&leap==0){ri++;if(ri==29)ri=1;}elseswitch(yue){case 1:ri++;if(ri==32) ri=1;break;case 3:ri++;if(ri==32) ri=1;break;case 4:ri++;if(ri==31) ri=1;break;case 5:ri++;if(ri==32) ri=1;break;case 6:ri++;if(ri==31) ri=1;break;case 7:ri++;if(ri==32) ri=1;break;case 8:ri++;if(ri==32) ri=1;break;case 9:ri++;if(ri==31) ri=1;break;case 10:ri++;if(ri==32) ri=1;break;case 11:ri++;if(ri==31) ri=1;break;case 12:ri++;if(ri==32) ri=1;break;}write_nyr(8,ri);write_(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue++;if(yue==13)yue=0;write_nyr(5,yue);write_(0x80+0x05);write_ds(8,yue);}if(numfun==7){nian++;if(nian==100)nian=0;leap=nian%4==0&&nian%100!=0;write_nyr(2,nian);write_(0x80+2);write_ds(9,nian);}}if(timesub==0){delay(5);while(!timesub);if(numfun==1){miao--;if(miao==-1)miao=59;write_sfm(9,miao);write_(0x80+0x40+9);write_ds(0,miao);}if(numfun==2){fen--;if(fen==-1)fen=59;write_sfm(6,fen);write_(0x80+0x40+6);write_ds(2,fen);}if(numfun==3){shi--;if(shi==-1)shi=23;write_sfm(3,shi);write_(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week--;if(week==0)week=7;write_zhou(0x0f,week);write_(0x80+0x0f);write_ds(6,week);}if(numfun==5){if(nian==0){switch(yue){case 1:ri--;if(ri==0) ri=31;break;case 2:ri--;if(ri==0) ri=29;break;case 3:ri--;if(ri==0) ri=31;break;case 4:ri--;if(ri==0) ri=30;break;case 5:ri--;if(ri==0) ri=31;break;case 6:ri--;if(ri==0) ri=30;break;case 7:ri--;if(ri==0) ri=31;break;case 8:ri--;if(ri==0) ri=31;break;case 9:ri--;if(ri==0) ri=30;break;case 10:ri--;if(ri==0) ri=31;break;case 11:ri--;if(ri==0) ri=30;break;case 12:ri--;if(ri==0) ri=31;break;}}else if(leap&&yue==2){ri--;if(ri==0)ri=29;}else if(yue==2&&leap==0){ri--;if(ri==0)ri=28;}elseswitch(yue){case 1:ri--;if(ri==0) ri=31;break;case 3:ri--;if(ri==0) ri=31;break;case 4:ri--;if(ri==0) ri=30;break;case 5:ri--;if(ri==0) ri=31;break;case 6:ri--;if(ri==0) ri=30;break;case 7:ri--;if(ri==0) ri=31;break;case 8:ri--;if(ri==0) ri=31;break;case 9:ri--;if(ri==0) ri=30;break;case 10:ri--;if(ri==0) ri=31;break;case 11:ri--;if(ri==0) ri=30;break;case 12:ri--;if(ri==0) ri=31;break;}write_nyr(8,ri);write_(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue--;if(yue==-1)yue=12;write_nyr(5,yue);write_(0x80+0x05);write_ds(8,yue);}if(numfun==7){nian--;if(nian==-1)nian=99;leap=nian%4==0&&nian%100!=0;write_nyr(2,nian);write_(0x80+2);write_ds(9,nian);}}}}void set_alarm(){uchar ashi,afen,amiao;if(timeclk==0)//判断是否按下闹钟设定键{delay(5);//延时消抖if(timeclk==0){while(!timeclk);anumfun++;//按键次数加1if(anumfun==1){flag=1;write_(0x80+0x40+0x0a);write_(0x0f);}if(anumfun==2){flag=1;write_(0x80+0x40+0x07);write_(0x0f);}if(anumfun==3){flag=1;write_(0x80+0x40+0x04);write_(0x0f);}if(anumfun==4){flag=0;anumfun=0;}}}if(anumfun!=0){if(timeadd==0)//如果加功能键按下{delay(5);while(!timeadd);if(anumfun==1) //设定秒{amiao++;if(amiao==60)amiao=0;write_sfm(9,amiao);write_(0x80+0x40+9);write_ds(1,amiao);}if(anumfun==2){afen++;if(afen==60)afen=0;write_sfm(6,afen);write_(0x80+0x40+6);write_ds(3,afen);}if(anumfun==3){ashi++;if(ashi==24)ashi=0;write_sfm(3,ashi);write_(0x80+0x40+3);write_ds(5,ashi);}}}if(anumfun!=0){if(timesub==0){delay(5);while(!timesub);if(anumfun==1){amiao--;if(amiao==-1)amiao=59;write_sfm(9,amiao);write_(0x80+0x40+9);write_ds(1,amiao);}if(anumfun==2){afen--;if(afen==-1)afen=59;write_sfm(6,afen);write_(0x80+0x40+6);write_ds(3,afen);}if(anumfun==3){ashi--;if(ashi==-1)ashi=23;write_sfm(3,ashi);write_(0x80+0x40+3);write_ds(5,ashi);}}}}void init(){EA=1;//开总中断EX0=1;//开外部中断0IT0=1;//设定触发方式为负跳变沿有效lcden=0;//选通液晶显示屏ledrw=0;//设定液晶显示屏的读写方式为读write_(0x38);//设置液晶显示模式为16*2显示,5*7点阵,8位数据接口 write_(0x0c);//打开显示,并使光标不显示也不闪烁write_(0x06);//光标指针每次自动加1write_(1);//清屏write_(0x80);//送地址指针for(num=0;num<16;num++){write_date(table[num]);delay(5);}write_(0x80+0x40);//写到第二行for(num=0;num<11;num++){write_date(table1[num]);delay(5);}write_ds(0x0a,0x20);//开启时钟芯片振荡器write_ds(0x0b,0x26);//开启闹钟read_ds(0x0c);//读取时钟芯片c寄存器}void main(){init();while(1){keyscan();set_alarm();if(flag1==1)didi();if(flag==0){//读取时间miao=read_ds(0x00);fen=read_ds(0x02);shi=read_ds(0x04);yue=read_ds(0x08);ri=read_ds(0x07);nian=read_ds(0x09);week=read_ds(0x06);//写入液晶显示屏write_sfm(9,miao);write_sfm(6,fen);write_sfm(3,shi);write_nyr(2,nian);write_nyr(5,yue);write_nyr(8,ri);write_zhou(0x0f,week);}}}void exter() interrupt 0{flag1=1;read_ds(0x0c);//读时钟芯片c寄存器。

单片机万年历c语言程序

单片机万年历c语言程序
DIS_led();
}
}
void time_1() interrupt 1
{
TH0 = (65536 - 1000) / 256;
TL0 = (65536 - 1000) % 256;
time++;
if(time == 2000)
{
time = 0;
/******************************************************************/
unsigned char code str[] = {
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff
};
unsigned char su[] = {
10,10,10,10,10,10,10,10
};
void delay_SMG(unsigned char t)
}
IN_key();
if(SURE == 1) //按下确认键 确认日期
{
if(flag_led > 0)
{
strl_led[flag_led] = day_add;
flag_led = 0;
SURE = 0;
day_add = 0;
lei = P3 & 0xf0;
zong = hang | lei;
switch (zong)
{
case 0x7e: key = 1; //模式选择按键
flag_led ++;
if(flag_led > 6) flag_led = 0;

51电子日历C程序

51电子日历C程序

#define SYS_CLOCK_EN 1#if SYS_CLOCK_EN#include "typedef.h"#include "reg52.h"#include "string.h"#include "stdlib.h"#include "Stdio.h"#define FOSC 22118400L#define MACHINE_NUM 12 /*根据需要调整,如:W777E58=4*/#define TICKS_PER_SEC 10 /* # of clock ticks to obtain 1 second */#define CLK_DATE_EN 1 /* Enable DATE (when 1) */#define ENTER_CRITICAL() EA=1#define EXIT_CRITICAL() EA=0#if CLK_DATE_ENtypedef struct clk_month{UCHAR MonthDays; /* Number of days in each month */char *MonthName; /* Name of the month */UCHAR MonthVal; /* Value used to compute day of the week */} CLK_MONTH;#endifstatic UCHAR ClkTickCtr; /* Counter used to keep track of system clock ticks */static UCHAR ClkHr;static UCHAR ClkMin;static UCHAR ClkSec; /* Counters for local TIME*/#if CLK_DATE_ENstatic UCHAR ClkDay; /* Counters for local DATE */static UCHAR ClkDOW; /* Day of week (0 is Sunday)*/static UCHAR ClkMonth;static UINT ClkYear;#endif/****************************************************************************** ***************************** FUNCTION PROTOTYPES******************************************************************************* ***************************/static BOOL ClkUpdateTime(void);#if CLK_DATE_ENstatic BOOL ClkIsLeapYear(UINT year);static void ClkUpdateDate(void);static void ClkUpdateDOW(void);#endifvoid Init_sys_timer(void);void Sys_clk_init(void);void Sys_clk_task(void);void Clk_format_time(UCHAR mode, char *s);void Clk_set_time(UCHAR hr, UCHAR min, UCHAR sec);int Cmp_now_time(UCHAR hr, UCHAR min, UCHAR sec);#if CLK_DATE_ENvoid Clk_format_date(UCHAR mode, char *s);void Clk_set_date(UCHAR month, UCHAR day, UINT year);void Clk_set_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);int Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec);#endif/****************************************************************************** ***************************/#if CLK_DATE_ENstatic char code *ClkDOWTbl[] = { /* NAME FOR EACH DAY OF THE WEEK */"Sunday ","Monday ","Tuesday ","Wednesday ","Thursday ","Friday ","Saturday "};static CLK_MONTH code ClkMonthTbl[] = { /* MONTHS TABLE */{0, "", 0}, /* Invalid month */{31, "January ", 6}, /* January */{28, "February ", 2}, /* February (note leap years are handled by code) */{31, "March ", 2}, /* March */{30, "April ", 5}, /* April */{31, "May ", 0}, /* May */{30, "June ", 3}, /* June */{31, "July ", 5}, /* July */{31, "August ", 1}, /* August */{30, "September ", 4}, /* September */{31, "October ", 6}, /* October */{30, "November ", 2}, /* November */{31, "December ", 4} /* December */};#endif/******************************************************************************** *************************** TIME-OF-DAY CLOCK TASK** Description : This task is created by Sys_clk_init() and is responsible for updating the time and date.* Sys_clk_task() executes every second.* Arguments : None.* Returns : None.* Notes : CLK_DL Y_TICKS must be set to produce 1 second delays.******************************************************************************* ***************************/void Sys_clk_task (void){if(++ClkTickCtr==TICKS_PER_SEC){ClkTickCtr=0;if (ClkUpdateTime() == TRUE){#if CLK_DATE_ENClkUpdateDate(); /* And date if a new day (i.e. MM-DD-YY) */#endif}}}void Sys_tick_isr(void) interrupt 5 using 3{TF2=0;Sys_clk_task();}void Init_sys_timer(void){BYTE_WORD Init_value;Sys_clk_init();T2CON=0x00;Init_value.word=FOSC/(TICKS_PER_SEC*MACHINE_NUM);TH2=RCAP2H=-Init_value.bytes.high;TL2=RCAP2L=-Init_value.bytes.low;ET2=1;TR2=1;//TMOD&=0xF0; //使用定时器0,但在中断中需要重新赋初值,因而我更倾向用Timer2//TMOD|=0x01;// Init_value.word=FOSC/(TICKS_PER_SEC*MACHINE_NUM);//TH0=-Init_value.bytes.high;//TL0=-Init_value.bytes.low;//ET0=1;//TR0=1;}/******************************************************************************** *************************** TIME MODULE INITIALIZATION* TIME-OF-DAY CLOCK INITIALIZATION** Description : This function initializes the time module. The time of day clock task will be created* by this function.* Arguments : None* Returns : None.******************************************************************************* ***************************/void Sys_clk_init (void){ClkTickCtr = 0;Clk_set_time(11,32,0);#if CLK_DATE_ENClk_set_date(5,28,2002);#endif}/******************************************************************************** *************************** FORMAT CURRENT DATE INTO STRING** Description : Formats the current date into an ASCII string.* Arguments : mode is the format type:* 1 will format the time as "MM-DD-YY" (needs at least 9 characters)* 2 will format the time as "Day Month DD, YYYY" (needs at least30 characters)* 3 will format the time as "YYYY-MM-DD" (needs at least 11 characters)* s is a pointer to the destination string. The destination string must be large* enough to hold the formatted date.* contain* Returns : None.* Notes : - A 'switch' statement has been used to allow you to add your own date formats. For* example, you could display the date in French, Spanish, German etc. by assigning* numbers for those types of conversions.* - This function assumes that strcpy(), strcat() and itoa() are reentrant.******************************************************************************* ***************************/#if CLK_DATE_ENvoid Clk_format_date (UCHAR mode, char *s){UINT year;char str[5];switch (mode){case 1:strcpy(s, "MM-DD-YY"); /* Create the template for the selected format */s[0] = ClkMonth / 10 + '0'; /* Convert DATE to ASCII */s[1] = ClkMonth % 10 + '0';s[3] = ClkDay / 10 + '0';s[4] = ClkDay % 10 + '0';year = ClkYear % 100;s[6] = year / 10 + '0';s[7] = year % 10 + '0';break;case 2:strcpy(s, ClkDOWTbl[ClkDOW]); /* Get the day of the week */strcat(s, ClkMonthTbl[ClkMonth].MonthName); /* Get name of month */if (ClkDay < 10){str[0] = ClkDay + '0';str[1] = 0;}else{str[0] = ClkDay / 10 + '0';str[1] = ClkDay % 10 + '0';str[2] = 0;}strcat(s, str);strcat(s, ", ");sprintf(str,"%d",ClkYear);strcat(s, str);break;case 3:strcpy(s, "YYYY-MM-DD"); /* Create the template for the selected format */s[0] = year / 1000 + '0';year = year % 1000;s[1] = year / 100 + '0';year = year % 100;s[2] = year / 10 + '0';s[3] = year % 10 + '0';s[5] = ClkMonth / 10 + '0'; /* Convert DATE to ASCII */s[6] = ClkMonth % 10 + '0';s[8] = ClkDay / 10 + '0';s[9] = ClkDay % 10 + '0';break;default:strcpy(s, "?");break;}}#endif/******************************************************************************** *************************** FORMAT CURRENT TIME INTO STRING** Description : Formats the current time into an ASCII string.* Arguments : mode is the format type:* 1 will format the time as "HH:MM:SS" (24 Hour format)* (needs at least 9 characters)* 2 will format the time as "HH:MM:SS AM" (With AM/PM indication)* (needs at least 13 characters)* s is a pointer to the destination string. The destination string must be large* enough to hold the formatted time.* contain* Returns : None.* Notes : - A 'switch' statement has been used to allow you to add your own time formats. * - This function assumes that strcpy() is reentrant.******************************************************************************* ***************************/void Clk_format_time (UCHAR mode, char *s){UCHAR hr;switch (mode){case 1:strcpy(s, "HH:MM:SS"); /* Create the template for the selected format */s[0] = ClkHr / 10 + '0'; /* Convert TIME to ASCII */s[1] = ClkHr % 10 + '0';s[3] = ClkMin / 10 + '0';s[4] = ClkMin % 10 + '0';s[6] = ClkSec / 10 + '0';s[7] = ClkSec % 10 + '0';break;case 2:strcpy(s, "HH:MM:SS AM"); /* Create the template for the selected format */s[9] = (ClkHr >= 12) ? 'P' : 'A'; /* Set AM or PM indicator */if (ClkHr > 12){ /* Adjust time to be displayed */hr = ClkHr - 12;}else{hr = ClkHr;}s[0] = hr / 10 + '0'; /* Convert TIME to ASCII */s[1] = hr % 10 + '0';s[3] = ClkMin / 10 + '0';s[4] = ClkMin % 10 + '0';s[6] = ClkSec / 10 + '0';s[7] = ClkSec % 10 + '0';break;default:strcpy(s, "?");break;}}/******************************************************************************** *************************** UPDATE THE TIME** Description : This function is called to update the time (i.e. hours, minutes and seconds)* Arguments : None.* Returns : TRUE if we have completed one day.* FALSE otherwise* Notes : This function updates ClkSec, ClkMin and ClkHr.******************************************************************************* ***************************/static BOOL ClkUpdateTime (void){BOOL newday;newday = FALSE; /* Assume that we haven't completed one whole day yet */if (ClkSec >= 59){ /* See if we have completed one minute yet */ClkSec = 0; /* Yes, clear seconds */if (ClkMin >= 59){ /* See if we have completed one hour yet */ClkMin = 0; /* Yes, clear minutes */if (ClkHr >= 23){ /* See if we have completed one day yet */ClkHr = 0; /* Yes, clear hours ... */newday = TRUE; /* ... change flag to indicate we have a new day */}else{ClkHr++; /* No, increment hours */}}else{ClkMin++; /* No, increment minutes */}}else{ClkSec++; /* No, increment seconds */}return (newday);}/******************************************************************************** *************************** SET TIME ONL Y** Description : Set the time-of-day clock* Arguments : hr is the desired hour (0..23)* min is the desired minutes (0..59)* sec is the desired seconds (0..59)* Returns : None.* Notes : It is assumed that you are specifying a correct time (i.e. there is no range checking* done by this function).******************************************************************************* ***************************/void Clk_set_time (UCHAR hr, UCHAR min, UCHAR sec){ENTER_CRITICAL(); /* Gain exclusive access to time-of-day clock */ClkHr = hr;ClkMin = min;ClkSec = sec;EXIT_CRITICAL(); /* Release access to time-of-day clock */}/******************************************************************************** *************************** DETERMINE IF WE HA VE A LEAP YEAR** Description : This function determines whether the 'year' passed as an argument is a leap year.* Arguments : year is the year to check for leap year.* Returns : TRUE if 'year' is a leap year.* FALSE if 'year' is NOT a leap year.******************************************************************************* ***************************/#if CLK_DATE_ENstatic BOOL ClkIsLeapYear(UINT year){if (!(year % 4) && (year % 100) || !(year % 400)){return TRUE;}else{return (FALSE);}}#endif/******************************************************************************** *************************** SET DA TE ONL Y** Description : Set the date of the time-of-day clock* Arguments : month is the desired month (1..12)* day is the desired day (1..31)* year is the desired year (CLK_TS_BASE_YEAR .. CLK_TS_BASE_YEAR+63)* Returns : None.* Notes : It is assumed that you are specifying a correct date (i.e. there is no range checking* done by this function).******************************************************************************* ***************************/#if CLK_DATE_ENvoid Clk_set_date (UCHAR month, UCHAR day, UINT year){ENTER_CRITICAL();ClkMonth = month;ClkDay = day;ClkYear = year;ClkUpdateDOW();EXIT_CRITICAL();}#endif/******************************************************************************** *************************** SET DATE AND TIME** Description : Set the date and time of the time-of-day clock* Arguments : month is the desired month (1..12)* day is the desired day (1..31)* year is the desired year (2xxx)* hr is the desired hour (0..23)* min is the desired minutes (0..59)* sec is the desired seconds (0..59)* Returns : None.* Notes : It is assumed that you are specifying a correct date and time (i.e. there is no range* checking done by this function).******************************************************************************* ***************************/#if CLK_DATE_ENvoid Clk_set_date_time (UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min,UCHAR sec){ENTER_CRITICAL(); /* Gain exclusive access to time-of-day clock */ClkMonth = month;ClkDay = day;ClkYear = year;ClkHr = hr;ClkMin = min;ClkSec = sec;ClkUpdateDOW(); /* Compute the day of the week (i.e. Sunday ...) */EXIT_CRITICAL(); /* Release access to time-of-day clock */}#endif/******************************************************************************** *************************** UPDATE THE DATE** Description : This function is called to update the date (i.e. month, day and year)* Arguments : None.* Returns : None.* Notes : This function updates ClkDay, ClkMonth, ClkYear and ClkDOW.******************************************************************************* ***************************/#if CLK_DATE_ENstatic void ClkUpdateDate (void){BOOL newmonth;newmonth = TRUE;if (ClkDay >= ClkMonthTbl[ClkMonth].MonthDays) { /* Last day of the month? */if (ClkMonth == 2) { /* Is this February? */if (ClkIsLeapYear(ClkYear) == TRUE) { /* Yes, Is this a leap year? */if (ClkDay >= 29) { /* Yes, Last day in february? */ClkDay = 1; /* Yes, Set to 1st day in March */} else {ClkDay++;newmonth = FALSE;}} else {ClkDay = 1;}} else {ClkDay = 1;}} else {ClkDay++;newmonth = FALSE;}if (newmonth == TRUE) { /* See if we have completed a month */if (ClkMonth >= 12) { /* Yes, Is this december ? */ClkMonth = 1; /* Yes, set month to january... */ClkYear++; /* ...we have a new year! */} else {ClkMonth++; /* No, increment the month */}}ClkUpdateDOW(); /* Compute the day of the week (i.e. Sunday ...) */}#endif/******************************************************************************** *************************** COMPUTE DAY-OF-WEEK** Description : This function computes the day of the week (0 == Sunday) based on the current month,* day and year.* Arguments : None.* Returns : None.* Notes : - This function updates ClkDOW.* - This function is called by ClkUpdateDate().**********************************************************************************************************/#if CLK_DATE_ENstatic void ClkUpdateDOW (void){UINT dow;dow = ClkDay + ClkMonthTbl[ClkMonth].MonthVal;if (ClkMonth < 3){if (ClkIsLeapYear(ClkYear)){dow--;}}dow += ClkYear + (ClkYear / 4);dow += (ClkYear / 400) - (ClkYear / 100);dow %= 7;ClkDOW = dow;}#endifint Cmp_now_time(UCHAR hr, UCHAR min, UCHAR sec){if(ClkHr!=hr)return(hr-ClkHr);else if(ClkMin!= min)return(min-ClkMin);elsereturn(sec-ClkSec);}#if CLK_DATE_ENint Cmp_now_date_time(UCHAR month, UCHAR day, UINT year, UCHAR hr, UCHAR min, UCHAR sec){if(ClkYear!=year)return(year-ClkYear);else if(ClkMonth!=month)return(month-ClkMonth);else if(ClkDay!=day)return(day-ClkDay);else if(ClkHr!=hr)return(hr-ClkHr);else if(ClkMin!= min)return(min-ClkMin);elsereturn(sec-ClkSec); }#endif#endif。

51单片机万年历毕设程序各种功能

51单片机万年历毕设程序各种功能

#include<reg52.h>//#include"DS18B20_3.H"#include <string.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned char#define wd 1 //定义是否有温度功能=0时无温度,=1时有温度#define yh 0x80 //LCD第一行的初始位置,因为LCD1602字符地址首位D7恒定为1(100000000=80)#define er 0x80+0x40 //LCD第二行初始位置(因为第二行第一个字符位置地址是0x40)//液晶屏的与C51之间的引脚连接定义(显示数据线接C51的P0口)sbit en=P2^7;sbit rw=P2^6; //如果硬件上rw接地,就不用写这句和后面的rw=0了sbit rs=P2^5; //校时按键与C51的引脚连接定义sbit menu=P3^0; //菜单键sbit set=P3^1; //设置键sbit add=P3^2; //加键sbit dec=P3^3; //减键sbit ensure=P3^4; //确认键sbit DQ=P2^0; //sbit buzzer=P1^4; //蜂鸣器,通过三极管8550驱动,端口低电平响sbit led=P2^4; //LCD背光开关bit led1=1;unsigned char temp_miao;unsigned char bltime; //背光亮的时间//DS1302时钟芯片与C51之间的引脚连接定义sbit IO=P1^1;sbit SCLK=P1^0;sbit RST=P1^2;uchar a,miao,shi,fen,ri,yue,nian,week,setn,temp;uint flag;//flag用于读取头文件中的温度值,和显示温度值bit c_moon;uchar nz_shi=12,nz_fen=0,nz_miao=0,setNZn; //定义闹钟变量uchar shangyimiao,bsn,temp_hour; //记录上一秒时间uchar T_NL_NZ; //计数器bit timerOn=0; //闹钟启用标志位bit baoshi=0; //整点报时标志位bit p_r=0; //平年/润年=0表示平年,=1表示润年data uchar year_moon,month_moon,day_moon,week;sbit ACC0=ACC^0;sbit ACC7=ACC^7;ACC累加器=AACC.0=E0H//********阳历转换阴历表************************************code uchar year_code[597]={ 0x04,0xAe,0x53, 0x0A,0x57,0x48, 0x55,0x26,0xBd, 0x0d,0x26,0x50, 0x0d,0x95,0x44, 0x46,0xAA,0xB9, 0x05,0x6A,0x4d, 0x09,0xAd,0x42, 0x24,0xAe,0xB6, 0x04,0xAe,0x4A, 0x6A,0x4d,0xBe, 0x0A,0x4d,0x52,0x0d,0x25,0x46, 0x5d,0x52,0xBA, 0x0B,0x54,0x4e, 0x0d,0x6A,0x43, 0x29,0x6d,0x37, 0x09,0x5B,0x4B, 0x74,0x9B,0xC1, 0x04,0x97,0x54, 0x0A,0x4B,0x48,0x5B,0x25,0xBC, 0x06,0xA5,0x50, 0x06,0xd4,0x45, 0x4A,0xdA,0xB8, 0x02,0xB6,0x4d, 0x09,0x57,0x42, 0x24,0x97,0xB7, 0x04,0x97,0x4A,0x66,0x4B,0x3e, 0x0d,0x4A,0x51, 0x0e,0xA5,0x46, 0x56,0xd4,0xBA, 0x05,0xAd,0x4e, 0x02,0xB6,0x44, 0x39,0x37,0x38, 0x09,0x2e,0x4B,0x7C,0x96,0xBf, 0x0C,0x95,0x53, 0x0d,0x4A,0x48, 0x6d,0xA5,0x3B,0x0B,0x55,0x4f, 0x05,0x6A,0x45, 0x4A,0xAd,0xB9, 0x02,0x5d,0x4d,0x09,0x2d,0x42, 0x2C,0x95,0xB6, 0x0A,0x95,0x4A, 0x7B,0x4A,0xBd,0x06,0xCA,0x51, 0x0B,0x55,0x46, 0x55,0x5A,0xBB, 0x04,0xdA,0x4e,0x0A,0x5B,0x43, 0x35,0x2B,0xB8, 0x05,0x2B,0x4C, 0x8A,0x95,0x3f,0x0e,0x95,0x52, 0x06,0xAA,0x48, 0x7A,0xd5,0x3C, 0x0A,0xB5,0x4f,0x04,0xB6,0x45, 0x4A,0x57,0x39, 0x0A,0x57,0x4d, 0x05,0x26,0x42,0x3e,0x93,0x35, 0x0d,0x95,0x49, 0x75,0xAA,0xBe, 0x05,0x6A,0x51,0x09,0x6d,0x46, 0x54,0xAe,0xBB, 0x04,0xAd,0x4f, 0x0A,0x4d,0x43,0x4d,0x26,0xB7, 0x0d,0x25,0x4B, 0x8d,0x52,0xBf, 0x0B,0x54,0x52, 0x0B,0x6A,0x47,0x69,0x6d,0x3C, 0x09,0x5B,0x50, 0x04,0x9B,0x45, 0x4A,0x4B,0xB9,0x0A,0x4B,0x4d, 0xAB,0x25,0xC2, 0x06,0xA5,0x54, 0x06,0xd4,0x49,0x6A,0xdA,0x3d, 0x0A,0xB6,0x51, 0x09,0x37,0x46, 0x54,0x97,0xBB,0x04,0x97,0x4f, 0x06,0x4B,0x44, 0x36,0xA5,0x37, 0x0e,0xA5,0x4A,0x86,0xB2,0xBf, 0x05,0xAC,0x53, 0x0A,0xB6,0x47, 0x59,0x36,0xBC,0x09,0x2e,0x50, 0x0C,0x96,0x45, 0x4d,0x4A,0xB8, 0x0d,0x4A,0x4C,0x0d,0xA5,0x41, 0x25,0xAA,0xB6, 0x05,0x6A,0x49, 0x7A,0xAd,0xBd,0x02,0x5d,0x52, 0x09,0x2d,0x47, 0x5C,0x95,0xBA, 0x0A,0x95,0x4e, 0x0B,0x4A,0x43, 0x4B,0x55,0x37, 0x0A,0xd5,0x4A, 0x95,0x5A,0xBf, 0x04,0xBA,0x53, 0x0A,0x5B,0x48, 0x65,0x2B,0xBC, 0x05,0x2B,0x50, 0x0A,0x93,0x45, 0x47,0x4A,0xB9, 0x06,0xAA,0x4C, 0x0A,0xd5,0x41,0x24,0xdA,0xB6, 0x04,0xB6,0x4A, 0x69,0x57,0x3d, 0x0A,0x4e,0x51,0x0d,0x26,0x46, 0x5e,0x93,0x3A, 0x0d,0x53,0x4d, 0x05,0xAA,0x43, 0x36,0xB5,0x37, 0x09,0x6d,0x4B, 0xB4,0xAe,0xBf, 0x04,0xAd,0x53,0x0A,0x4d,0x48, 0x6d,0x25,0xBC, 0x0d,0x25,0x4f, 0x0d,0x52,0x44, 0x5d,0xAA,0x38, 0x0B,0x5A,0x4C, 0x05,0x6d,0x41, 0x24,0xAd,0xB6,0x04,0x9B,0x4A, 0x7A,0x4B,0xBe, 0x0A,0x4B,0x51, 0x0A,0xA5,0x46,0x5B,0x52,0xBA, 0x06,0xd2,0x4e, 0x0A,0xdA,0x42, 0x35,0x5B,0x37,0x09,0x37,0x4B, 0x84,0x97,0xC1, 0x04,0x97,0x53, 0x06,0x4B,0x48,0x66,0xA5,0x3C, 0x0e,0xA5,0x4f, 0x06,0xB2,0x44, 0x4A,0xB6,0x38, 0x0A,0xAe,0x4C, 0x09,0x2e,0x42, 0x3C,0x97,0x35, 0x0C,0x96,0x49,0x7d,0x4A,0xBd, 0x0d,0x4A,0x51, 0x0d,0xA5,0x45, 0x55,0xAA,0xBA,0x05,0x6A,0x4e, 0x0A,0x6d,0x43, 0x45,0x2e,0xB7, 0x05,0x2d,0x4B,0x8A,0x95,0xBf, 0x0A,0x95,0x53, 0x0B,0x4A,0x47, 0x6B,0x55,0x3B,0x0A,0xd5,0x4f, 0x05,0x5A,0x45, 0x4A,0x5d,0x38, 0x0A,0x5B,0x4C, 0x05,0x2B,0x42, 0x3A,0x93,0xB6, 0x06,0x93,0x49, 0x77,0x29,0xBd, 0x06,0xAA,0x51,0x0A,0xd5,0x46, 0x54,0xdA,0xBA, 0x04,0xB6,0x4e, 0x0A,0x57,0x43,0x45,0x27,0x38, 0x0d,0x26,0x4A, 0x8e,0x93,0x3e, 0x0d,0x52,0x52,0x0d,0xAA,0x47, 0x66,0xB5,0x3B, 0x05,0x6d,0x4f, 0x04,0xAe,0x45, 0x4A,0x4e,0xB9, 0x0A,0x4d,0x4C, 0x0d,0x15,0x41, 0x2d,0x92,0xB5, };///月份数据表code uchar day_code1[9]={0x0,0x1f,0x3b,0x5a,0x78,0x97,0xb5,0xd4,0xf3};code uint day_code2[3]={0x111,0x130,0x14e}bit c_moon;data uchar year_moon,month_moon,day_moon,week;//子函数,用于读取数据表中农历月的大月或小月,如果该月为大返回1,为小返回0bit get_moon_day(uchar month_p,uint table_addr){uchar temp;switch (month_p){case 1:{temp=year_code[table_addr]&0x08;if (temp==0)return(0);else return(1);}case 2:{temp=year_code[table_addr]&0x04;if (temp==0)return(0);else return(1);}case 3:{temp=year_code[table_addr]&0x02;if (temp==0)return(0);else return(1);}case 4:{temp=year_code[table_addr]&0x01;if (temp==0)return(0);else return(1);}case 5:{temp=year_code[table_addr+1]&0x80;if (temp==0) return(0);else return(1);}case 6:{temp=year_code[table_addr+1]&0x40;if (temp==0)return(0);else return(1);}case 7:{temp=year_code[table_addr+1]&0x20;if (temp==0)return(0);else return(1);}case 8:{temp=year_code[table_addr+1]&0x10;if (temp==0)return(0);else return(1);}case 9:{temp=year_code[table_addr+1]&0x08;if (temp==0)return(0);else return(1);}case 10:{temp=year_code[table_addr+1]&0x04;if (temp==0)return(0);else return(1);}case 11:{temp=year_code[table_addr+1]&0x02;if (temp==0)return(0);else return(1);}case 12:{temp=year_code[table_addr+1]&0x01;if (temp==0)return(0);else return(1);}case 13:{temp=year_code[table_addr+2]&0x80;if (temp==0)return(0);else return(1);}}}/*函数功能:输入BCD阳历数据,输出BCD阴历数据(只允许1901-2099年)调用函数示例:Conversion(c_sun,year_sun,month_sun,day_sun)如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世纪,c_sun=1为19世纪调用函数后,原有数据不变,读c_moon,year_moon,month_moon,day_moon得出阴历BCD数据*/void Conversion(bit c,uchar year,uchar month,uchar day){ //c=0 为21世纪,c=1 为19世纪输入输出数据均为BCD数据uchar temp1,temp2,temp3,month_p;uint temp4,table_addr;bit flag2,flag_y;temp1=year/16; //BCD->hex 先把数据转换为十六进制temp2=year%16;// year=temp1*10+temp2;year=temp1*16+temp2;temp1=month/16;temp2=month%16;//month=temp1*10+temp2;month=temp1*16+temp2;temp1=day/16;temp2=day%16;//day=temp1*10+temp2;day=temp1*16+temp2;//定位数据表地址if(c==0){table_addr=(year+0x64-1)*0x3;}else {table_addr=(year-1)*0x3;}//定位数据表地址完成//取当年春节所在的公历月份temp1=year_code[table_addr+2]&0x60;temp1=_cror_(temp1,5);//取当年春节所在的公历月份完成//取当年春节所在的公历日temp2=year_code[table_addr+2]&0x1f;//取当年春节所在的公历日完成// 计算当年春年离当年元旦的天数,春节只会在公历1月或2月if(temp1==0x1){temp3=temp2-1;}else{temp3=temp2+0x1f-1;}// 计算当年春年离当年元旦的天数完成//计算公历日离当年元旦的天数,为了减少运算,用了两个表//day_code1[9],day_code2[3]//如果公历月在九月或前,天数会少于0xff,用表day_code1[9],//在九月后,天数大于0xff,用表day_code2[3]//如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1//如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10]+10-1if (month<10){temp4=day_code1[month-1]+day-1;}else{temp4=day_code2[month-10]+day-1;}if ((month>0x2)&&(year%0x4==0)){ //如果公历月大于2月并且该年的2月为闰月,天数加1temp4+=1;}//计算公历日离当年元旦的天数完成//判断公历日在春节前还是春节后if (temp4>=temp3){ //公历日在春节后或就是春节当日使用下面代码进行运算temp4-=temp3;month=0x1;month_p=0x1; //month_p为月份指向,公历日在春节前或就是春节当日month_p指向首月flag2=get_moon_day(month_p,table_addr); //检查该农历月为大小还是小月,大月返回1,小月返回0flag_y=0;if(flag2==0)temp1=0x1d; //小月29天else temp1=0x1e; //大小30天temp2=year_code[table_addr]&0xf0;temp2=_cror_(temp2,4); //从数据表中取该年的闰月月份,如为0则该年无闰月while(temp4>=temp1){temp4-=temp1;month_p+=1;if(month==temp2){flag_y=~flag_y;if(flag_y==0)month+=1;}else month+=1;flag2=get_moon_day(month_p,table_addr);if(flag2==0)temp1=0x1d;else temp1=0x1e;}day=temp4+1;}else{ //公历日在春节前使用下面代码进行运算temp3-=temp4;if (year==0x0){year=0x63;c=1;}else year-=1;table_addr-=0x3;month=0xc;temp2=year_code[table_addr]&0xf0;temp2=_cror_(temp2,4);if (temp2==0)month_p=0xc;elsemonth_p=0xd; ////month_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12flag_y=0;flag2=get_moon_day(month_p,table_addr);if(flag2==0)temp1=0x1d;else temp1=0x1e;while(temp3>temp1){temp3-=temp1;month_p-=1;if(flag_y==0)month-=1;if(month==temp2)flag_y=~flag_y;flag2=get_moon_day(month_p,table_addr);if(flag2==0)temp1=0x1d;else temp1=0x1e;}day=temp1-temp3+1;}c_moon=c; //HEX->BCD ,运算结束后,把数据转换为BCD数据temp1=year/10;temp1=_crol_(temp1,4);temp2=year%10;year_moon=temp1|temp2;temp1=month/10;temp1=_crol_(temp1,4);temp2=month%10;month_moon=temp1|temp2;temp1=day/10;temp1=_crol_(temp1,4);temp2=day%10;day_moon=temp1|temp2;}/*函数功能:输入BCD阳历数据,输出BCD星期数据(只允许1901-2099年)调用函数示例:Conver_week(c_sun,year_sun,month_sun,day_sun)如:计算2004年10月16日Conversion(0,0x4,0x10,0x16);c_sun,year_sun,month_sun,day_sun均为BCD数据,c_sun为世纪标志位,c_sun=0为21世纪,c_sun=1为19世纪调用函数后,原有数据不变,读week得出阴历BCD数据*/code uchar table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表/*算法:日期+年份+所过闰年数+月较正数之和除7 的余数就是星期但如果是在闰年又不到3 月份上述之和要减一天再除7星期数为0*/void Conver_week(uchar year,uchar month,uchar day){//c=0 为21世纪,c=1 为19世纪输入输出数据均为BCD数据uchar p1,p2;year+=0x64; //如果为21世纪,年份数加100p1=year/0x4; //所过闰年数只算1900年之后的p2=year+p1;p2=p2%0x7; //为节省资源,先进行一次取余,避免数大于0xff,避免使用整型数据p2=p2+day+table_week[month-1];if (year%0x4==0&&month<3)p2-=1;week=p2%0x7;}/**************************************************************/uchar code tab1[]={"20 - - "}; //年显示的固定字符uchar code tab2[]={" : : "}; //时间显示的固定字符uchar code nlp[]={"NL: - - PING"}; //农历平年显示uchar code nlr[]={"NL: - - RUN "}; //农历润年显示uchar code NZd[]={"timer: - - "}; //显示闹钟固定点uchar code qk[]= {" "}; //清空显示uchar code tm[]= {"time"};//=====================DS18B20========================================= ====//***************************************************************************** *void Delayns(int num)//延时函数{while(num--);}//***************************************************************************** *void Init_DS18B20(void)//初始化ds1820{unsigned char x=0;DQ = 1; //DQ复位Delayns(8); //稍做延时DQ = 0; //单片机将DQ拉低Delayns(80); //精确延时大于480usDQ = 1; //拉高总线Delayns(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败Delayns(20);}//***************************************************************************** *unsigned char ReadOneChar(void)//读一个字节{unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;Delayns(4);}return(dat);}//***************************************************************************** *void WriteOneChar(unsigned char dat)//写一个字节{unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;Delayns(5);DQ = 1;dat>>=1;}}//***************************************************************************** *unsigned int ReadTemperature(void)//读取温度{unsigned char a=0;unsigned char b=0;unsigned int t=0;float tt=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器a=ReadOneChar(); //读低8位b=ReadOneChar(); //读高8位t=b;t<<=8;t=t|a;tt=t*0.0625;t= tt*10+0.5; //放大10倍输出并四舍五入return(t);}//*****************************************************************************//延时函数,后面经常调用void delay(uint xms)//延时函数,有参函数uint x,y;for(x=xms;x>0;x--)for(y=110;y>0;y--);}/********液晶写入指令函数与写入数据函数,以后可调用**************//*在这个程序中,液晶写入有关函数会在DS1302的函数中调用,所以液晶程序要放在前面*/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=0;a<14;a++){write_1602dat(tab1[a]);//向液晶屏写日历显示的固定符号部分//delay(3);}write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示for(a=0;a<8;a++){write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号//delay(3);}}/*********************over***********************//***************DS1302有关子函数********************/void write_byte(uchar dat)//写一个字节{ACC=dat;RST=1;for(a=8;a>0;a--){IO=ACC0;SCLK=0;SCLK=1;ACC=ACC>>1;}}uchar read_byte()//读一个字节{RST=1;for(a=8;a>0;a--){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(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据00//write_1302(0x82,0x00);//向DS1302内写分寄存器82H写入初始分数据00//write_1302(0x84,0x12);//向DS1302内写小时寄存器84H写入初始小时数据12 //write_1302(0x8a,0x04);//向DS1302内写周寄存器8aH写入初始周数据4//write_1302(0x86,0x07);//向DS1302内写日期寄存器86H写入初始日期数据07 //write_1302(0x88,0x01);//向DS1302内写月份寄存器88H写入初始月份数据01 //write_1302(0x8c,0x10);//向DS1302内写年份寄存器8cH写入初始年份数据10 write_1302(0x8e,0x80); //打开写保护//------------------------------------//温度显示子函数void write_temp(uchar add,uint dat)//向LCD写温度数据,并指定显示位置{uint gw,sw,bw;bw=dat/100;//取得百位sw=dat%100/10;//取得十位数字gw=dat%10;//取得个位数字write_1602com(er+add);//er是头文件规定的值0x80+0x40write_1602dat(0x30+bw);write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码write_1602dat('.');write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码write_1602dat(0xdf);//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码}//------------------------------------//时分秒显示子函数void write_sfm(uchar add,uchar dat)//向LCD写时分秒,有显示位置加、现示数据,两个参数{uchar gw,sw;gw=dat%10;//取得个位数字sw=dat/10;//取得十位数字write_1602com(er+add);//er是头文件规定的值0x80+0x40write_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);//设定显示位置为第一个位置+addwrite_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码//------------------------------------//农历显示子函数void write_nl(uchar add,uchar dat)//向LCD写时分秒,有显示位置加、现示数据,两个参数{uchar gw,sw;//gw=dat%10;//取得个位数字//sw=dat/10;//取得十位数字gw=dat%16;//取得个位数字sw=dat/16;//取得十位数字write_1602com(er+add);//er是头文件规定的值0x80+0x40// write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码// write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码write_1602dat('0'+sw);//数字+30得到该数字的LCD1602显示码write_1602dat('0'+gw);//数字+30得到该数字的LCD1602显示码}//-------------------------------------------void write_week(uchar week)//写星期函数{write_1602com(yh+0x0c);//星期字符的显示位置switch(week){case 1:write_1602dat('M');//星期数为1时,显示write_1602dat('O');write_1602dat('N');break;case 2:write_1602dat('T');//星期数据为2时显示write_1602dat('U');write_1602dat('E');break;case 3:write_1602dat('W');//星期数据为3时显示write_1602dat('E');write_1602dat('D');break;case 4:write_1602dat('T');//星期数据为4是显示write_1602dat('H');write_1602dat('U');break;case 5:write_1602dat('F');//星期数据为5时显示write_1602dat('R');write_1602dat('I');break;case 6:write_1602dat('S');//星期数据为6时显示write_1602dat('T');write_1602dat('A');break;case 0:write_1602dat('S');//星期数据为7时显示write_1602dat('U');write_1602dat('N');break;}write_1602dat(' ');}//****************键盘扫描有关函数********************** void keyscan(){if(ensure==0){delay(9);if(ensure==0){buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;led1=1; //背光灭setn=0; //退出任何当前的设置setNZn=0;T_NL_NZ=0;write_1602com(0x0c); //设置光标不闪烁TR0=1; //打开定时器temp=(miao)/10*16+(miao)%10;write_1302(0x8e,0x00);write_1302(0x80,0x00|temp); //miao数据写入DS1302write_1302(0x8e,0x80);}}if(menu==0){delay(9);if(menu==0){led1=0;bltime=0;if((setn==0)&&(setNZn==0)) //在没有进入调时模式时才可按动{buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;if(TR1==1){TR1=0;}else{T_NL_NZ++;if(T_NL_NZ==3){setn=0;setNZn=0;T_NL_NZ=0;}}}while(menu==0);}}if(set==0)//---------------set为功能键(设置键)--------------------{delay(9);//延时,用于消抖动if(set==0)//延时后再次确认按键按下{led1=0;bltime=0;buzzer=0;//蜂鸣器短响一次delay(20);buzzer=1;while(!set);if(T_NL_NZ==0x02) //证明是对闹钟进行设置{setNZn++;if(setNZn==4) //闹钟设定成功,退回到正常显示并开启闹钟{setNZn=0;setn=0;timerOn=1;}switch(setNZn){case 0: //正常显示日期时间write_1602com(0x0c); //置光标不闪?write_1602com(er); //时间显示固定符号写入位置?for(a=0;a<16;a++)write_1602dat(NZd[a]); //写显示时间固定符号,两个冒号write_sfm(8,nz_shi); //闹钟时write_sfm(11,nz_fen); //闹钟分write_sfm(14,nz_miao); //闹钟秒break;case 1: //闹钟秒光标闪烁write_1602com(er+15); //设置按键按动一次,秒位置显示光标//er+0x09;write_1602com(0x0f); //设置光标为闪烁break;case 2: //闹钟分光标闪烁write_1602com(er+12); //设置按键按动一次,秒位置显示光标//er+0x09;write_1602com(0x0f); //设置光标为闪烁break;case 3: //闹钟时光标闪烁write_1602com(er+9); //设置按键按动一次,秒位置显示光标//er+0x09;write_1602com(0x0f); //设置光标为闪烁break;}}else //证明是对时间及日期进行设置{if(T_NL_NZ==0){setn++;if(setn==7)setn=0; //设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环switch(setn){case 1: TR0=0;//关闭定时器//TR1=0;write_1602com(er+7);//设置按键按动一次,秒位置显示光标//er+0x09;write_1602com(0x0f);//设置光标为闪烁temp=(miao)/10*16+(miao)%10;//秒数据写入DS1302write_1302(0x8e,0x00);write_1302(0x80,0x80|temp);//miaowrite_1302(0x8e,0x80);break;case 2:write_1602com(er+4); //按2次fen位置显示光标//er+0x06//write_1602com(0x0f);break;case 3:write_1602com(er+1); //按动3次,shi//write_1602com(0x0f);break;// case 4: write_1602com(yh+0x0e);//按动4次,week//write_1602com(0x0f);// break;case 4: write_1602com(yh+0x0a);//按动4次,ri//write_1602com(0x0f);break;case 5: write_1602com(yh+0x07);//按动5次,yue//write_1602com(0x0f);break;case 6: write_1602com(yh+0x04);//按动6次,nian//write_1602com(0x0f);break;case 0:write_1602com(0x0c);//按动到第7次,设置光标不闪烁TR0=1;//打开定时器temp=(miao)/10*16+(miao)%10;write_1302(0x8e,0x00);write_1302(0x80,0x00|temp);//miao数据写入DS1302write_1302(0x8e,0x80);break;}}}}}//------------------------------加键add----------------------------if((setn!=0)&&(setNZn==0))//当set按下以下。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//sbit beep=P3^3;
uint temp;
float f_temp;
uint warn_l1=270;
uint warn_l2=250;
uint warn_h1=300;
uint warn_h2=320;
uint get_temp();
void delayms(uint x);
void write_com(uchar com);
该程序为51单片机c语言电子万年历
#include"reg52.h"
//#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit DATA=P0^7;
void DisplayYear(uchar x);
void DisplayWeek(uchar x);
void dis_temp(uint t);
void read_date(void);
void turn_val(char newval,uchar flag,
uchar newaddr,uchar s1num);
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x85);
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x87);
write_data(' ');
dis_temp(get_temp());
}
void DisSecond(uchar x)
{
uchar i,j;
ReadValue = ReadSet1302(0x81);
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
WriteSet1302(0x8c,((14/10)<<4|(14%10))); //nian
//WriteSet1302(0x8a,((4/10)<<4|(4%10)));
}
/////////////////////////////////////////////////////////////////
write_data(j+0x30);
write_com(0x88);
write_data('/');
}
void DisplayYear(uchax/10;
j=x%10;
write_com(0x81);
write_data(2+0x30);
write_com(0x82);
write_data(i+0x30);
write_com(0x8a);
write_data(j+0x30);
}
void DisplayMonth(uchar x)
{
uchar i,j;
i=x/10;
j=x%10;
write_com(0x86);
write_data(i+0x30);
write_com(0x87);
{
write_data(table2[x]);
x++;
}
}
void read_date(void)
{
ReadValue = ReadSet1302(0x81);
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = ReadSet1302(0x83);
void Write1302(uchar dat)
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delayms(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302
year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
write_data(i+0x30);
write_com(0x80+0x44);
write_data(j+0x30);
write_com(0x80+0x45);
write_data(':');
}
void DisplayHour(uchar x)
{
uchar i,j;
i=x/10;
j=x%10;
write_com(0x80+0x40);
sbit RST=P0^5;
sbit SCLK=P0^6;
sbit menu=P3^0; //菜单
sbit add=P3^1; //加一
sbit dec=P3^7; //减一
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit ds=P3^2;
void write_data(uchar date);
void init();
void dis_temp(uint t);
void Write1302(uchar dat);
void WriteSet1302(uchar Cmd,uchar dat);
uchar Read1302(void);
uchar ReadSet1302(uchar Cmd);
write_data(0+0x30);
write_com(0x83);
write_data(i+0x30);
write_com(0x84);
write_data(j+0x30);
write_com(0x85);
write_data('/');
}
void DisplayWeek(uchar x)
{ uchar i;
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delayms(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delayms(2); //稍微等待
}
return dat; //将读出的数据返回
}
uchar ReadSet1302(uchar Cmd)
uchar ReadValue,num,time;
void delayms(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
////////////////////////////////////////////////////////////
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delayms(2); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
}
void Init_DS1302(void)
{
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值
delayms(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delayms(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
void WriteSet1302(uchar Cmd,uchar dat)
lcden=0;
}
void init()
{
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
/////////////////////////////////////////////////////////////////
void write_com(uchar com)
{
lcdrs=0;
P2=com;
delayms(5);
lcden=1;
delayms(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
P2=date;
delayms(5);
相关文档
最新文档