单片机电子万年历含程序

合集下载

单片机制作的12864液晶万年历_C语言程序

单片机制作的12864液晶万年历_C语言程序

#include<reg52.H>#include<intrins.h>#include<math.h>////////////////////////////////////////DS18B20#define uchar unsigned char#define uint unsigned intsbit DQ = P1 ^ 0; // 定义DS18B20的单总线#define Lcd_Bus P0sbit LCD_RS=P2^7; //数据/命令选择sbit LCD_RW=P2^6; //读写控制sbit LCD_EN=P2^5; //片选信号#define LCD_DA TA P0 //8 bit数据线#define LOW 0#define HIGH 1//初始化指令#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H#define AC_INIT 0x02 //将AC设置为00H。

且游标移到原点位置#define CURSE_ADD 0x06 //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)#define FUN_MODE 0x30 //工作模式:8位基本指令集#define DISPLAY_ON 0x0c //显示开,显示游标,且游标位置反白#define DISPLAY_OFF 0x08 //显示关#define CURSE_DIR 0x14 //游标向右移动:AC=AC+1#define SET_CG_AC 0x40 //设置AC,范围为:00H~3FH#define SET_DD_AC 0x80#define FUN_MODEK 0x36 //扩展指令集,8位指令#define X1address 0x80 //上半屏X轴起始地址#define X2address 0x88 //下半屏X轴起始地址#define Y address 0x80 //Y轴起始地址#define Set_Column 0x40#define Set_Page 0xB8uchar code shu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};uchar code xingqi[]="星期";uchar code hanzishu[]="一二三四五六日";unsigned char TempData = 0;double DS18B20Data;uint jiemian=0;//////////////////////////////////////////DS1302sbit DS1302_RST = P1^4;sbit DS1302_IO = P1^3;sbit DS1302_SCK = P1^2;unsigned char table[]={0X00,0X18,0X0c,0X15,0X06,0X01,0X0a};//0s 24min 12hour 14ri 5yue 5zhou 2010nianunsigned char data table1[7];//uchar code table2[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};uchar code shuzi[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,};unsigned char aa,bb;uchar miaoge,miaoshi,fenge,fenshi,shige,shishi,rige,rishi,yuege,yueshi,zhou,niange,nianshi;uchar shezhinum=0;//unsigned char shi,ge;////////////////////////////////////////////////键盘扫描sbit key_mnue = P3^7;sbit key_jia = P2^0;sbit key_jian = P2^1;sbit key_enter= P2^2;uchar key_number=0;//int nian,yue,ri,shi,fen;/////////////////////////////////////////////////红外sbit HW_IRQ = P3 ^ 2; // 定义38KHz一体化红外接收头与CPU的连接unsigned char DT;static unsigned char data IRCode[3],IRCON,IRCON2;//////////////////////////////////////////////////蜂鸣器sbit BEEP =P1^1;/****************************************************************************** *************** 函数名称:DS18B20_Delay()* 功能:DS18B20软件延时专用* 入口参数:count 延时参数,值越大,延时越长* 出口参数:无******************************************************************************* **************/void DS18B20_Delay(uint count) //延时函数{while(count--);}/****************************************************************************** *************** 函数名称:DS18B20_Init()* 功能:DS18B20初始化* 入口参数:无* 出口参数:返回值为1则初始化成功* 返回值为0则初始化失败******************************************************************************* **************/uchar DS18B20_Init(void){uchar x = 0;DQ = 1; // DQ复位DS18B20_Delay(8); // 稍做延时DQ = 0; // 单片机将DQ拉低DS18B20_Delay(80); // 精确延时,大于480usDQ = 1; // 拉高总线DS18B20_Delay(14); // 稍做延时后x = DQ; // 若x=0则初始化成功,若x=1则初始化失败DS18B20_Delay(20);return (~x);}/****************************************************************************** *************** 函数名称:DS18B20_Read1Byte()* 功能:从DS18B20读一个字节* 入口参数:无* 出口参数:从DS18B20读出的一个字节******************************************************************************* **************/uchar DS18B20_Read1Byte(void){uchar i = 0;uchar dat = 0;for(i=8;i>0;i--){DQ = 0; // 给脉冲信号dat >>= 1;DQ = 1; // 给脉冲信号if(DQ) dat |= 0x80;DS18B20_Delay(4);}return (dat);}/****************************************************************************** *************** 函数名称:DS18B20_Write1Byte()* 功能:向DS18B20写一个字节* 入口参数:dat 要写入DS18B20的一字节数据* 出口参数:无******************************************************************************* **************/void DS18B20_Write1Byte(uchar dat){uchar i = 0;for(i=8;i>0;i--){DQ = 0;DQ = dat&0x01;DS18B20_Delay(5);DQ = 1;dat>>=1;}}/****************************************************************************** *************** 函数名称:Read_Disp_Temperature()* 功能:读取并显示温度* 入口参数:无* 出口参数:无******************************************************************************* **************/double Read_Disp_Temperature(void){uint a = 0, b = 0, c = 0,d = 0,e = 0, t = 0;double tt = 0;DS18B20_Init();DS18B20_Write1Byte(0xCC); // 跳过读序号列号的操作DS18B20_Write1Byte(0x44); // 启动温度转换DS18B20_Init();DS18B20_Write1Byte(0xCC); // 跳过读序号列号的操作DS18B20_Write1Byte(0xBE); // 读取温度寄存器a = DS18B20_Read1Byte();b = DS18B20_Read1Byte();t = b;t <<= 8;t = t | a;//tt = t * 0.0625;return t;}//***************************************************************** //函数名称:delay(uint t)延时函数。

单片机万年历温度检测C程序(1302+1820+1602+51)

单片机万年历温度检测C程序(1302+1820+1602+51)

