⑴ C51单片机的万年历程序设计
我这有个数码管显示的程序
以前做的,。。
你可以在我这个程序上修改修改
包括键盘扫描,还有动态显示
。
。
【。。。】
#include
//常量参数
#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();
};
}
⑵ 求单片机日历时钟C语言源程序
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code DSY_CODE[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0xff};
uchar DSY_BUFFER[]={0,0,0xBF,0,0,0xBF,0,0};
uchar Scan_BIT;
uchar DSY_IDX;
uchar Key_State;
uchar h,m,s,s100;
void DelayMS(uchar x)
{
uchar i;
while(x--) for(i=0;i<120;i++);
}
void Increase_Hour()
{
if(++h>23)h=0;
DSY_BUFFER[0]=DSY_CODE[h/10];
DSY_BUFFER[1]=DSY_CODE[h%10];
}
void Increase_Minute()
{
if(++m>59)
{
m=0;Increase_Hour();
}
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
}
void Increase_Second()
{
if(++s>59)
{
s=0;Increase_Minute();
}
DSY_BUFFER[6]=DSY_CODE[s/10];
DSY_BUFFER[7]=DSY_CODE[s%10];
}
void T0_INT()interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
P3=Scan_BIT;
P0=~DSY_BUFFER[DSY_IDX];
Scan_BIT=_crol_(Scan_BIT,1);
DSY_IDX=(DSY_IDX+1)%8;
}
void T1_INT()interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(++s100==20)
{
s100=0;Increase_Second();
}
}
void main()
{
P0=P3=0xFF;
TMOD=0x11;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TH1=0xDC;
TL1=0;
TCON=0x01;
EA=1;
ET0=1;
ET1=1;
h=12;m=s=s100=0;
DSY_BUFFER[0]=DSY_CODE[h/10];
DSY_BUFFER[1]=DSY_CODE[h%10];
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
DSY_BUFFER[6]=DSY_CODE[s/10];
DSY_BUFFER[7]=DSY_CODE[s%10];
Scan_BIT=0xFE;
DSY_IDX=0;
TR0=TR1=1;
Key_State=0xFF;
while(1)
{
if(P1^Key_State)
{
DelayMS(10);
if(P1^Key_State)
{
Key_State=P1;EA=0;
if((Key_State&0x01)==0)Increase_Hour();
else if((Key_State&0x02)==0)
{
m=(m+1)%60;
DSY_BUFFER[3]=DSY_CODE[m/10];
DSY_BUFFER[4]=DSY_CODE[m%10];
}
EA=1;
}
}
}
}
分给我吧,我不知道您要的是液晶时钟还是数码管的,但是我给你的是时钟,日历很好加,自己根据理解家上吧。希望对你有帮助。
⑶ 单片机日历时钟显示程序
建议你看看DS12C887或者DS1302的资料。
⑷ 单片机led显示时间年月日
如果想使单片机控制的LED数码管或点阵屏显示时间年月日,需要根据硬件配置编写完整的时钟、日历程序,程序调试好了下载到单片机里在整个系统供电正常时就可以自动显示了。
⑸ 基于单片机的万年历怎么做啊只要求显示日期和时间电路图、程序有谁懂的支援下哇.拜托了!
#include <reg52.h>
#include<stddef.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD1602_FLAG
#define LCD1602_PORT P0
sbit lcd1602_rs=P2^0;
sbit lcd1602_e=P2^2;
sbit lcd1602_rw=P2^1;
sbit lcd1602_busy=P0^7;
sbit key_ch=P3^5;
sbit key_add=P3^6;
sbit key_minus=P3^7;
uchar i,sec,min,h,date,month,flag;
uint year;
uchar *chgstr[7]={" ","sec","min","hour","date","min","year"};
uchar j,k,m,n,o,p;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar timestr[10],datestr[10];
void init();
void delay(uint);
void time_display();
void date_display();
void control();
void time();
/*
************************************
* 函数名称:lcd1602_CheckBusy()
* 函数功能:状态查询
************************************
*/
void lcd1602_CheckBusy()
{
do
{
lcd1602_busy=1;
lcd1602_rs=0;
lcd1602_rw=1;
lcd1602_e=0;
lcd1602_e=1;
}
while(lcd1602_busy);
}
/*
***************************************
* 函数名称: lcd1602_WriteCmd()
* 函数功能:写命令
* 入口参数:命令字
* 出口参数:无
***************************************
*/
void lcd1602_WriteCmd(const uchar cmd)
{
lcd1602_CheckBusy();
lcd1602_rs=0;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=cmd;
lcd1602_e=0;
}
/*
*******************************************
* 函数名称:lcd1602_WriteData()
* 函数功能:写数据
* 入口参数:c--待写数据
* 出口参数:无
*********************************************
*/
void lcd1602_WriteData(const uchar c)
{
lcd1602_CheckBusy();
lcd1602_rs=1;
lcd1602_rw=0;
lcd1602_e=1;
LCD1602_PORT=c;
lcd1602_e=0;
}
/*
***********************************************
* 函数名称:lcd1602_Init()
* 函数功能:初始化LCD
* 入口参数:无
* 出口参数:无
***********************************************
*/
void lcd1602_Init()
{
lcd1602_WriteCmd(0x38); //显示模式为8位2行5*7点阵
lcd1602_WriteCmd(0x0c); //display enable,flag enable,flash enable,
lcd1602_WriteCmd(0x06); //flag move to right,screen don't move
lcd1602_WriteCmd(0x01); //clear screen
}
/*
************************************************
* 函数名称:lcd1602_Display()
* 函数功能: 字符显示
* 入口参数:ptr--字符或字符串指针
* 出口参数:无
* 说 明:用户可通过以下方式来调用:
* 1)lcd1602_Display("Hello,world!");
* 2) INT8U 存储类型 txt[]="要显示的字符串";
* 或者 INT8U 存储类型 txt[]={'t','x','t',..,'\0'};
* INT8U *ptr;
* ptr=&txt;
* lcd1602_Display(ptr);
* 或 lcd1602_Display(txt);
* 或 lcd1602_Display(&txt);
************************************************
*/
void lcd1602_Display(const uchar *ptr,uchar line,uchar xaddr)
{
uchar data i=0;
uchar *data q;
q=ptr;
switch(line)
{
case 0:
lcd1602_WriteCmd(0x80+xaddr);
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q);
q++;
i++;
}
break;
case 1:
lcd1602_WriteCmd(0xc0+xaddr);
while(q!=NULL && (*q!='\0') && i<16)
{
lcd1602_WriteData(*q);
q++;
i++;
}
break;
}
}
void main()
{
lcd1602_Init();
init();
while(1)
{
time_display();
date_display();
control();
}
}
void init()
{
i=0;
sec=0;
min=30;
h=7;
date=17;
month=10;
year=2017;
flag=0;
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void time_display()
{
timestr[7]=0x30+sec%10;
timestr[6]=0x30+sec/10;
timestr[5]=':';
timestr[4]=0x30+min%10;
timestr[3]=0x30+min/10;
timestr[2]=':';
timestr[1]=0x30+h%10;
timestr[0]=0x30+h/10;
timestr[8]=0;
lcd1602_Display(timestr,1,3);
}
void date_display()
{
datestr[9]=0x30+date%10;
datestr[8]=0x30+date/10;
datestr[7]=':';
datestr[6]=0x30+month%10;
datestr[5]=0x30+month/10;
datestr[4]=':';
datestr[3]=0x30+year%10;
datestr[2]=0x30+year/10%10;
datestr[1]=0x30+year/100%10;
datestr[0]=0x30+year/1000;
lcd1602_Display(datestr,0,2);
}
void control()
{
if(!key_ch)
{
delay(5);
if(!key_ch)
{
flag++;
TR0=0;
if(flag==7)
{flag=0;TR0=1;lcd1602_Init();}
lcd1602_Display(chgstr[flag],1,12);
}
}
while(!key_ch);
if(flag==1&&key_add==0)
{
while(!key_add);
sec++;
if(sec==60)
sec=0;
}
if(flag==1&&key_minus==0)
{
while(!key_minus);
sec--;
if(sec==-1)
sec=59;
}
if(flag==2&&key_add==0)
{
while(!key_add);
min++;
if(min==60)
min=0;
}
if(flag==2&&key_minus==0)
{
while(!key_minus);
min--;
if(min==-1)
min=59;
}
if(flag==3&&key_add==0)
{
while(!key_add);
h++;
if(h==24)
h=0;
}
if(flag==3&&key_minus==0)
{
while(!key_minus);
h--;
if(h==-1)
h=23;
}
if(flag==4&&key_add==0)
{
while(!key_add);
date++;
if(date==29)
if((year%4!=0)&&(month==2))
date=1;
if(date==30)
if((year%4==0)&&(month==2))
date=1;
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
date=1;
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
date=1;
}
if(flag==4&&key_minus==0)
{
while(!key_minus);
if(date>1)date--;
}
if(flag==5&&key_add==0)
{
while(!key_add);
month++;
if(month==13)
month=1;
}
if(flag==5&&key_minus==0)
{
while(!key_minus);
month--;
if(month==0)
month=12;
}
if(flag==6&&key_add==0)
{
while(!key_add);
year++;
if(year==99)
year=1;
}
if(flag==6&&key_minus==0)
{
while(!key_minus);
year--;
if(year==0)
year=99;
}
}
void T0_rpt() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
i++;
time();
}
void time()
{
if(i==20)
{
i=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
h++;
if(h==24)
{
h=0;
min=0;
sec=0;
date++;
if(date==29)
if((year%4!=0)&&(month==2))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==30)
if((year%4==0)&&(month==2))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==31)
if((month==4)||(month==6)||(month==9)||(month==11))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
if(date==32)
if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12))
{
date=1;
month++;
if(month==13)
{
month=1;
year++;
}
}
}
}
}
}
}
⑹ 求单片机日历C程序设计
#include<reg52.h>
#include<define.h>
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void didi()
{
beep=0;
delay(50);
beep=1;
delay(100);
beep=0;
delay(50);
beep=1;
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
EA=1;
EX0=1;
IT0=1;
la=0;
wela=0;
lcden=0;
// set_time();
set_alarm(14,13,10);
write_ds(0x0B,0x26);
read_ds(0x0c);
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
}
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 keyscan()
{
rd=0;
if(flag1==1)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
flag1=0;
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
flag1=0;
}
}
}
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
flag=1;
flag1=0;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
flag=0;
write_ds(0,miao);
write_ds(2,fen);
write_ds(4,shi);
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(1);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(1);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/* if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void write_ds(uchar add,uchar date)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;
ds_date=P0;
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}
void set_time()
{
write_ds(4,10);
write_ds(2,32);
}
void set_alarm(uchar ashi,uchar afen,uchar amiao)
{
write_ds(1,amiao);
write_ds(3,afen);
write_ds(5,ashi);
}
void main()
{
init();
while(1)
{
keyscan();
if(flag1==1)
didi();
if(flag==0)
{
miao=read_ds(0);
fen=read_ds(2);
shi=read_ds(4);
write_sfm(10,miao);
write_sfm(7,fen);
write_sfm(4,shi);
}
}
}
void exter() interrupt 0
{ uchar c;
flag1=1;
c=read_ds(0x0c);
}
#define uchar unsigned char
#define uint unsigned int
sbit la=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
sbit beep=P2^3;
sbit dscs=P1^4;
sbit dsas=P1^5;
sbit dsrw=P1^6;
sbit dsds=P1^7;
sbit dsirq=P3^3;
uchar count,s1num,flag,flag1;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";
uchar code table1[]=" : : ";
void write_ds(uchar,uchar);
void set_alarm(uchar,uchar,uchar);
uchar read_ds(uchar);void set_time();
⑺ 51单片机制做日历
看看这个程序嘛,,虽然没有你要得年月日,但是有时间得啊。。。可以借此来点灵感。。我也在做这个东西。。。我还在收集资料啊。。。共同学习。。
;采用8位LED软件译码动态显示程序
;使用AT89C51单片机,12MHZ晶振,P0输出字段码,P2口输出位选码,用共阳
;LED数码管,P1.0为调时位选择按键,P1.1为加1键,P1.2为减1键。
;片内RAM的70H到77H单元为LED数码管的显示缓冲区
;78H,79H,7AH分别为秒、分、小时计数单元
;7BH为50ms计数器,7CH为调时按键计数器
ORG 0000H
LJMP START
ORG 000BH ;定时器/计数器T0中断程序入口
LJMP INTT0
;主程序
START:MOV R0,#70H
MOV R7,#0CH
INIT: MOV @R0,#00H
INC R0
DJNZ R7,INIT
MOV 72H,#10
MOV 75H,#10
MOV TMOD,#01H
MOV TL0,#0B0H
MOV TH0,#03CH
SETB EA
SETB ET0
SETB TR0
START1: LCALL SCAN
LCALL KEYSCAN
SJMP START1
;延时1MS子程序
DL1MS: MOV R6,#14H
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;延时20MS子程序
DL20MS: ACALL SCAN
ACALL SCAN
ACALL SCAN
RET
;数码管显示程序
SCAN: MOV A,78H ;时间存入显示缓冲区相应位置
MOV B,#0AH
DIV AB
MOV 71H,A
MOV 70H,B
MOV A,79H
MOV B,#0AH
DIV AB
MOV 74H,A
MOV 73H,B
MOV A,7AH
MOV B,#0AH
DIV AB
MOV 77H,A
MOV 76H,B
MOV R1,#70H ;循环扫描显示
MOV R5,#80H
MOV R3,#08H
SCAN1: MOV A,R5
MOV P2,A
MOV A,@R1
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P0,A
MOV A,R5
LCALL DL1MS
INC R1
MOV A,R5
RR A
MOV R5,A
DJNZ R3,SCAN1
MOV P2,#00H
MOV P0,#0FFH
RET
TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH
;“0~9”,“-”的共阳极字段码
;定时器/计数器T0中断服务程序
INTT0: PUSH ACC
PUSH PSW
CLR ET0
CLR TR0
MOV TL0,#0B0H
MOV TH0,#03CH
SETB TR0
INC 7BH
MOV A,7BH
CJNE A,#14H,OUTT0
MOV 7BH,#00
INC 78H
MOV A,78H
CJNE A,#3CH,OUTT0
MOV 78H,#00
INC 79H
MOV A,79H
CJNE A,#3CH,OUTT0
MOV 79H,#00
INC 7AH
MOV A,7AH
CJNE A,#18H,OUTT0
MOV 7AH,#00
OUTT0:
SETB ET0
pop psw
pop acc
RETI
;按键处理程序
KEYSCAN: CLR EA
JNB P1.0,KEYSCAN0
JNB P1.1,KEYSCAN1
JNB P1.2,KEYSCAN2
KEYOUT: SETB EA
RET
KEYSCAN0: LCALL DL20MS
JB P1.0,KEYOUT
WAIT0: JNB P1.0,WAIT0
INC 7CH
MOV A,7CH
CLR TR0
CLR ET0
CJNE A,#03H,KEYOUT
MOV 7CH,#00
SETB TR0
SETB ET0
SJMP KEYOUT
KEYSCAN1: LCALL DL20MS
JB P1.1,KEYOUT
WAIT1: JNB P1.1,WAIT1
MOV A,7CH
CJNE A,#02H,KSCAN11
INC 79H
MOV A,79H
CJNE A,#3CH,KEYOUT
MOV 79H,#00
SJMP KEYOUT
KSCAN11: INC 7AH
MOV A,7AH
CJNE A,#18H,KEYOUT
MOV 7AH,#00
SJMP KEYOUT
KEYSCAN2: LCALL DL20MS
JB P1.2,KEYOUT
WAIT2: JNB P1.2,WAIT2
MOV A,7CH
CJNE A,#02H,KSCAN21
DEC 79H
MOV A,79H
CJNE A,#0FFH,KEYOUT
MOV 79H,#3BH
SJMP KEYOUT
KSCAN21: DEC 7AH
MOV A,7AH
CJNE A,#0FFH,KEYOUT
MOV 7AH,#17H
SJMP KEYOUT
END
⑻ 跪求 51单片机+12864液晶+1302时钟制成的万年历c程序
顶层文件 万年历.C
#include<reg51.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4;
bit key_flag1=0,key_flag2=0;
SYSTEMTIME adjusted;
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchar data_alarm[7]={0};
/************键盘控制******************************/
int key_scan() //扫描是否有键按下
{ int i=0;
uint temp;
P1=0xf0;
temp=P1;
if(temp!=0xf0)
i=1;
else
i=0;
return i;
}
uchar key_value() //确定按键的值
{
uint m=0,n=0,temp;
uchar value;
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;
P1=0xfe; temp=P1; if(temp!=0xfe)m=0;
P1=0xfd;temp=P1 ;if(temp!=0xfd)m=1;
P1=0xfb;temp=P1 ;if(temp!=0xfb)m=2;
P1=0xf7;temp=P1 ;if(temp!=0xf7)m=3;
P1=0xef;temp=P1 ;if(temp!=0xef)n=0;
P1=0xdf;temp=P1 ;if(temp!=0xdf)n=1;
P1=0xbf;temp=P1 ;if(temp!=0xbf)n=2;
value=v[m][n];
return value;
}
/***************************设置闹铃函数*******************************/
void naoling(void)
{
uchar i=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')*10;else {data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
uchar according(void)
{ uchar k;
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1;
else k=0;
return k;
}
void speak(void)
{uint i=50;
while(i)
{speaker=0;
delay(1);
speaker=1;
delay(1);
i--;
}
}
void alarm(void)
{uint i=10;
while(i)
{
speak();
delay(10);
i--;
}
}
/**************************修改时间操作********************************/
void reset(void)
{
sec_add=0;
min_add=0;
hou_add=0;
day_add=0;
mon_add=0;
yea_add=0 ;
}
void adjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++;break;
case '1':min_add++;break;
case '2':hou_add++;break;
case '3':day_add++;break;
case '4':mon_add++;break;
case '5':yea_add++;break;
case 'b':reset();break;
default: break;
}
adjusted.Second+=sec_add;
adjusted.Minute+=min_add;
adjusted.Hour+=hou_add;
adjusted.Day+=day_add;
adjusted.Month+=mon_add;
adjusted.Year+=yea_add;
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60;
if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60;
if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24;
if(adjusted.Day>31) adjusted.Day=adjusted.Day%31;
if(adjusted.Month>12) adjusted.Month=adjusted.Month%12;
if(adjusted.Year>100) adjusted.Year=adjusted.Year%100;
}
/**************************中断处理函数*********************************/
void changing(void) interrupt 0 using 0 //需要修改时间和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
else key_flag1=1;
}
void alarming(void) interrupt 3 using 0 //需要设置闹铃或者停止设置
{
if(key_flag2)key_flag2=0;
else key_flag2=1;
}
/********************************主函数***********************************/
main()
{uint i;
uchar *l;
uchar p1[]="D:",p2[]="T:";
SYSTEMTIME T;
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602();
Initial_DS1302() ;
while(1)
{ write_com(0x80);
write_string(p1,2);
write_com(0xc0);
write_string(p2,2);
DS1302_GetTime(&T) ;
adjusted.Second=T.Second;
adjusted.Minute=T.Minute;
adjusted.Hour=T.Hour;
adjusted.Week=T.Week;
adjusted.Day=T.Day;
adjusted.Month=T.Month;
adjusted.Year=T.Year;
for(i=0;i<9;i++)
{
adjusted.DateString[i]=T.DateString[i];
adjusted.TimeString[i]=T.TimeString[i];
}
adjust();
if(key_flag2)naoling();
if(according())alarm();
DateToStr(&adjusted);
TimeToStr(&adjusted);
write_com(0x82);
write_string(adjusted.DateString,8);
write_com(0xc2);
write_string(adjusted.TimeString,8);
delay(10);
}
(二)头文件1 显示模块 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0;
sbit lcdrw = P2^1;
sbit lcden = P2^2;
void delay(uint z) // 延时
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) // 写入指令数据到 lcd
{
lcdrw=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) // 写入字符显示数据到 lcd
{
lcdrw=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init1602() // 初始化设定
{
lcdrw=0;
lcden=0;
write_com(0x3C);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void write_string(uchar *pp,uint n)
{
int i;
for(i=0;i<n;i++)
write_data(pp[i]);
}
#endif
(三)头文件2 时钟模块 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_
sbit DS1302_CLK = P2^6; //实时时钟时钟线引脚
sbit DS1302_IO = P2^7; //实时时钟数据线引脚
sbit DS1302_RST = P2^5; //实时时钟复位线引脚
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct SYSTEM_TIME
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9]; //用这两个字符串来放置读取的时间
unsigned char TimeString[9];
}SYSTEMTIME; //定义的时间类型
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用于计算 DS1302_RAM 地址的宏
/******内部指令**********/
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0;
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1; //因为在前面已经定义了ACC0 = ACC^0;以便再次利用DS1302_IO = ACC0;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
/********************************/
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10))); //将十进制数转换为BCD码
} //在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将BCD码转换为十进制数
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8];
D[0]=Time->Second/10<<4+Time->Second%10;
D[1]=Time->Minute/10<<4+Time->Minute%10;
D[2]=Time->Hour/10<<4+Time->Hour%10;
D[3]=Time->Day/10<<4+Time->Day%10;
D[4]=Time->Month/10<<4+Time->Month%10;
D[5]=Time->Week/10<<4+Time->Week%10;
D[6]=Time->Year/10<<4+Time->Year%10;
return D;
}
void DateToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME *Time)
{
//将十进制数转换为液晶显示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
void Initial_DS1302(void)
{
unsigned char Second;
Second=Read1302(DS1302_SECOND);
if(Second&0x80) //初始化时间
DS1302_SetTime(DS1302_SECOND,0);
}
void DS1302_TimeStop(bit flag) // 是否将时钟停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND, Data|0x80);
else
Write1302(DS1302_SECOND, Data&0x7F);
}
#endif
⑼ 电子日历单片机制作
实现日历的显示、闹钟设置、日期和时间的设置功能
⑽ 单片机做的日历 c语言程序
这是一个DS1302时钟程序,根据自己的硬件电路适当改改就可以做成日历了 /********************************************************************
*DS1302控制程序 2011.12.01 wqz
********************************************************************/
#include<reg52.h>
#include<intrins.h>
typedef unsigned uchar;sbit sda=P2^1; //DS1302
sbit clk=P2^0;
sbit ce=P2^2;
//sbit sda=P3^4;
//sbit clk=P3^6;
//sbit ce=P3^5;
//
//sbit _138_A=P2^2; //138A,B,C口
//sbit _138_B=P2^3;
//sbit _138_C=P2^4;sbit IO =P1^7; //595控制信号
sbit RLK =P1^6;
sbit CLK =P1^5;#define my_delay5us() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();\
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
//#define T0_init() TMOD=0x01;TH0=0xb8;TL0=0x00;TR0=1;ET0=1;EA=1uchar cc[8]; //将要显示的时间由BCD码转换成要显示的数值存放在CC[]中
uchar bb[8]; //存放从DS1302中读取出来的数据
uchar aa[7]={0,30,18,20,12,6,11}; //初始时间
uchar code write_rtc[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //时间寄存器写地址
uchar code tember[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //共阴数码管显示表void my_delay1ms(int t); //延时1ms函数
void write_1byte(uchar temp); //写一字节数据
uchar read_1byte(); //读一字李数据
void write_addr_data(uchar Addr, uchar Data); //先写地址再写数据
uchar writeadd_readdat(uchar ucAddr); //先写地址再读数据
void write1_readM(); //连续读多个字节数据
void ds1302_init(); //DS1302初始化/********************************************************************
*
* 主函数
********************************************************************/void main()
{
uchar i,j,dat; my_delay1ms(10);
ds1302_init(); //给DS1302付初值 11年12月20日 周六 18-30-00
// T0_init(); while(1)
{
write1_readM(); //读DS1302中的数据 cc[0]=bb[0]%16;
cc[1]=bb[0]/16;
cc[2]=10;
cc[3]=bb[1]%16;
cc[4]=bb[1]/16;
cc[5]=10;
cc[6]=bb[2]%16;
cc[7]=bb[2]/16; for(j=0;j<8;j++)
{
dat=tember[cc[j]];
RLK=0;
my_delay5us();
for(i=0;i<8;i++)
{
if(dat&0x80)IO=1;
else IO=0;
my_delay5us();
CLK=1;
my_delay5us();
CLK=0;
dat<<=1;
}
my_delay5us();
RLK=1;
}
my_delay1ms(500);
}
}/**********************************************************************/void my_delay1ms(int t) //延时
{
uchar i,j;
while(t--)
{
for(i=4;i>0;i--)
for(j=50;j>0;j--);
}
}/**********************************************************************/void write_1byte(uchar temp) //写一字节数据
{
uchar i; clk=0;
my_delay5us();
for (i=0;i<8;i++)
{
if(temp&0x01)sda=1;
else sda=0;
my_delay5us();
clk=1;
my_delay5us();
clk=0;
temp>>=1;
}
}/**********************************************************************/uchar read_1byte() //读一字节数据
{
uchar i,num;
for (i=0;i<8;i++)
{
num>>=1;
if(sda)
num|=0x80;
my_delay5us();
clk=1;
my_delay5us();
clk=0;
}
return num;
}/**********************************************************************/void write_addr_data(uchar Addr, uchar Data) //先写地址再写数据
{
ce = 0;
my_delay5us();
clk = 0;
my_delay5us();
ce = 1;
my_delay5us();
write_1byte(Addr); // 地址,命令
write_1byte(Data); // 写1Byte数据
my_delay5us();
clk=1;
my_delay5us();
ce =0;
} /**********************************************************************/uchar writeadd_readdat(uchar ucAddr) //先写地址再读数据
{
uchar num1=0; ce = 0 ;
my_delay5us();
clk = 0;
my_delay5us();
ce = 1;
my_delay5us();
write_1byte(ucAddr); // 地址,命令
num1 = read_1byte(); // 读1Byte数据
my_delay5us();
clk = 1;
my_delay5us();
ce =0; return(num1);
}/**********************************************************************/void write1_readM() //连续读多个字节数据
{
uchar i,Addr; Addr=0x81;
for (i=0;i<7;i++)
{
bb[i] = writeadd_readdat( Addr);//*格式为: 秒 分 时 日 月 星期 年
Addr += 2;
}
}/**********************************************************************/void ds1302_init() //初始时间 11年12月20日 周六 18-30-00
{
uchar i,*p,tmp; for(i=0;i<7;i++)
{ /*如想设置DS1302的“秒”,设置时间为37秒,所以输入的是十*/
tmp=aa[i]/10; /*进制数37,对应的16进制是0x25,但是DS1302寄存器使用的是压*/
aa[i]=aa[i]%10; /*缩BCD码,所以应该写入BCD数值37才行,即0x37。所以需要将*/
aa[i]=aa[i]+tmp*16; /*10进制的37转换为16进制表示的0x37*/
}
write_addr_data(0x8E,0X00);
p=write_rtc; //传地址
for(i=0;i<7;i++) //7次写入 秒分时日月周年
{
write_addr_data(*p,aa[i]);
p++;
} write_addr_data(0x8E,0x80);
}/**********************************************************************///void ET0_ser() interrupt 1
//{
//// uchar i;
//
// TH0=0x55;
// TL0=0x00;
//
//// P0=tember[cc[i]];
//// switch(i)
//// {
//// case 0 : _138_A=1;_138_B=1;_138_C=1; break;
//// case 1 : _138_A=0;_138_B=1;_138_C=1; break;
//// case 2 : _138_A=1;_138_B=0;_138_C=1; break;
//// case 3 : _138_A=0;_138_B=0;_138_C=1; break;
//// case 4 : _138_A=1;_138_B=1;_138_C=0; break;
//// case 5 : _138_A=0;_138_B=1;_138_C=0; break;
//// case 6 : _138_A=1;_138_B=0;_138_C=0; break;
//// case 7 : _138_A=0;_138_B=0;_138_C=0; break;
//// }
//// i++;
//// if(i==8)i=0;
//}