1302+1820+1602+51万年历#include<reg51.H>#include<INTRINS.H>#define uchar unsigned char#define uint unsigned int#define TIME (0X10000-50000)#define FLAG 0XEF //闹钟标志//引脚连接图sbit rst=P3^5;sbit clk=P3^4;sbit io=P3^3;sbit rs=P1^5;sbit rw=P1^6;sbit e=P1^7;sbit DQ=P1^4; //温度输入口sbit beep=P3^2;sbit ACC_7=ACC^7;//全局变量及常量定义uchar i=20,j,time1[16];uchar alarm[2],time2[15],time[3];uchar code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12个月的最大日期(非闰年)//音律表uint code table1[]={64260,64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217};//发声部分的延时时间uchar code table2[]={0x82,1,0x81,0xf4,0xd4,0xb4,0xa4,0x94,0xe2,1,0xe1,0xd4,0xb4,0xc4,0xb4,4,0};//LCD自建字uchar code tab[]={0x18,0x1b,5,4,4,5,3,0,0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02,//年0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,//月0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00};//日//*******温度小数部分用查表法**********//uchar codeditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x0 7,0x08,0x08,0x09,0x09};//闹钟中用的全局变量uchar th1,tl1;uchar temp_ioa[2]={0x00,0x00}; // 读出温度暂放bit flag; //18b20存在标志位/***********11微秒延时函数**********/delay(uint t){for(;t>0;t--);}/***********18B20复位函数**********/ow_reset(void){uchar i;DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66usfor(i=0;i<0x30;i++){if(!DQ)goto d1;}flag=0; //清标志位,表示ds1820不存在DQ=1;return;d1: delay(45); //延时500usflag=1;DQ=1; //置标志位,表示ds1820存在}/**********18B20写命令函数*********///向 1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ=val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ=1;delay(1);}/*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value=0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ=1;_nop_();_nop_();_nop_();_nop_(); //4usif(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}/***********读出温度函数**********/read_temp(){ow_reset(); //总线复位if(!flag) //判断ds1820是否存在?若ds18b20不存在则返回 return;//write_byte(0xCC); // Skip ROM//write_byte(0x44); // 发转换命令//delay(70);write_byte(0xCC); //发Skip ROM命令write_byte(0xBE); //发读命令temp_ioa[0]=read_byte(); //温度低8位temp_ioa[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令}/***********温度数据处理函数**********/work_temp(){uchar n=0,m;if(temp_ioa[1]>127)//负温度求补码{temp_ioa[1]=(256-temp_ioa[1]);temp_ioa[0]=(256-temp_ioa[0]);n=1;}time2[13]=ditab[temp_ioa[0]&0x0f]+'0';time2[12]='.';m=((temp_ioa[0]&0xf0)>>4)|((temp_ioa[1]&0x0f)<<4);// if(n){m-=16;}time2[9]=m/100+'0';time2[11]=m%100;time2[10]=time2[11]/10+'0';time2[11]=time2[11]%10+'0';if(time2[9]=='0')//最高位为0时都不显示{time2[9]=0x20;if(n)//负温度时最高位显示"-"{time2[9]='-';}if(time2[10]=='0'){if(n){time2[10]='-';time2[9]=0x20;}elsetime2[10]=0x20;if(time2[11]=='0'&&time2[13]=='0')time2[11]=time2[12]=0x20;}}}delay1ms(uchar time) //延时1ms{uchar i,j;for(i=0;i<time;i++){for(j=0;j<250;j++);}}//LCD驱动部分enable(){rs=0;rw=0;e=0;delay1ms(3);e=1;}write2(uchar i){P0=i;rs=1;rw=0;e=0;delay1ms(2);e=1;}write1(uchar data *address,m) {uchar i,j;for(i=0;i<m;i++,address++) {j=*address;write2(j);}}//LCD显示lcdshow(){P0=0XC; //显示器开、光标关enable();P0=0x80; //写入显示起始地址enable();write1(time1,16);P0=0xc1; //写入显示起始地址enable();write1(time2,15);}//自建字zijianzi(){uchar i;P0=0x40;enable();for(i=0;i<32;i++){write2(tab[i]);delay1ms(2);}}//DS1302读写子程序write(uchar address){uchar i;clk=0;_nop_();rst=1;_nop_();for(i=0;i<8;i++){io=address&1;_nop_();clk=1;address>>=1;clk=0;}}uchar read(){uchar i,j=0;for(i=0;i<8;i++){j>>=1;_nop_();clk=0;_nop_();if(io)j|=0x80;_nop_();clk=1;}return(j);}//部分显示数据初始化timestart(){time1[1]=time1[13]=time2[8]=time2[9]=time2[10]=0x20,time2[14]=0; time1[6]=1,time1[9]=2,time1[12]=3,time1[2]='2',time1[3]='0'; time1[14]='W',time2[2]=time2[5]=':';write(0xc1);alarm[0]=read();rst=0;write(0xc3);alarm[1]=read();rst=0;write(0xc5);time1[0]=read();rst=0;}//读取时间readtime(){uchar i,m,n;write(0x8d); //读取年份m=read();rst=0;time1[4]=m/16+0x30;time1[5]=m%16+0x30;write(0x8b); //读取星期m=read();rst=0;time1[15]=m+0x30;for(i=7,n=0x89;i<11;i+=3,n-=2) //读取月份和日期{write(n);m=read();rst=0;time1[i]=m/16+0x30;time1[i+1]=m%16+0x30;}for(m=0,i=0,n=0x85;i<7;i+=3,n-=2,m++) //读取时,分,秒{write(n);time[m]=read();rst=0;time2[i]=time[m]/16+0x30;time2[i+1]=time[m]%16+0x30;}}time0() interrupt 1 using 1{i--;if(i==0){if(j!=0)j--;i=20;}TH0=TIME/256,TL0=TIME%256;}//闹钟部分intime1() interrupt 3{TH1=th1,TL1=tl1;beep=!beep;}showalarm(){uchar i,j,a,b,n;ET1=1;for(j=0;j<6;j++){i=0;while(1){a=table2[i];if(a==0)break;b=a&0xf;a>>=4;if(a==0){TR1=0;goto D1;}a=((--a)<<1)/2;TH1=th1=table1[a]/256,TL1=tl1=table1[a]%256; TR1=1;D1: do{b--;for(n=0;n<3;n++){readtime();lcdshow();P2=0xf7;if(P2==0xe7){delay1ms(100);if(P2==0xe7){TR1=0;ET1=0;return;}}}}while(b!=0);i++;}TR1=0;}ET1=0;}//根据日期的变动自动调整星期uchar setweek(){uchar i=5,j,n;j=(time1[4]&0xf)*10+(time1[5]&0xf); n=j/4;i=i+5*n;n=j%4;if(n==1)i+=2;else if(n==2)i+=3;else if(n==3)i+=4;j=(time1[7]&0xf)*10+(time1[8]&0xf); if(j==2)i+=3;else if(j==3)i+=3;else if(j==4)i+=6;else if(j==5)i+=1;else if(j==6)i+=4;else if(j==7)i+=6;else if(j==8)i+=2;else if(j==9)i+=5;else if(j==11)i+=3;else if(j==12)i+=5;if(n==0)if(j>2)i++;j=(time1[10]&0xf)*10+(time1[11]&0xf);i+=j;i%=7;if(i==0)i=7;return(i);}//设置时间settime(){uchar i=0x85,year,month,day,n;time2[6]=time2[7]=0x30,time1[14]=time1[15]=0x20; lcdshow();while(1){P0=0xe; //显示器开、光标开enable();P0=i; //定光标enable();P2=0xf7;if(P2!=0XF7){delay1ms(100); //延时0.1s去抖动if(P2!=0XF7){j=7;if(P2==0X77){i+=3;if(i==0x8e)i=0xc2;else if(i>0xc5)i=0x85;}else if(P2==0xb7){year=(time1[4]&0xf)*10+(time1[5]&0xf); month=(time1[7]&0xf)*10+(time1[8]&0xf); day=(time1[10]&0xf)*10+(time1[11]&0xf); if(i==0x85){year++;if(year>99)year=0;if((year%4)!=0)if(month==2&&day==29)day=28;}else if(i==0x88){month++;if(month>12)month=1;if(day>Day[month-1]){day=Day[month-1];if(month==2&&(year%4)==0)day=29;}}else if(i==0x8b){day++;if(day>Day[month-1]){if(month==2&&(year%4)==0){if(day>29)day=1;}if(month!=2)day=1;}}else if(i==0xc2){n=(time2[0]&0xf)*10+(time2[1]&0xf);n++;if(n>23)n=0;time2[0]=n/10+0x30;time2[1]=n%10+0x30;}else{n=(time2[3]&0xf)*10+(time2[4]&0xf);n++;if(n>59)n=0;time2[3]=n/10+0x30;time2[4]=n%10+0x30;}time1[4]=year/10+0x30;time1[5]=year%10+0x30;time1[7]=month/10+0x30;time1[8]=month%10+0x30;time1[10]=day/10+0x30;time1[11]=day%10+0x30;lcdshow();}else if(P2==0xd7){write(0x8c);write((time1[4]&0xf)*16+(time1[5]&0xf));rst=0;write(0x8a);write(setweek());rst=0;for(i=7,n=0x88;i<11;i+=3,n-=2){write(n);write((time1[i]&0xf)*16+(time1[i+1]&0xf)); rst=0;}for(i=0;i<7;i+=3,n-=2){write(n);write((time2[i]&0xf)*16+(time2[i+1]&0xf)); rst=0;}TR0=0;time1[14]='W';return;}else{TR0=0;time1[14]='W';return;}}}if(j==0){TR0=0;time1[14]='W';return;}}}//设置闹钟setalarm(){uchar i,n;for(i=1;i<16;i++){time1[i]=0x20;}time2[0]=alarm[0]/16+0x30;time2[1]=(alarm[0]&0xf)+0x30;time2[3]=alarm[1]/16+0x30;time2[4]=(alarm[1]&0xf)+0x30;time2[6]=time2[7]=0x30;lcdshow();i=0xc2;while(1){P0=0xe; //显示器开、光标开enable();P0=i; //定光标enable();P2=0xf7;if(P2!=0XF7){delay1ms(100); //延时0.1s去抖动 if(P2!=0XF7){j=7;if(P2==0X77){i+=3;if(i>0xc5)i=0xc2;}else if(P2==0xb7){if(i==0xc2){n=(time2[0]&0xf)*10+(time2[1]&0xf);n++;if(n>23)n=0;time2[0]=n/10+0x30;time2[1]=n%10+0x30;}else{n=(time2[3]&0xf)*10+(time2[4]&0xf);n++;if(n>59)n=0;time2[3]=n/10+0x30;time2[4]=n%10+0x30;}lcdshow();}else if(P2==0xd7){write(0xc0);write((time2[0]&0xf)*16+(time2[1]&0xf)); rst=0;write(0xc2);write((time2[3]&0xf)*16+(time2[4]&0xf)); rst=0;time1[0]=FLAG;write(0xc4);write(time1[0]);rst=0;TR0=0;timestart();return;}else{TR0=0;timestart();return;}}}if(j==0){TR0=0;timestart();return;}}}main(){IE=0X82;TMOD=0x11;write(0x8E); //禁止写保护write(0);rst=0;P0=1; //清屏并光标复位enable();P0=0X38; //设置显示模式:8位2行5x7点阵enable();P0=6; //文字不动,光标自动右移enable();zijianzi(); //自建字timestart();while(1){readtime(); //读取时间read_temp(); //读出18B20温度数据 work_temp(); //处理温度数据lcdshow(); //显示时间if(time1[0]!=0x20)if(time[0]==alarm[0])if(time[1]==alarm[1])if(time[2]==0)showalarm();P2=0xf7;if((P2&0XF0)!=0XF0){delay1ms(100); //延时0.1s去抖动 if((P2&0XF0)!=0XF0){j=7;TH0=TIME/256,TL0=TIME%256;TR0=1;if(P2==0x77){settime();}else if(P2==0XB7){setalarm();}else if(P2==0XD7){TR0=0;if(time1[0]==FLAG)time1[0]=0x20;elsetime1[0]=FLAG;write(0xc4);write(time1[0]);rst=0;}}}delay1ms(100);}}单片机万年历——基于1302和1602(1篇)2009-12-06 21:191302和1602的接法在我相册里面使用1602液晶显示DS1302+c51时钟[注12M晶振]=============================================================*/#include <AT89x52.h>#include <string.h>#include < intrins.h >#define delayNOP() ; {_nop_() ;_nop_() ;_nop_() ;_nop_() ;} ;#define LCM_RW P3_1 //定义引脚#define LCM_RS P3_0#define LCM_E P3_2#define LCM_Data P0#define Busy 0x80 //用于检测LCM状态字中的Busy标识#define uchar unsigned charsbit T_CLK=P2^4;sbit T_IO =P2^5;sbit T_RST=P2^6;sbit ACC0=ACC^0;sbit ACC7=ACC^7;sbit system=P1^1; //模式sbit TimerUp=P1^2; //时间加sbit TimerDown=P1^0; //时间减sbit Speaker=P2^1; //蜂鸣器void Set(uchar,uchar); //根据选择调整相应项目void RTInputByte(uchar); //输入 1Byte */uchar RTOutputByte(void); //输出 1Byte */void W1302(uchar, uchar); //向DS1302写入一个字节uchar R1302(uchar); //从DS1302读出一个字节void Set1302(uchar * ); //设置时间void KeySound(); //按键音void ClockSound(); //闹铃蜂鸣声uchar id,msec,model,LedTime,d;bit a,b; //闪烁标志位uchar inittime[7]={0x00,0x10,0x19,0x29,0x03,0x04,0x06}; //初始化后设置为:06年3月29日星期3 19点10分0秒void Out_LCM(void); //显示屏幕void model0(void); //显示输出void model1(void);void model2(void);void model3(void);void model4(void);void model5(void);void model6(void);void id_case1_key(); //项目调整void Modset(); //模式键处理void WriteDataLCM(uchar WDLCM);void WriteCommandLCM(uchar WCLCM,BuysC);uchar ReadStatusLCM(void);void LCMInit(void);void OutputInformation(uchar X, uchar Y, uchar DData);void DisplayListChar(uchar X, uchar Y, uchar code *DData);void Delay5Ms(void);void Delay400Ms(void);void systemsetup(void); //进入系统设置uchar code systemp[]={"System.setup"}; //字符串输出(系统设定)uchar code TIMER[]={"Time"}; //字符串输出(时间)uchar code DATE[]={"Date"}; //字符串输出(日期)uchar code alarmclock[]={"Clock"}; //字符串输出(闹铃)uchar code lamp[]={"Lamp"}; //字符串输出(背光灯)uchar code reset[]={"Reset"}; //字符串输出(时间归零)uchar code exit[]={"Exit"}; //字符串输出(退出)uchar code set[]={"Set"}; //字符串输出(设置)uchar code sec[]={"sec"}; //字符串输出(秒)uchar code ClockSet[]={"ClockSet"}; //字符串输出(闹铃设置)uchar code ClockOn[]={"ON"}; //字符串输出(ON)uchar code ClockOff[]={"OFF"}; //字符串输出(OFF)void timesetup(void); //时间设置void datesetup(void); //日期设置void alarmclockset(void); //闹铃设置void lampsetup(void); //背光灯设置void timereset(void); //时间清零/*******************************************************************/ void delay1(int ms){unsigned char y ;while(ms--){for(y = 0 ; y<250 ; y++){_nop_() ;_nop_() ;_nop_() ;_nop_() ;}}}void main(void){Speaker=1; //关闭蜂鸣器LED=0; //打开LED ,低电平有效,外接9012驱动Delay400Ms(); //启动等待,等LCM讲入工作状态Delay400Ms();LCMInit(); //LCM初始化TMOD=0x01; //16位定时TH0=0x3c; //50msTL0=0xb0;EA=1;TR0=1;ET0=1;while(1){if(TimerDown==0) //左移键按下后把背光灯打开{Delay5Ms();if(TimerDown==0){KeySound(); //蜂鸣声LED=0; //打开背光灯LedTime=R1302(0xc1)/16*10+R1302(0xc1)%16;} //取出背光灯时间并转换为十进制数}b=1; //模式键是否动作标志。

单片机制作数字钟(含万年历、秒表功能)

单片机制作数字钟(含万年历、秒表功能)

数字钟、万年历制作(基于单片机)电路原理图:程序://********************20131206****数字钟程序#pragma SMALL#include <reg51.h>#include <absacc.h>#include <intrins.h>//********************************************************* *********编译预处理void display(unsigned char *p); //显示函数,P为显示数据首地址unsigned char keytest(); //按键检测函数unsigned char search(); //按键识别函数void alarm(); //闹钟判断启动函数void ftion0(); //始终修改函数void ftion1(); //闹钟修改函数void ftion3(); //日期修改函数void cum(); //加1修改函数void minus(); //减1修改函数void jinzhi(); //进制修改函数void riqi(); //日期void stopwatch(); //秒表函数//********************************************************* *******函数声明sbit P2_7=P2^7;//********************************************************* *******端口定义unsigned char clockbuf[3]={0,0,0};unsigned char bellbuf[3]={0,0,0};unsigned char date[3]={1,1,1}; //日期存放数组unsigned char stop[3]={0,0,0};unsigned char msec1,msec2;unsigned char timdata,rtimdata,dtimdata;unsigned char count;unsigned char *dis_p;unsigned char or; //12进制控制标志unsigned char ri; //日期显示控制标志位unsigned char mb; //秒表控制标志位bit arm,rtim,rhour,rmin,hour,min,sec,day,mon,year; //定义位变量//********************************************************* *****全局变量定义void main(){unsigned char a;or=0; //12进制修改标志清零ri=0;mb=0;P2_7=0;arm=0;msec1=0;msec2=0;timdata=0;rtimdata=0;count=0;TMOD=0x12;TL0=0x06;TH0=0x06;TH1=(65536-10000)/256;TL1=(65536-10000)%256;EA=1;ET0=1;ET1=1;TR0=1;TR1=0;dis_p=clockbuf;while(1){a=keytest();if(a==0x78) //判断是否有键按下{display(dis_p);if(arm==1) alarm();}else{display(dis_p);a=keytest();if(a!=0x78){a=search();switch(a){case 0x00:ftion0();break;case 0x01:ftion1();break;case 0x02:cum();break;case 0x06:jinzhi();break;case 0x03:riqi();break;case 0x04:ftion3();break;case 0x05:minus();break;case 0x07:stopwatch();break;case 0x09:TR1=1;break;case 0x0a:TR1=0;break;case 0x0b:stop[0]=0;stop[1]=0;stop[2]=0;break;default:break;}}}}}//********************************************主函数【完】void display(unsigned char *p){unsigned char buffer[]={0,0,0,0,0,0};unsigned char k,i,j,m,temp;unsigned char led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};buffer[0]=p[0]/10;buffer[1]=p[0]%10;buffer[2]=p[1]/10;buffer[3]=p[1]%10;buffer[4]=p[2]/10;buffer[5]=p[2]%10;if((sec==0)&&(min==0)&&(hour==0)&&(rmin==0)&&(rhour==0)&&( day==0)&&(mon==0)&&(year==0)) //没有修改标志,正常显示{for(k=0;k<3;k++){temp=0x01;for(i=0;i<6;i++){P0=0x00; //段选端口j=buffer[i];P0=led[j];P1=~temp; //位选端口temp<<=1;for(m=0;m<200;m++);}}}else //若有修改标志,则按以下标志分别显示{if(sec==1||day==1){P1=0x1f;i=buffer[5];P0=led[i];for(m=0;m<200;m++);P1=0x2f;j=buffer[4];P0=led[j];for(m=0;m<200;m++);}if(min==1||rmin==1||mon==1){P1=0x3b;i=buffer[2];P0=led[i];for(m=0;m<200;m++);P1=0x37;j=buffer[3];P0=led[j];for(m=0;m<200;m++);}if(hour==1||rhour==1||year==1) {P1=0x3e;i=buffer[0];P0=led[i];for(m=0;m<200;m++);P1=0x3d;j=buffer[1];P0=led[j];for(m=0;m<200;m++);}}}//**********************************LED显示函数【完】unsigned char keytest(){unsigned char c;P2=0x78; //检测是否有键按下c=P2;c=c&0x78;return(c);}//******************************************键盘检测函数【完】unsigned char search(){unsigned char a,b,c,d,e;c=0x3f;a=0; //行号while(1){P2=c;d=P2;d=d&0x07;if(d==0x03){b=0;break;} //列号else if(d==0x05){b=1;break;}else if(d==0x06){b=2;break;}a++;c>>=1;if(a==5){a=0;c=0x3f;}}e=a*3+b;do{display(dis_p);}while((d=keytest())!=0x78);return(e);}//***********************************************查键值函数【完】void alarm(){if((clockbuf[0]==bellbuf[0])&&(clockbuf[1]==bellbuf[1])){P2_7=1;rtim=1;if(count==10){count=0;P2_7=0;arm=0;rtim=0;}}}//****************************************闹钟判断启动函数【完】void ftion0(){TR0=0;rhour=0;rmin=0;dis_p=clockbuf;rtimdata=0;timdata++;switch(timdata){case 0x01:sec=1;break;case 0x02:sec=0;min=1;break;case 0x03:min=0;hour=1;break;case 0x04:timdata=0;hour=0;TR0=1;break;default:break;}}//*********************************************时钟设置函数【完】void ftion1(){if(TR0==0) TR0=1;sec=0;min=0;hour=0;dis_p=bellbuf;timdata=0;rtimdata++;switch(rtimdata){case 0x01:rmin=1;break;case 0x02:rmin=0;rhour=1;break;case 0x03:rtimdata=0;rhour=0;arm=1;dis_p=clockbuf;break;default:break;}}//*********************************************闹钟设置函数【完】void ftion3(){if(TR0==0) TR0=1;day=0;mon=0;year=0;dis_p=date;timdata=0;rtimdata=0;dtimdata++;switch(dtimdata){case 0x01:day=1;break;case 0x02:day=0;mon=1;break;case 0x03:mon=0;year=1;break;case 0x04:dtimdata=0;year=0;dis_p=clockbuf;break;default:break;}}//*************************************************日期修改函数【完】void minus(){if(sec==1){if(0==clockbuf[2]) clockbuf[2]=59;else clockbuf[2]--;}else if(min==1){if(0==clockbuf[1]) clockbuf[1]=59;else clockbuf[1]--;}else if(hour==1){if(or==0) //判断进制{if(0==clockbuf[0]) clockbuf[0]=23;else clockbuf[0]--;}if(or==1){if(1==clockbuf[0]) clockbuf[0]=12;else clockbuf[0]--;}}else if(rmin==1){if(bellbuf[1]==0) bellbuf[1]=59;else bellbuf[1]--;}else if(rhour==1){if(or==0){if(bellbuf[0]==0) bellbuf[0]=23;else bellbuf[0]--;}if(or==1){if(bellbuf[0]==1) bellbuf[0]=12;else bellbuf[0]--;}}else if(day==1){if(date[2]==1) date[2]=31;else date[2]--;}else if(mon==1){if(date[1]==1) date[1]=12;else date[1]--;}else if(year==1){if(date[0]==1) date[0]=99;else date[0]--;}}//*************************************减1修改功能函数【完】void cum(){if(sec==1){if(59==clockbuf[2]) clockbuf[2]=0;else clockbuf[2]++;}else if(min==1){if(59==clockbuf[1]) clockbuf[1]=0;else clockbuf[1]++;}else if(hour==1){if(or==0) //判断进制{if(23==clockbuf[0]) clockbuf[0]=0;else clockbuf[0]++;}if(or==1){if(12==clockbuf[0]) clockbuf[0]=1;else clockbuf[0]++;}}else if(rmin==1){if(bellbuf[1]==59) bellbuf[1]=0;else bellbuf[1]++;}else if(rhour==1){if(or==0){if(bellbuf[0]==23) bellbuf[0]=0;else bellbuf[0]++;}if(or==1){if(bellbuf[0]==12) bellbuf[0]=1;else bellbuf[0]++;}}else if(day==1){if(date[2]==31) date[2]=1;else date[2]++;}else if(mon==1){if(date[1]==12) date[1]=1;else date[1]++;}else if(year==1){if(date[0]==99) date[0]=0;else date[0]++;}}//*************************************加1修改功能函数【完】void jinzhi(){if(or==0) or=1;else or=0;}//***********************************进制修改控制函数【完】void riqi(){if(ri==0){dis_p=date;}if(ri==1){dis_p=clockbuf;}ri++;if(ri==2) ri=0;}//********************************日期控显示函数【完】void stopwatch(){if(mb==0){dis_p=stop;mb=1;}else{mb=0;dis_p=clockbuf;}}//************秒表**********秒表**********秒表函数【完】void clock() interrupt 1{EA=0;if(msec1!=0x14) msec1++; //6MHz晶振定时10mselse{msec1=0;if(msec2!=100) msec2++; //定时1selse{if(rtim==1) count++; //闹钟启动标志计时10smsec2=0;if(clockbuf[2]!=59) clockbuf[2]++;else{clockbuf[2]=0;if(clockbuf[1]!=59) clockbuf[1]++;else{clockbuf[1]=0;if(or==0){if(clockbuf[0]!=23) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}if(or==1){if(clockbuf[0]!=12) clockbuf[0]++;else{clockbuf[0]=0;if((date[1]==1)||(date[1]==1)||(date[1]==1)||(date[1]==3)||(date[ 1]==5)||(date[1]==7)||(date[1]==8)||(date[1]==10)||(date[1]==12)){if(date[2]!=30) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if((date[1]==4)||(date[1]==6)||(date[1]==9)||(date[1]==11)){if(date[2]!=29) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}if(date[1]==2){if((((date[0]%4==0)&&(date[0]%100!=0))||(date[0]%400==0))){if(date[2]!=28) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}else{if(date[2]!=27) date[2]++;else{date[2]=1;if(date[1]!=11) date[1]++;else{date[1]=1;date[0]++;}}}}}}}}}}EA=1;}//*******************************定时器0中断函数【完】void miaobiao() interrupt 3{TH1=(65536-10000)/256;TL1=(65536-10000)%256;if(stop[2]!=99) stop[2]++;else{stop[2]=0;if(stop[1]!=59) stop[1]++;else{stop[1]=0;if(stop[0]!=59) stop[0]++;else stop[0]=0;}}}//***********************************定时器1中断函数【完】。

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("简洁界面");}。

单片机万年历程序带农历和闹钟

单片机万年历程序带农历和闹钟

#include < character.h >#include < lcd.h >#include < clock.h >#include < sensor.h>#include < calendar.h >#include < key.h >/*****************************预概念**************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************/ sbit bell = P2 ^ 0; //概念蜂鸣器端口sbit in = P2 ^ 7; //概念红外检测端口/***************************************************************************** * 名称: Timer0_Service() inturrupt 1* 功能: 中断效劳程序整点报时3声嘟嘟的声音* 入口参数:* 出口参数:*****************************************************************************/ void Timer0_Service() interrupt 1{static uchar count = 0;static uchar flag = 0; //记录鸣叫的次数count = 0;TR0 = 0; //关闭Timer0TH0 = 0x3c;TL0 = 0XB0; //延时50 msTR0 = 1 ; //启动Timer0count ++;if( count == 20 ) //鸣叫1 秒{bell = ~ bell;count = 0;flag ++;}if( flag == 6 ){flag = 0;TR0 = 0; //关闭Timer0}}/****************************************************************************** 名称: Timer2_Servie() interrupt 5* 功能: 中断效劳程序整点报时一分钟* 入口参数:* 出口参数:*****************************************************************************/ void Timer3_Service() interrupt 5{static uchar count;TF2 = 0; //软件清除中断标志count ++;if( in == 1 ){count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}if( count == 120 ) // 一分钟后关闭报警{count = 0; //计算清0TR2 = 0; //关闭Timer2bell = 1; //关闭蜂鸣器}}/****************************************************************************** * 函数名称:main()* 功能:* 入口参数:* 出口参数:******************************************************************************* */void main( void ){uchar clock_time[7] = { 0x00, 0x17, 0x12, 0x14, 0x12, 0x08 }; //概念时刻变量秒分时日月年uchar alarm_time[2] = { 0, 0}; //闹钟设置alarm_time[0]: 分钟alarm_time[1] :小时uchar temperature[2]; //概念温度变量temperature[0] 低8位temperature[1] 高8位Lcd_Initial(); //LCD初始化Clock_Initial( clock_time ); //时钟初试化/***********************中断初始化***************************/EA = 1; //开总中断ET0 = 1; //Timer0 开中断ET2 = 1; //Timer2 开中断TMOD = 0x01 ; //Timer0 工作方式1RCAP2H = 0x3c;RCAP2L = 0xb0; //Timer2 延时50 mswhile( 1 ){switch( Key_Scan() ){case up_array: //{Key_Idle();}break;case down_array:{Key_Idle();}break;case clear_array:{Key_Idle();}break;case function_array:{Key_Function( clock_time, alarm_time );}case null:{Clock_Fresh( clock_time ); //时刻刷新Lcd_Clock( clock_time ); //时刻显示Sensor_Fresh( temperature ); //温度更新Lcd_Temperture( temperature ); //温度显示Calendar_Convert( 0 , clock_time );Week_Convert( 0, clock_time );//整点报时if( ( * clock_time == 0x59 ) && ( * ( clock_time + 1 ) == 0x59 ) ){bell = 0;TR2 = 1; //启动Timer2}//闹钟报警if( * alarm_time == * ( clock_time + 1 ) ) //分钟相吻合if( * ( alarm_time + 1 ) == *( clock_time + 2 ) ) //小时相吻合{bell = 0;TR2 = 1; //启动Timer2}}break;}}}#ifndef _SUN_MOON#define _SUN_MOON/*************************************************************************/#define uchar unsigned char#define uint unsigned int/****************************************************************************** *** 名称: get_moon_day(uchar month_p,uint table_addr)* 功能: 读取数据表中农历的大月或小月,若是大月返回1, 小月返回0* 入口参数:* 出口参数:******************************************************************************* **/bit get_moon_day( uchar month_p,uint calendar_address ){uchar temp;switch(month_p){case 1: { temp = year_code[calendar_address] & 0x08; if(temp==0) return(0); else return(1); }case 2: { temp = year_code[calendar_address] & 0x04; if(temp==0) return(0); else return(1); }case 3: { temp = year_code[calendar_address] & 0x02; if(temp==0) return(0); else return(1); }case 4: { temp = year_code[calendar_address] & 0x01; if(temp==0) return(0); else return(1); }case 5: { temp = year_code[calendar_address + 1] & 0x80; if(temp==0) return(0); else return(1); }case 6: { temp = year_code[calendar_address + 1] & 0x40; if(temp==0) return(0); else return(1); }case 7: { temp = year_code[calendar_address + 1] & 0x20; if(temp==0) return(0); else return(1); }case 8: { temp = year_code[calendar_address + 1] & 0x10; if(temp==0) return(0); else return(1); }case 9: { temp = year_code[calendar_address + 1] & 0x08; if(temp==0) return(0); else return(1); }case 10: { temp = year_code[calendar_address + 1] & 0x04; if(temp==0) return(0); else return(1); }case 11: { temp = year_code[calendar_address + 1] & 0x02; if(temp==0) return(0); else return(1); }case 12: { temp = year_code[calendar_address + 1] & 0x01; if(temp==0) return(0); else return(1); }case 13: { temp = year_code[calendar_address + 2] & 0x80; if(temp==0) return(0); else return(1); }}}/*************************************************************************** 名称: void Calendar_Convert( uchar * clock_time )* 功能: 输入BCD的阳历数据,输出BCD阴历数据( 1901 - 2099 )* 入口参数: c_flag:阳历的世纪标志clock_time: 时钟地址* 出口参数: 无* 说明: c_flag = 0 :21世纪c_flag = 1 :19世纪*****************************************************************************/ void Calendar_Convert( uchar c_flag, uchar * clock_time ){bit flag_month, flag_year;uchar year, month, day, month_point; //概念年月天uchar temp1, temp2, temp3;uint calendar_address; //概念农历地址uint day_number;uchar clock_moon[3]; //概念阴历clock_time += 3; //指向日day = ( * clock_time >> 4 ) * 10 + ( *clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向月month = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制clock_time ++; //指向年year = ( * clock_time >> 4 ) * 10 + ( * clock_time & 0x0f ); //BCD转换十进制//定位日历地址if( c_flag == 0 )calendar_address = ( year + 99 ) * 3;elsecalendar_address = ( year - 1 ) * 3;//春节(正月初一)所在的阳历月份temp1 = year_code[ calendar_address + 2 ] & 0x60; //Bit6~~Bit5:春节所在的阳历月份temp1 >>= 5 ;//春节(正月初一)所在的阳历日期temp2 = year_code[ calendar_address + 2 ] & 0x1f; //Bit4~~Bit0:春节所在的阳历日期//计算春节(正月初一)离昔时元旦{ 1月1日(阳历) }的天数;春节只会在阳历的1月或2月if( temp1 == 1 )temp3 = temp2 - 1;elsetemp3 = temp2 + 31 - 1;//计算阳历月离昔时元旦{ 1月1日(阳历) }的天数if( month < 10 )day_number = day_code1[ month - 1 ] + day - 1;elseday_number = day_code2[ month - 10 ] + day - 1;//若是阳历的月大于2 且该年的2月为闰月,天数加1//闰年指的确实是阳历有闰日或阴历有闰月的一年;//阳历四年一闰,在二月加一天,这一天叫做闰日://农历三年一闰,五年两闰,十九年七闰,每逢闰年所加的一个月叫做闰月。

单片机万年历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单片机万年历汇编程序 2

51单片机万年历汇编程序 2

;真正的万年历: 84 bytes 的51 ASM;==SUB_WNL=== 万年历==* Deng Miao * 2004-06-01 ***** GuangZhou ****** SJ DA TA30H ; 世纪BCD 00 TO 99NH DA TA31H ; 年号BCD 00 TO 99 0000 TO 9999 年YF DA TA32H ; 月份BCD 01 TO 12org 000hMOV SP, #40HMOV SJ, #21H ;2004-05MOV NH, #01HMOV YF, #4HACALL SUB_WNLSJMP $;===============SUB_WNL===================; 入口:; SJ DA TA30H ; 世纪BCD 00 TO 99; NH DA TA31H ; 年号BCD 00 TO 99 0000 TO 9999 年; YF DA TA32H ; 月份BCD 01 TO 12; 出口; ACC -- 本月天数BCD 28 to 31; B -- 本月1日的星期数1 to 6 == 星期1 to 星期6; 0 -- 星期日; 使用: ACC, B, R5, R6; STACK: 3 bytes (不包括调用)ORG 50HSUB_WNL:PUSH PSWMOV A, SJACALL BCD2BIN_MOD4; x 400年: (大周期); =146097天= 7 * 20871 + 0 天; x 100年:; 000年= 7 * 0 + 0 + 1 - 1 1 = 0 * 2 + 1 ****; 100年= 7 * 5217 + 7 + 1 - 2 2 = 1 * 2; 200年= 7 * 10435 + 7 + 1 - 4 4 = 2 * 2; 300年= 7 * 15653 + 7 + 1 - 6 6 = 3 * 2; {1,2,4,6}MOV A, R6 ; A=R6= SJ_BIN MOD 4RLC A; A=A*2+C A = {1,2,4,6} ****XRL A, #10000111B ; A = 87H - A; 边界调整MOV R5, A; A = {86H, 85H, 83H, 81H} ; R5: 星期MOV A, NHJZ WNL_1ACALL BCD2BIN_MOD4XCH A, R5SUBB A, R5 ; 0 年; 0 = 0 + 0 + 1 + (-1) ***MOV R5, A单片机日记:WNL_1:MOV A, YFADD A, #(WNL_TAB-$-4)MOVC A, @A+PCMOV R6, ASW AP AACALL WNL_F0; 大年对>=3月调整准备ADDC A, R5 ; 月调整MOV B, #7DIV AB ; B = A MOD 7MOV A, R6ACALL WNL_F0; 大年调整准备ADDC A, #28POP PSWRETWNL_TAB:DB 3*2 + 5 * 32+0 ;1 BIT 0 : "2月" 标志DB 0*2+1+1 * 32+0 ;2 ** BIT 1..2: 月大小DB 3*2 + 1 * 32+16 ;3 00:28 天DB 2*2 + 4 * 32+16 ;4 01:----DB 3*2 + 6 * 32+16 ;5 10: 30 天DB 2*2 + 2 * 32+16 ;6 11: 31 天DB 3*2 + 4 * 32+16 ;7 BIT 3: 0 -----DB 3*2 + 7 * 32+16 ;8 BIT 4: 0: 1/2月DB 2*2 + 3 * 32+16 ;9 1: >=3月WNL_F0: ; 6 BYTES ; 大年调整准备RRC A;0AHANL A, #07H ;0BH;0CHANL C, F0 ;0DH;0EHRET ;0FHDB 3*2 + 5 * 32+16 ;10H BIT 5..7: 星期调整数DB 2*2 + 1 * 32+16 ;11H 0:---DB 3*2 + 3 * 32+16 ;12H 1-7: 调整数BCD2BIN_MOD4:; 功能:A. 1 BYTES BCD TO BIN; B. MOD 4; C. MUL 2; 入口:; A: SJ OR NH; F0 : 大世纪; 出口; ACC -- (BIN(A) \ 4) * 2 - (BIN(A) MOD 4) - F0; R6 -- BIN(A) MOD 4; C -- IIF( (BIN(A) MOD 4)=0, 1, 0 ); 使用: ACC, B, R6, PSW; STACK: 0 bytes (不包括调用)MOV R6, A; BCD ==> BINANL A, #0F0H ; 16X+Y ==> 10X+YSW AP AMOV B, #(256-6) ; (256-6)*X + (16X+Y)MUL AB ;ADD A, R6 ; = 256X + (10X+Y)MOV R6, A; MOD4ANL A, #3XCH A, R6 ; R6 = BIN MOD 4 = {0,1,2,3}; X 4年:3 * 365 + 366 = 7*209 + (-2) ** XRL A, R6 ; A = (BIN \ 4)RR A; A = (BIN \4 ) * 2 **MOV C, F0 ; 大世纪调整SUBB A, R6;X 1 年:;0 年0 = 0 + 0 + 1 + (-1) ***;1 年366 = 7*52 + 1 + 1;2 年366 + 365 = 7*104 + 2 + 1;3 年366 + 365 + 365 = 7*156+3 + 1; {-1,1,2,3}CJNE R6, #1, $ + 3 ; C = IIF(R6>=1, 0, 1)MOV F0, C ; C=1 为大年/大世纪RET;-----------------------------END ;======== END OF FILE。

单片机万年历程序

单片机万年历程序

#include<reg52.h>#include<INTRINS.H>#include<STDLIB.H>sbit ring=P1^7;sbit key1=P1^0;sbit key2=P1^1;sbit key3=P1^2;sbit key4=P1^3;sbit key5=P1^4;sbit key6=P1^5;sbit key7=P1^6;unsigned int code table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};static int a[10]={0x3f,0x06,0x5B,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};static char c[10]={0x3f,0x06,0x5B,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};static char b[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};static char diapnum[8]={0,};static char doopnum[8]={0,};int fen=0,shi=0,y=0,tian=0;static int xingqi ;void delay(int t){int j,k;for(j=0;j<t;j++)for(k=0;k<240;k++);}idoth( int num){ diapnum[1]=num/10;diapnum[0]=num%10;} //数码管位的分配idoth1( int num){ doopnum[1]=num/10;doopnum[0]=num%10;} //数码管位的分配unsigned int week( unsigned int nian,unsigned int yue,unsigned int ri ) {unsigned int temp;unsigned int x;temp = nian / 4;temp = nian + temp;temp = temp % 0x07;temp = temp + ri-1 + table_week[ yue - 1 ];if( ( nian % 4 == 0 ) && ( yue <3 ) )temp -=1;x=temp%7;if(x==0)x=8;return( x );}itime(){TMOD=0x02;TH0=0xd8;TL0=0xf0;TR0=1;} //定时计数void main(){ unsigned int time_num=0;//8unsigned int time_num1=0;unsigned int time_num2=0;unsigned int kk,gg;unsigned int ri=1,yue=1,nian=10;int g=0, h=1, z=0 ;char flag=0;bit flag_dot=1;itime();while(1){if(TF0)//0{ //1TF0=0;time_num++;}//1if(time_num>=21){ time_num=0; //2flag++;flag_dot=!flag_dot;if(flag_dot){ //3diapnum[2]=0x7f;diapnum[5]=0x7f;doopnum[2]=0x7f;doopnum[5]=0x7f; //第五位第二位亮} //3else{ //4diapnum[2]=0xff;diapnum[5]=0xff;doopnum[2]=0xff;doopnum[5]=0xff; } //4} //2if(flag>=60){flag=0; //5time_num1++;if(time_num1>=60){ //6time_num1=0;time_num2++;if(time_num2>=24){ //7time_num2=0;ri++;if(ri>=31){yue++;ri=0;{if((nian%4==1)&& (ri==28)) { yue++;ri=0;}else if((nian%4==0)&&(ri==29)) {yue++;ri=0; }{if(ri>31)yue++;ri=0;{if(ri>30)yue++;ri=0;{if(ri>31)yue++;ri=0;{if(ri>30)yue++;ri=0;{if(ri>31)yue++;ri=0;{if(ri>30)yue++;ri=0;{if(ri>30)yue++;ri=0;{ if(ri>31)yue++;ri=0;{ if(ri>30)yue++;ri=0;{if(ri>31)yue++;ri=0;} //7{if(yue>12)nian++;} }}}}}} }}} } } }} //6} //5idoth(time_num2);diapnum[7]=diapnum[1];diapnum[6]=diapnum[0];idoth(time_num1);diapnum[4]=diapnum[1];diapnum[3]=diapnum[0];idoth(flag); //十分秒idoth1(nian);doopnum[7]=doopnum[1];doopnum[6]=doopnum[0];idoth1(yue);doopnum[4]=doopnum[1];doopnum[3]=doopnum[0];idoth1(ri); //年月日xingqi=week( nian,yue,ri) ;if( time_num2==0&&time_num1==10) { ring=~ring ;}if(key1==0){ delay(50) ; fen++ ;time_num1=fen;if(fen==60) fen=0;}if(key2==0){ delay(50) ; shi++ ;time_num2=shi ; } if(key5==0){ delay(50) ;if(fen!=0) fen--;if(shi!=0) shi-- ;if(tian!=0) tian-- ;if(y!=0) yue-- ;}if(key3==0){ delay(50) ; tian++ ;ri=tian;}if(key4==0){delay(50) ; y++ ; yue=y ;if(yue>12) {yue=0; nian++;}}if(key6!=0){ P3=b[7] ; gg=doopnum[0] ; P0=~c[gg] ; kk=diapnum[0] ; P2=~a[kk]; d elay(3) ;P3=b[6] ; kk=diapnum[1] ; P2=~a[kk]; gg=doopnum[1] ; P0=~c[gg] ; delay(3) ;P3=b[5] ; P2 =diapnum[2] ; P0=doopnum[2] ; d elay(3) ;P3=b[4] ; kk=diapnum[3] ; P2=~a[kk]; gg=doopnum[3] ; P0=~c[gg] ; delay(3) ;P3=b[3] ; kk=diapnum[4] ; P2=~a[kk]; gg=doopnum[4] ; P0=~c[gg] ; delay(3) ;P3=b[2] ; P2 =diapnum[5] ; P0=doopnum[5] ; d elay(3) ;P3=b[1] ; kk=diapnum[6] ; P2=~a[kk]; gg=doopnum[6] ; P0=~c[gg] ; delay(3) ;P3=b[0] ; kk=diapnum[7] ; P2=~a[kk]; gg=doopnum[7] ; P0=~c[gg] ; delay(3) ;} //年月日时分秒的显示else {delay(50); P3=b[7] ; P2=~a[xingqi]; P0=0xff ; }}}。

单片机电子万年历(含程序)

单片机电子万年历(含程序)

CHANGZHOU INSTITUTE OF TECHNOLOGY科研实践项目名称:电子万年历设计二级学院:电子信息与电气工程学院专业:电气工程及其自动化班级: 10 电二学生姓名:祝学东学号: 10020442 指导教师:庄志红职称:副教授起止时间: 2013年12月9日—2013年12月20日摘要本设计是电子万年历。

具备三个功能:能显示:年、月、日、时、分、秒、星期,并具有可调整日期和时间功能。

该电子万年历使用12MHZ晶振与单片机AT89C52相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。

利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。

同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。

若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。

若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性,从而使得其成本降低,更适合我们大学生自主研发。

AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。

关键词:单片机数字显示动态扫描时间日期可调目录第一章设计论证及要求 (1)1.1设计应用意义 (1)1.2设计方案论证 (1)1.2.1 单片机芯片选择 (1)1.2.2显示模块选择 (1)1.2.3时钟芯片选择 (2)1.3设计流程 (2)第二章系统硬件电路设计 (3)2.1 CPU时钟 (3)2.2 主控芯片AT89C52模块 (3)2.3 显示控制电路的设计及原理 (4)2.4 按键电路设计 (6)第三章系统软件设计 (7)3.1 软件主流程 (7)3.2初始化程序及宏定义 (9)3.3主程序 (10)3.4显示子程序 (12)3.5 按键子程序 (15)3.6 延时子程序 (16)第四章系统调试与分析 (17)第五章设计总结 (20)第六章参考文献 (21)附一元件清单 (22)附二仿真原理图 (23)附三程序清单 (24)附四实物图 (35)第一章设计论证及要求1.1设计应用意义二十一世纪是数字化技术高速发展的时代,而单片机在数字化高速发展的时代扮演着极为重要的角色。

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序

基于单片机的万年历源代码程序源程序代码如下:#include<reg52.h>#include<intrins.h>unsigned char code displaywelcome[]={" Welcome To My Lcd Timer"};//欢迎界面unsigned char code displaywish[]={" Happy Every Day ^_^"}; //欢迎界面unsigned char code overtemperature[]={"OVERTEMPERATURE!"};unsigned char code digit[]={"0123456789"}; //数字代码unsigned char mode,TH,TL,TN,TD,length,tempswitch,Maxtemp=40,amode,alarmmode,minutes,hours, minutea,seconds,houra=12;sbit SCLK=P1^0; //DS1302时钟输入sbit DATE=P1^1; //DS1302数据输入sbit REST=P1^2; //DS1302复位端口sbit SET=P1^4; //DS1302设置模式选择位sbit ADD=P1^5; //增加sbit RED=P1^6; //减小sbit CANL=P1^7;void delay1ms(int i)//1毫秒延时{int j,k;while(i--)for(j=76;j>1;j--);for(k=29;k>1;k--);}void delaynus(unsigned char n) //延时若干微秒{unsigned char i;for(i=0;i<n;i++);}/***********蜂鸣器模块************/sbit beep=P3^6; //位定义,定义P.6位fmpvoid dely500(void){unsigned char i;for(i=250;i>0;i--){_nop_();}}void baojing(unsigned char n){unsigned char x,i;while(n--){for(i=0;i<5;i++){for(x=0;x<200;x++){beep=~beep;dely500();}}for(i=0;i<3;i++){for(x=0;x<200;x++){beep=~beep;dely500();dely500();}}}}/*******DS1302模块*************/void Write1302(unsigned char date)//向1302写数据{unsigned char i;SCLK=0;delaynus(2);for(i=0;i<8;i++){DATE=date&0x01;SCLK=1;delaynus(2);SCLK=0;delaynus(2);date>>=1;}}void WriteSet1302(unsigned char cmd,unsigned char date) //根据相应的命令输入相应的数据{REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(5);Write1302(date);SCLK=1;REST=0;}unsigned char Read1302(void) //读取1302数据{unsigned char i,date;delaynus(2);for(i=0;i<8;i++){date>>=1;if(DATE==1)date|=0x80;SCLK=1;delaynus(2);SCLK=0;delaynus(2);}return date;}unsigned char ReadSet1302(unsigned char cmd)//根据命令读取1302相应的值{unsigned char date;REST=0;SCLK=0;REST=1;Write1302(cmd);delaynus(2);date=Read1302();SCLK=1;REST=0;return date;}void IntDS1302(void) //DS1302初始化{unsigned char flag;flag= ReadSet1302(0x81);if(flag&0x80) { //判断时钟芯片是否关闭WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((0/10)<<4|(0%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((0/10)<<4|(0%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((0/10)<<4|(0%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((10/10)<<4|(10%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令}}/***************液晶显示模块*****************/sbit RS=P2^5;sbit RW=P2^6;sbit E=P2^7;sbit BF=P0^7;/*液晶忙检测*/bit BusyTest(void){bit result;RS=0;RW=1;E=1;_nop_();_nop_();_nop_();result=BF;_nop_();_nop_();_nop_();E=0;return result;/*写指令*/void Write_com(unsigned char command) {while(BusyTest()!=0);RS=0;RW=0;E=0;_nop_();_nop_();_nop_();P0=command;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;}/*写地址*/void Write_Address(unsigned char address) {Write_com(address|0x80);delay1ms(1);}/*写数据*/void Write_Date(unsigned char date){RS=1;RW=0;E=0;_nop_();_nop_();_nop_();P0=date;_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();E=0;delay1ms(1);}/*初始化*/void Lcd_Int(void){Write_com(0x38);delay1ms(1);Write_com(0x38);delay1ms(1);Write_com(0x06);delay1ms(1);Write_com(0x0c);delay1ms(1);Write_com(0x01);}void displaymainpart(void)//显示液晶主要部分(不变化部分){Write_Address(0x01);delay1ms(1);Write_Date('D');Write_Date('A');Write_Date('T');Write_Date('E');Write_Date(':');delay1ms(1);Write_Address(0x0A);delay1ms(1);Write_Date('-');Write_Address(0x0D);Write_Date('-');Write_Address(0x42);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Date(':');Write_Address(0x4A);Write_Date('-');Write_Address(0x4D);Write_Date('-');Write_Address(0x06);Write_Date('2');Write_Date('0');}void display_Second(unsigned char second) //在液晶上显示秒{unsigned char i,j;i=second/10;j=second%10;Write_Address(0x4E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Minute(unsigned char minute) //在液晶上显示分{unsigned char i,j;i=minute/10;j=minute%10;Write_Address(0x4B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Hour(unsigned char hour) //在液晶上显示时{unsigned char i,j;i=hour/10;j=hour%10;Write_Address(0x48);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Day(unsigned char day) //在液晶上显示日{unsigned char i,j;i=day/10;j=day%10;Write_Address(0x0E);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Month(unsigned char month) //在液晶上显示月{unsigned char i,j;i=month/10;j=month%10;Write_Address(0x0B);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_Year(unsigned char year) //在液晶上显示年{unsigned char i,j;i=year/10;j=year%10;Write_Address(0x08);Write_Date(digit[i]);Write_Date(digit[j]);delay1ms(1);}void display_houra(unsigned char x) //闹钟小时部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x44);Write_Date(digit[i]);Write_Date(digit[j]);}void display_minutea(unsigned char x)//闹钟分钟部分显示{unsigned char i,j;i=x/10;j=x%10;Write_Address(0x47);Write_Date(digit[i]);Write_Date(digit[j]);}void display_Time(void) //显示实时时间{unsigned char value,day,month,year;Write_com(0x0c);value=ReadSet1302(0x81);seconds=(((value&0x70)>>4)*10+(value&0x0f));display_Second(seconds);value=ReadSet1302(0x83);minutes=(((value&0x70)>>4)*10+(value&0x0f));display_Minute(minutes);value=ReadSet1302(0x85);hours=(((value&0x70)>>4)*10+(value&0x0f));display_Hour(hours);value=ReadSet1302(0x87);day=(((value&0x70)>>4)*10+(value&0x0f));display_Day(day);value=ReadSet1302(0x89);month=(((value&0x70)>>4)*10+(value&0x0f));display_Month(month);value=ReadSet1302(0x8D);year=(((value&0xf0)>>4)*10+(value&0x0f));display_Year(year);}void displaystar(void) //显示欢迎界面{unsigned char i,j;Write_Address(0x0f);while(displaywelcome[i]!='\0'){Write_Date(displaywelcome[i]);i++;delay1ms(1);}i=0;Write_Address(0x4f);while(displaywish[i]!='\0'){Write_Date(displaywish[i]);i++;delay1ms(1);}j=40;while(j--){Write_com(0x18);//循环左移delay1ms(700);}Write_com(0x01);delay1ms(10);}void gbdisplay(unsigned char address) //时间调整时光标闪烁{Write_Address(address);delay1ms(5);Write_com(0x0f);delay1ms(5);}void displaymaxt(unsigned char x) //显示最大温度{unsigned char i,j,k;Write_com(0x0c);delay1ms(2);Write_Address(0x44);i=x/100;j=x/10;k=x%10;Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);}/*****************时间调整部分*********************/void hourset(void) //调时{unsigned char timevalue,hour;delay1ms(500); //防止多次触发WriteSet1302(0x8e,0x00);//将写保护去掉,确保能正常将调整后的数值写入DS1302timevalue=ReadSet1302(0x85); //读取此时的数值hour=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(50);if(ADD==0){hour++;delay1ms(300);while(ADD==0);}}if(RED==0){delay1ms(50);if(RED==0){hour--;delay1ms(300);if(hour==0) hour=23;while(RED==0);}}timevalue=(((hour)/10)<<4|(hour%10));WriteSet1302(0x84,timevalue);delay1ms(1);display_Hour(hour);Write_Address(0x49);delay1ms(5);if(hour>=24) hour=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void minuteset(void) //调分{unsigned char timevalue,minute;delay1ms(500);WriteSet1302(0x8e,0x00);timevalue=ReadSet1302(0x83);minute=(((timevalue&0x70)>>4)*10+(timevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){minute++;if(minute>=60) timevalue=0;while(ADD==0);}}if(RED==0)delay1ms(10);if(RED==0){minute--;delay1ms(300);if(minute==0) minute=59;while(RED==0);}}timevalue=((minute/10)<<4|(minute%10));WriteSet1302(0x82,timevalue);delay1ms(1);display_Minute(minute);Write_Address(0x4c);delay1ms(5);if(minute>=60) minute=0;delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void secondset(void) //秒归零{unsigned char second;delay1ms(500);WriteSet1302(0x8e,0x00);while(1){if(ADD==0){delay1ms(10);if(ADD==0){second=0;WriteSet1302(0x80,0x00);while(ADD==0);}delay1ms(1);display_Second(second);Write_Address(0x4f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void yearset(void) //调年{unsigned char datevalue,year;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x8d);year=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){year++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){year--;delay1ms(300);while(RED==0);}}datevalue=((year/10)<<4|(year%10));WriteSet1302(0x8c,datevalue);delay1ms(5);display_Year(year);delay1ms(5);Write_Address(0x09);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void monthset(void) //调月{unsigned char datevalue,month;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x89);month=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){month++;if(month>12) month=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){month--;delay1ms(300);if(month==0) month=12;while(RED==0);}}datevalue=((month/10)<<4|(month%10));WriteSet1302(0x88,datevalue);delay1ms(1);display_Month(month);Write_Address(0x0c);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void dayset(void) //调日{unsigned char datevalue,day;delay1ms(500);WriteSet1302(0x8e,0x00);datevalue=ReadSet1302(0x87);day=(((datevalue&0x70)>>4)*10+(datevalue&0x0f));while(1){if(ADD==0){delay1ms(10);if(ADD==0){day++;if(day>31) day=1;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){day--;delay1ms(300);if(day==0) day=31;while(RED==0);}}datevalue=((day/10)<<4|(day%10));WriteSet1302(0x86,datevalue);delay1ms(1);display_Day(day);Write_Address(0x0f);delay1ms(5);if(CANL==0){mode=0;Write_com(0x0c);break;}if(SET==0) break;}WriteSet1302(0x8e,0x80);}void alarmhourset(void) //闹钟小时调整{unsigned char value;value=houra;while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x0c);delay1ms(5);value++;if(value>23) value=0;while(ADD==0);}}if(RED==0){delay1ms(20);if(RED==0){value--;if(value==0) value=23;while(RED==0);}}houra=value;display_houra(houra);gbdisplay(0x45);if(CANL==0){delay1ms(500);break;}}}void alarmminuteset(void) //闹钟分钟调整{while(1){if(ADD==0){delay1ms(20);if(ADD==0){minutea++;if(minutea>59) minutea=0;while(ADD==0) ;}}if(RED==0){delay1ms(20);if(RED==0){minutea--;if(minutea==0) minutea=59;while(RED==0) ;}}display_minutea(minutea);gbdisplay(0x48);if(CANL==0){delay1ms(500);break;}}}void TimeSet(void) //时间调整函数{display_Time();if(SET==0){delay1ms(10);if(SET==0){mode++;delay1ms(20);switch(mode){case(1):{gbdisplay(0x48);hourset(); delay1ms(500);} break;case(2):{gbdisplay(0x4c);minuteset();delay1ms(500);} break;case(3):{gbdisplay(0x4f);secondset();delay1ms(500);} break;case(4):{gbdisplay(0x09);yearset();delay1ms(500);} break;case(5):{gbdisplay(0x0c);monthset();delay1ms(500);} break;case(6):{gbdisplay(0x0f);dayset();delay1ms(500);} break;}if(mode==7) mode=0;}}}/***************显示温度模块********************/unsigned char code displayexplain[]={"Digit thermometer"};unsigned char code displayerror[]={"DS18B20 ERROR"};unsigned char code displayerror1[]={"PLEASE CHECK "};unsigned char code displaypart1[]={"WenDu:"};unsigned char code displaypart2[]={"Cent"};unsigned char flag;/**********************操作DS18B20模块***************************/ sbit DQ=P3^3;unsigned char time;/**********************DS18B20初始化****************************/bit IntDS18B20(void){bit temp;DQ=1;for(time=0;time<2;time++);DQ=0;for(time=0;time<200;time++);DQ=1;for(time=0;time<10;time++);temp=DQ;for(time=0;time<200;time++);return temp;}/**************************读DS18B20**********************/unsigned char ReadDS18B20(void){unsigned char i;unsigned char dat;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;_nop_();DQ=1;for(time=0;time<2;time++);dat>>=1;if(DQ==1)dat=dat|0x80;elsedat=dat|0x00;for(time=0;time<10;time++);}return dat;}/*********************向DS18B20写数据**************************/ void WriteDS18B20(unsigned char date){unsigned char i;for(i=0;i<8;i++){DQ=1;_nop_();DQ=0;DQ=date&0x01;for(time=0;time<10;time++);DQ=1;for(time=0;time<1;time++);date>>=1;}for(time=0;time<4;time++);}/*******************为读取温度做好准备************************/ void ReadyreadDS18B20(void){IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0X44);delay1ms(200);IntDS18B20();WriteDS18B20(0XCC);WriteDS18B20(0XBE);}/*************在1602液晶上显示相关信息模块**********************/ /****************当未检测到DS18B20时显示信息模块****************/ void Display_Error(void){unsigned char i=0;Write_Address(0x00);while(displayerror[i]!='\0'){Write_Date(displayerror[i]);i++;delay1ms(100);}delay1ms(5);i=0;Write_Address(0x40);while(displayerror1[i]!='\0'){Write_Date(displayerror1[i]);i++;delay1ms(100);}delay1ms(3000) ;}/*************温度显示模块****************/void Display_Explain(void){unsigned char i=0;Write_Address(0x00);delay1ms(5);while(displayexplain[i]!='\0'){Write_Date(displayexplain[i]);i++;delay1ms(5);}i=0;Write_Address(0x40);while(displaypart1[i]!='\0'){Write_Date(displaypart1[i]);i++;delay1ms(5);}i=0;Write_Address(0x4C);while(displaypart2[i]!='\0'){Write_Date(displaypart2[i]);i++;delay1ms(5);}Write_Address(0x49);Write_Date('.');delay1ms(5);}/*********************显示温度整数部分*************************/ void Display_Integer(unsigned char x){unsigned char i,j,k;i=x/100;j=x%100/10;k=x%10;Write_Address(0x46);if(flag==1) Write_Date('-');Write_Date(digit[i]);Write_Date(digit[j]);Write_Date(digit[k]);delay1ms(50) ;}/************显示温度小数部分*********************/ void Display_Decimal(unsigned char x){Write_Address(0x4A);delay1ms(5);Write_Date(digit[x]);delay1ms(50);}void displayovert(void){unsigned char i;Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('W');Write_Date('A');Write_Date('R');Write_Date('N');Write_Date('I');Write_Date('N');Write_Date('G');Write_Date('!');Write_Address(0x40);while(overtemperature[i]!='\0'){Write_Date(overtemperature[i]);i++;delay1ms(10);}}/*******************温度主函数********************/ void Temperature(void){unsigned char i;delay1ms(5);if(IntDS18B20()!=0) Display_Error();else{delay1ms(1);Write_com(0x01);delay1ms(5);Display_Explain();for(length=50;length>0;length--){for(i=0;i<6;i++){flag=0;ReadyreadDS18B20();TL=ReadDS18B20();TH=ReadDS18B20();if((TH&0XF8)!=0X00){flag=1;TL=~TL;TH=~TH;TL+=1;if(TL>255) TH+=1;TN=TH*16+TL/16;TD=(TL%16)*10/16;}TN=TH*16+TL/16;TD=(TL%16)*10/16;Display_Integer(TN);Display_Decimal(TD);delay1ms(10);}if(tempswitch==1){if(TN>=Maxtemp){Write_Address(0x03);delay1ms(5);displayovert();while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);break;}}}}if(CANL==0) break;}}}void tempset(void){if(ADD==0){delay1ms(10);if(ADD==0){Maxtemp++;while(ADD==0);}}if(RED==0){delay1ms(10);if(RED==0){Maxtemp--;while(RED==0);}}}void Maxtempset(void) //高温报警设置{Write_com(0x01);delay1ms(10);Write_Address(0x03);delay1ms(10);Write_Date('T');Write_Date('E');Write_Date('M');Write_Date('P');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x40);Write_Date('M');Write_Date('A');Write_Date('X');Write_Date(':');while(1){if(SET==0){delay1ms(20);if(SET==0){Write_Address(0x4e);Write_com(0x0f);while(1){if(ADD==0){delay1ms(20);if(ADD==0){Write_Address(0x4b);delay1ms(5);Write_Date('O');Write_Date('N');Write_Date(' ');tempswitch=1;}}if(RED==0){delay1ms(20);if(RED==0){Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');tempswitch=0;}}if(CANL==0){delay1ms(500);break;}}}}if(tempswitch==1){Write_Address(0x4b);Write_Date('O');Write_Date('N');Write_Date(' ');tempset();displaymaxt(Maxtemp);if(CANL==0){Write_com(0x01);displaymainpart();break;}}if(tempswitch==0){Write_com(0x0c);Write_Address(0x4b);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){Write_com(0x01); displaymainpart();break;}}}void alarmswitchset(void){while(1){if(ADD==0){delay1ms(100);if(ADD==0){alarmmode=1;Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}}if(RED==0){alarmmode=0;Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}if(CANL==0){delay1ms(500);break;}}}/**************** 设置模块 ******************/ void Set(void){if(SET==0){delay1ms(10);if(SET==0){Write_Address(0x40);Write_Date('T');Write_com(0x0f);delay1ms(1000);Write_com(0x0c);while(1){TimeSet();if(ADD==0){delay1ms(20);if(ADD==0){Write_com(0x01);Write_Address(0x00);delay1ms(5);Write_Date('S');delay1ms(10);Maxtempset();}}if(RED==0){delay1ms(20);if(RED==0){Write_com(0x01);delay1ms(5);Write_Address(0x02);Write_Date('A');Write_Date('L');Write_Date('A');Write_Date('R');Write_Date('M');Write_Address(0x09);Write_Date('S');Write_Date('E');Write_Date('T');Write_Address(0x46);Write_Date('-');display_houra(houra);display_minutea(minutea);if(alarmmode==1){Write_Address(0x4c);Write_Date('O');Write_Date('N');Write_Date(' ');}if(alarmmode==0){Write_Address(0x4c);Write_Date('O');Write_Date('F');Write_Date('F');}while(1){if(SET==0){delay1ms(100);if(SET==0){amode++;switch(amode){case(1):{gbdisplay(0x45);alarmhourset();Write_com(0x0c);delay1ms( 500);} break;case(2):{gbdisplay(0x48);alarmminuteset();Write_com(0x0c);delay1m s(500);} break;case(3):{gbdisplay(0x4c);alarmswitchset();Write_com(0x0c);delay1m s(500);} break;}if(amode==4) amode=0;}}if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}if(CANL==0){Write_Address(0x40);Write_Date(' ');Write_com(0x0c);break;}}}}}/***************主函数**********************/void main(){IE=0X82; //打开定时中断TMOD=0X01; //选择定时器0工作在方式1TR0=0; //启动定时器0IntDS1302(); //初始化DS1302delay1ms(1);Lcd_Int(); //1602液晶初始化delay1ms(2);displaystar(); //显示欢迎界面displaymainpart(); //显示主要部分(不变化)while(1){display_Time( );Set( );if(ADD==0){Write_com(0x01);delay1ms(5);Temperature();Write_com(0x01);displaymainpart();}if((hours==houra)&&(minutes==minutea)&&(seconds==0)) {if(alarmmode==1){Write_com(0x01);delay1ms(5);Write_Address(0x03);Write_Date('T');Write_Date('I');Write_Date('M');Write_Date('E');Write_Address(0x08);Write_Date('U');Write_Date('P');Write_Date('!');delay1ms(5);while(1){baojing(1);if(CANL==0){Write_com(0x01);delay1ms(5);displaymainpart();break;}}}}}}。

基于AT89c52单片机电子万年历设计(带程序)

基于AT89c52单片机电子万年历设计(带程序)

目录一、摘要•二、设计・3三、设计任务.2四、设计要求•3五、系统方案设计・31、系统-31)原理构成框图•32)设计思路42 、主程序设计43 、中断程序设计55 、时间调整电路的设计7六、系统评价7七、c 语言程序注释及说明8一、摘要单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。

单片机接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。

将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。

本设计是基于AVR 单片机强大的控制功能制作而成的电子万年历,该电子万年历包括四大功能:实时显示年、月、日、时、分、秒、星期;人为的校正年、月、日、时、分、星期;第一次开机显示12-00-30 。

二、设计目的1、掌握C52 程序用于实践并实现相应的功能;2、掌握时钟程序的使用方法;3、掌握时间函数的使用方法;4、掌握键盘的程序使用方法;三、设计任务通过与单片机连接数码管动态显示年、月、日、时、分、秒、星期等功能,并能准确计算闰年闰月的显示,七个按钮连接P0 口可以精确调整每一个时间数值,通过对所设计的万年历时钟电路进行实验测试,达到了动态显示时间,随时调整时间等技术指标。

四、设计要求(1)能够准确的计时,时间可在数码管上显示出来,默认显示为时、分、秒,每隔一分钟自动显示年、月、日及星期,也可通过按键控制显示,并可通过按键调节时间。

(2)第一次开机显示12-30-30 。

(3)每半秒led 彩灯闪烁一次五、系统方案设计:1 、系统总体设计:1)原理构成框图本设计用AT89C52 作为核心控制部分,外接晶振电路与复位电路,以两个四位数码管作为显示部分,开关控制显示时间与日期,具体框图如图 1 所示,数码管框图如图 2 所示:P3 口开关控制>调整时间部分复位电路P1 口Led 彩灯部分单片机AT89C52数码管段选部分八数码管显示部分SB.B:「74HC138图1 原理框图图2 :数码管模块2)设计思路通过一段时间对专业书籍及多种设计方案的研究分析,我采用了比较常用的AT89C52作为核心控制芯片,用C语言进行编程来满足设计的要求。

单片机万年历程序(带闹钟)

单片机万年历程序(带闹钟)

第一章设计方案1.1.硬件设计1.1.1设计要求实现年月日、时分秒、星期的显示功能,用两个按键来实现日期和时间的调整功能,调整要求星期能自动更新,且能实现位调。

显示格式:四位年,两位月,两位日,星期字母前三位,两位时,两位分,两位秒。

比如:YYYY-MM-DD WEEKHH:MM:SS1.1.2硬件框图图1-1-硬件框图日期时间由硬件软件结合产生;按键之间相互配合完成当前日期时间的调整功能。

过程与结果由控制芯片分别输出到显示器上。

本设计附加了播放音乐的功能。

音乐从蜂鸣器产生。

1.1.3硬件选择1).显示模块本设计具体选用与实际应用与消耗资源相关。

万年历用到的地方大多都在室内。

现市场上与许多显示器,在日常生活中最常见的有数码管,led点阵屏,lcd液晶显示器等。

八段数码管的优点:亮度高,显示大。

驱动部份的软件简单;缺点:与液晶相比,耗电及体积大。

数码管只能单纯的显示数字,不能生动的表达各个参数的信息,消耗电力也比led液晶显示器大。

LCD液晶显示器它是一种专门用来显示字母、数字、符号等的点阵型液晶模块,在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高,由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。

因此,液晶显示器画质高且不会闪烁。

数字式接口,液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。

体积小、重量轻,液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。

功耗低,相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。

Lcd液晶能一屏把本设计所要显示的信息表达完整。

而且lcd耗电小,体积小很适合与室内使用。

本设计的要求日期时间以数字表示、星期用3位英文字符表示共21个字符,lcd1602能显示32个字表 1-1 lcd1602引脚及功能2).按键与蜂鸣器本设计选用轻触按钮,型号为XDJT1102S。

c51单片机万年历的c程序

c51单片机万年历的c程序

c51单片机万年历的c程序c51单片机万年历的c程序求一个单片机可以显示阳历的年、月、日、星期、小时.分.秒。

阴历也能显示,标明是否为闰年。

用LCD液晶显示,可以调整时间。

这有个数码管显示的程序以前做的,。

你可以在我这个程序上修改修改包括键盘扫描,还有动态显示。

【。

】#include <REG51.H>//常量参数#define TMODW 0x01;#define SCONW 0x00;#define xplay 0x04;//显示分频系数//显示位选unsigned char data stb;//键值缓存,0xFF无键命令unsigned char data keynum;//显示字型变量unsigned char data play[8];//工作参数unsigned char data l,m;//字型码unsigned char code BCDPC[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//字位码unsigned char code STBCODE[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 };//400Hz xplay分频计数unsigned char data cttime;//时钟参数unsigned char data hr,min,sec,sec100;//调整时钟参数(时钟“走”)void ct1(){sec100++;if (sec100==100){sec100=0;sec++;if (sec==60){sec=0;min++;if (min==60){min=0;hr++;if (hr==24) hr=0;}}}}//时钟参数→LED 显示缓存7段参数转换函数;void xcplay(){play[0]=BCDPC[hr/10];play[1]=BCDPC[hr%10];play[2]=BCDPC[min/10];play[3]=BCDPC[min%10];play[4]=BCDPC[sec/10];play[5]=BCDPC[sec%10];play[6]=BCDPC[sec100/10]; play[7]=BCDPC[sec100%10];}//显示扫描void cplay(){T0=1;//T0-高电平消隐T1=0;//T1-低电平准备发脉冲前沿TI=0;//?P1=0;//?SBUF=STBCODE[stb];while (TI==0){};TI=0;SBUF=play[stb];while (TI==0){};T1=1;T0=0;stb=++stb&0x07;}extern void cthl0();//定时器0中断处理程序void ct0(void) interrupt 1 using 1 {cthl0();cttime--;if (cttime==0){cttime=xplay;ct1();//调用时钟“走”函数xcplay();//调用时钟参数→Led显示缓存转换函数};cplay();}void w20ms(){for (l=0;l<41;l++){for (m=0;m<81;m++){}}}void tkey(){P1=0xF0;keynum=0xFF;if (P1!=0xF0){w20ms();P1=0xF0;if (P1!=0xF0){P1=0xFE;switch (P1){case 0xEE:keynum=0;break;case 0xDE:keynum=1;break;case 0xBE:keynum=2;break;case 0x7E:keynum=3;break;}P1=0xFD;switch (P1){case 0xED:keynum=4;break;case 0xDD:keynum=5;break;case 0xBD:keynum=6;break; case 0x7B:keynum=7;break; }P1=0xFB;switch (P1){case 0xEB:keynum=8;break; }};};P1=0x00;}void command(){switch (keynum){case 0:{hr=hr+1;if (hr==24)hr=0;}break;case 1:{min=min+1;if (min==60)min=0;}break;case 2:{sec=sec+1;if (sec==60)sec=0;}break;case 3:{sec100=0; }break;case 4:{while(!(P1=0xED)) {hr=0;min=0;sec=0;}}break;case 5:{hr=hr-1;if (hr==00)hr=24;}break;case 6:{min=min-1; if (min==00)min=59;}break;case 7:{sec=sec-1; if (sec==00)sec=0;}break;case 0xFF:break; }keynum=0xFF; }main (){ hr=8;min=5;sec=8;sec100=0; TMOD=TMODW; SCON=SCONW; ET0=1;TR0=1;EA=1;cttime=xplay; while (1){w20ms();tkey(); command();};}。

单片机万年历 现成程序

单片机万年历  现成程序
64138,64291,64426,64489,64603,64704,64795, //低音1~7
64837,64913,64981,65012,65070,65120,65166, //中音1~7
65186,65225,65259,65274,65303,65328,65351, //高音1~7
2+7,0x02,5+0,0x02,1+7,0x04,
//------------
0,0x00
};
//-----------------------秒表用:-----------------------
struct clkms_type
{uchar s;
uchar ms;
else {if(riqi[4]==0&&riqi[5]==2&&riqi[6]==2&&riqi[7]>8) {riqi[5]++;riqi[6]=0;riqi[7]=1;}}}
{ if(riqi[4]==0&&riqi[5]>9) {riqi[4]=1;riqi[5]=0;}; //month
struct backclk_type
{char h;
char m;
char s;
}backclk={0,0,5};
void back_clk() //时钟-1s处理
{backclk.s--;
if(backclk.s==-1&&backclk.m)
{backclk.s=59;
if(riqi[4]==1&&riqi[5]>2) {riqi[4]=0;riqi[5]=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_com(uchar com){lcdrs=0;P0=com;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_com(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_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void write_zhou(uchar add,uchar date) {write_com(0x80+add);write_date(0x30+date);}void write_ds(uchar add,uchar date){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;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_com(0x80+0x40+0x0a); write_com(0x0f);}if(numfun==2){write_com(0x80+0x40+0x07); write_com(0x0f);}if(numfun==3){write_com(0x80+0x40+0x04); write_com(0x0f);}if(numfun==4){write_com(0x80+0x0f);write_com(0x0f);}if(numfun==5){write_com(0x80+0x09);write_com(0x0f);}if(numfun==6){write_com(0x80+0x06);write_com(0x0f);}if(numfun==7){write_com(0x80+0x03); write_com(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_com(0x80+0x40+9); write_ds(0,miao);}if(numfun==2){fen++;if(fen==60)fen=0;write_sfm(6,fen);write_com(0x80+0x40+6); write_ds(2,fen);}if(numfun==3){shi++;if(shi==24)shi=0;write_sfm(3,shi);write_com(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week++;if(week==8)week=1;write_zhou(0x0f,week);write_com(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_com(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue++;if(yue==13)yue=0;write_nyr(5,yue);write_com(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_com(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_com(0x80+0x40+9); write_ds(0,miao);}if(numfun==2){fen--;if(fen==-1)fen=59;write_sfm(6,fen);write_com(0x80+0x40+6); write_ds(2,fen);}if(numfun==3){shi--;if(shi==-1)shi=23;write_sfm(3,shi);write_com(0x80+0x40+3);write_ds(4,shi);}if(numfun==4){week--;if(week==0)week=7;write_zhou(0x0f,week);write_com(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_com(0x80+0x08);write_ds(7,ri);}if(numfun==6){yue--;if(yue==-1)yue=12;write_nyr(5,yue);write_com(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_com(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_com(0x80+0x40+0x0a); write_com(0x0f);}if(anumfun==2){flag=1;write_com(0x80+0x40+0x07); write_com(0x0f);}if(anumfun==3){flag=1;write_com(0x80+0x40+0x04); write_com(0x0f);}{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_com(0x80+0x40+9); write_ds(1,amiao);}{afen++;if(afen==60)afen=0;write_sfm(6,afen);write_com(0x80+0x40+6); write_ds(3,afen);}if(anumfun==3){ashi++;if(ashi==24)ashi=0;write_sfm(3,ashi);write_com(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_com(0x80+0x40+9); write_ds(1,amiao);}if(anumfun==2){afen--;if(afen==-1)afen=59;write_sfm(6,afen);write_com(0x80+0x40+6); write_ds(3,afen);}if(anumfun==3){ashi--;if(ashi==-1)ashi=23;write_sfm(3,ashi);write_com(0x80+0x40+3);write_ds(5,ashi);}}}}void init(){EA=1;//开总中断EX0=1;//开外部中断0IT0=1;//设定触发方式为负跳变沿有效lcden=0;//选通液晶显示屏ledrw=0;//设定液晶显示屏的读写方式为读write_com(0x38);//设置液晶显示模式为16*2显示,5*7点阵,8位数据接口 write_com(0x0c);//打开显示,并使光标不显示也不闪烁write_com(0x06);//光标指针每次自动加1write_com(1);//清屏write_com(0x80);//送地址指针for(num=0;num<16;num++){write_date(table[num]);delay(5);}write_com(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寄存器。

LCD12864单片机电子万年历程序

LCD12864单片机电子万年历程序

*********************************#include<>#include<>#define LCD_Data P0#define uchar unsigned charunsigned charsec,min,hour,day,month,year,cen,week, next,aa,bb,cc,dd,mm,temp0,LunarMonth, LunarDay,LunarYear;int temp;uchar tt=1;bit c_moon;bit cenbit=1;bit w;sbit LCD_RS=P2^0;sbit LCD_RW=P2^1;sbit LCD_E=P2^2;sbit PSB=P2^3;sbit DS1302_CLK=P3^7;sbit DS1302_IO=P3^6;sbit DS1302_RST=P3^5;sbit DS18B20=P2^5;sbit speak=P2^7;sbit SetKey=P1^4; // 按键功能:设置sbit SureKey=P1^5; // 按键功能:确认sbit PlusKey=P1^6; // 按键功能:加sbit ReduceKey=P1^7; // 按键功能:减sbit scl=P1^1;sbit sda=P1^0;void DisplayShengXiao(void);void delay(unsigned int a)// 延时 1MS/ 次{unsigned char i;while(--a){for(i=0;i<125;i++) ;}}void delayb(unsigned int count){while(count--);}void delays(){ ; ;}void start(){sda=1;scl=1;delays();sda=0;delays();}void stop(){sda=0;scl=1;delays();sda=1;delays();}void response(){uchar i;while((sda==1)&&i<255)i++; //给应答信号 sda=0 ;错误( while (( sda==0 )|i<255 ) i++ ;)程序进入 while 死循环scl=1;delays();scl=0; // 没有这一步出错,如果没有 sda 将保持 0 状态,一直处于应答中。

单片机万年历程序代码

单片机万年历程序代码

单片机万年历程序代码以下是一个示例单片机万年历的程序代码:```c#include <reg51.h>typedef unsigned char uchar;typedef unsigned int uint;sbit K1 = P2^0; // 显示年份sbit K2 = P2^1; // 显示月份sbit K3 = P2^2; // 显示日期uchar code year_tab[] = {31,28,31,30,31,30,31,31,30,31,30,31}; uchar code week_tab[] = {0x06,0x07,0x01,0x02,0x03,0x04,0x05}; uchar year, month, day, week;void delay(uint ms){uint i, j;for(i=ms;i>0;i--)for(j=110;j>0;j--);}uchar getKey(){if(K1==0) {delay(5);if(K1==0)return 1;while(!K1);}if(K2==0) {delay(5);if(K2==0)return 2;while(!K2);}if(K3==0) {delay(5);if(K3==0)return 3;while(!K3);}return 0;}void display(uchar num) {P0 = num;delay(1);P0 = 0x00;}void init(){TMOD=0x01;TH0=0xFC;TL0=0x67;EA=1;ET0=1;TR0=1;}void main(){init();while(1) {uchar key = getKey();if(key == 1) {year++;if(year == 100)year = 0;}else if(key == 2) {month++;if(month == 13)month = 1;}else if(key == 3) {day++;if(day > year_tab[month-1]) { day = 1;}}display(year / 10);display(year % 10);display(month / 10);display(month % 10);display(day / 10);display(day % 10);display(week);}}void timer0() interrupt 1{TH0=0xFC;TL0=0x67;week++;if(week == 7)week = 0;}```该代码的主要思路是通过外部三个按键模拟年、月和日的调节,通过一个定时器不断更新星期的计数,然后将年、月、日和星期分别在数码管上显示出来。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

CHANGZHOU INSTITUTE OF TECHNOLOGY
科研实践
项目名称:电子万年历设计
二级学院:电子信息与电气工程学院
专业:电气工程及其自动化班级: 10 电二
学生姓名:祝学东学号:
指导教师:庄志红职称:副教授
起止时间: 2013年12月9日—2013年12月20日
摘要
本设计是电子万年历。

具备三个功能:能显示:年、月、日、时、分、秒、星期,并具有可调整日期和时间功能。

该电子万年历使用12MHZ晶振与单片机AT89C52相连接,通过软件编程的方法实现了以24小时为一个周期,同时显示小时、分钟和秒的要求。

利用单片机定时器及计数器产生定时效果通过编程形成数字钟效果,再利用数码管动态扫描显示单片机内部处理的数据。

同时通过端口读入当前外部控制状态来改变程序的不同状态,实现不同功能。

电子万年历设计与制作可采用数字电路实现,也可以采用单片机来完成。

若用数字电路完成,所设计的电路相当复杂,大概需要十几片数字集成块,其功能也主要依赖于数字电路的各功能模块的组合来实现,焊接的过程比较复杂,成本也非常高。

若用单片机来设计制作完成,由于其功能的实现主要通过软件编程来完成,这样一来就降低了硬件电路的复杂性,从而使得其成本降低,更适合我们大学生自主研发。

AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,AT89C52单片机在电子行业中有着广泛的应用。

关键词:单片机数字显示动态扫描时间日期可调
目录
第一章设计论证及要求 (1)
1.1设计应用意义 (1)
1.2设计方案论证 (1)
1.2.1 单片机芯片选择 (1)
(1)
(2)
1.3设计流程 (2)
第二章系统硬件电路设计 (3)
2.1 CPU时钟 (3)
2.2 主控芯片AT89C52模块 (3)
2.3 显示控制电路的设计及原理 (4)
2.4 按键电路设计 (6)
第三章系统软件设计 (7)
3.1 软件主流程 (7)
3.2初始化程序及宏定义 (9)
3.3主程序 (10)
3.4显示子程序 (12)
3.5 按键子程序 (15)
3.6 延时子程序 (16)
第四章系统调试与分析 (17)
第五章设计总结 (20)
第六章参考文献 (21)
附一元件清单 (22)
附二仿真原理图 (23)
附三程序清单 (24)
附四实物图 (35)
第一章设计论证及要求
1.1设计应用意义
二十一世纪是数字化技术高速发展的时代,而单片机在数字化高速发展的时代扮演着极为重要的角色。

电子万年历的开发与研究在信息化时代的今天亦是当务之急,因为它应用在学校、机关、企业、部队等单位礼堂、训练场地、教学室、公共场地等场合,可以说遍及人们生活的每一个角落。

所以说单片机的开发是国家之所需,社会之所需,人民之所需。

由于社会对信息交换不断提高的要求及高新技术的逐步发展,促使电子万年历发展并且投入市场得到广泛应用。

1.2设计方案论证
1.2.1 单片机芯片选择
方案一: 采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术, 当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。

方案二: 采用AT89C52,片内ROM全都采用Flash ROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全该芯片内部存储器为8KB ROM 存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。

但由于课程学习是主要以AT89C51为主,因此选择AT89C52。

1.2.2 显示模块选择
方案一:采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以也不用此种作为显示.
方案二:采用LED数码管动态扫描,LED数码管价格适中,对于显示数字最合适,而且采用动态扫描法与单片机连接时,占用的单片机口线少。

所以采用了LED数码管作为显示。

1.2.3 时钟芯片选择。

相关文档
最新文档