您的当前位置:首页正文

基于STC89C51单片机的万年历制作方法

来源:爱go旅游网
基于51单片机的万年历论文

学校 华侨大学

学院 信息科学与工程学院

班级 10级 集成电路设计与集成系统

一、摘要 1、

2、74lLS245摘要:

74LS245是我们常用的芯片,用来驱动led或者其他的设备,它是8路同相三态双向总线收发器,可双向传输数据。

74LS245还具有双向三态功能,既可以输出,也可以输入数据。

3、四位一体共阴数码管管脚图:

二、所用到的元器件:

元器件各类、及参数、个数 STC89C51RC系列单片机 按键开关 上拉电阻10K 其它各类电阻 1n4148二极管 电容 FJ3461AH类4位一体共阴数码管 12MHz晶振 导线 1、天关及其功能:

P1_0 //时钟秒或日历天调整 P1_1 //时钟分或日历月调整 P1_2; //时钟时或日历年调整 P1_3 //时间与日历间的切换 RST:复位。

1个 5个 1组 220/8个、10K/4个、1K/个 4个 22uf/1个、30pf/2个 2组 1个 若干 三、protues仿真图:

四1、Altium designer下的原理图:

2、Altium designer下的PCB图:

五、c语言源代码:

#include #include #define uchar unsigned char #define uint unsigned int

/*七段共阳管显示定义*/

uchar code dispcode[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x80}; //此表为 LED 的字模, 共阳数码管 0-9 ,_ 和. /*定义并初始化变量*/ uchar seconde=0;//秒 uchar minite=0;//分 uchar hour=12; //时 uchar day=24;//日 uchar month=3;//月

uint year=2012,a=1,b=1,c=1; //年和下降沿变量

uchar mstcnt=0;//定时器计数,定时50ms,mstcnt满20,秒加1 int dateadd1=0;

sbit P1_0=P1^0; //时钟秒或日历天调整 sbit P1_1=P1^1; //时钟分或日历月调整 sbit P1_2=P1^2; //时钟时或日历年调整 sbit P1_3=P1^3; //时间与日历间的切换 /*函数声明*/

void delay(uint k ); //延时子程序 void time_pro( ); //时间处理子程序 void display( ); //时间显示调整子程序 void dateadd(int m); //日历处理子程序 void calendar( ); //日历显示调整子程序 /*延时子程序*/ void delay (uint k) { uchar j; while(k--) {

for(j=0;j<125;j++) {;} } }

/*时间处理子程序*/ void time_pro(void) {

if(seconde==60) {

seconde=0; minite++; if(minite==60) { minite=0; hour++; if(hour==24)

{ hour=0; dateadd1++; } } } }

/*时间显示调整子程序*/ void display(void) {

if(P1_3==1) {

/*时间调整键盘扫描子程序*/

if(P1_0!=a)//秒位的调整,下降沿有效 {

delay(10); if(P1_0==0) {

seconde++;

if(seconde==60) {

seconde=0; } }a=P1_0; }

if(P1_1!=b)//分位的调整,下降沿有效 {

delay(10); if(P1_1==0) { minite++; if(minite==60) { minite=0; } }b=P1_1; }

if(P1_2!=c)//时位的调整,下降沿有效 {

delay(10); if(P1_2==0) { hour++; if(hour==24)

{ hour=0; } }c=P1_2; }

/*时间显示子程序*/ P3=0Xfe;

P0=dispcode[hour/10];//时十位 delay(2); P3=0Xfd;

P0=dispcode[hour%10];//时个位 delay(2); P3=0Xfb;

P0=dispcode[10];//间隔符 - delay(2); P3=0Xf7;

P0=dispcode[minite/10];//分十位 delay(2); P3=0Xef;

P0=dispcode[minite%10];//分个位 delay(2); P3=0Xdf;

P0=dispcode[10];//间隔符 - delay(2); P3=0Xbf;

P0=dispcode[seconde/10];//秒十位 delay(2); P3=0X7f;

P0=dispcode[seconde%10];//秒个位 delay(2); } }

/*日历处理子程序*/

void dateadd( int m) //日期加1函数 { if(m) { dateadd1--; switch(month)

{

case 1: if( day==31)

{ day=1;

month++; break;

}

else day=day+1; break;

case 2: if((year%400==0)||(year%4==0&&year%100!=0)) {

if(day==29) {month++; day=1; break; }

else day=day+1; break; } else {

if(day==28) {month++; day=1; break; }

else day=day+1; break; }

case 3: if( day==31)

{ month++;

day=1; break; }

else day=day+1; break;

case 4: if( day==30) {

month++; day=1; break; }

else day=day+1; break;

case 5: if( day==31) {

month++; day=1; break; }

else day=day+1; break;

case 6: if( day==30) {

month++; day=1; break; }

else day=day+1; break;

case 7: if( day==31) {

month++; day=1; break; }

else day=day+1; break;

case 8: if( day==31) {

month++; day=1; break; }

else day=day+1; break;

case 9: if( day==30) {

month++; day=1; break; }

else day=day+1; break;

case 10: if( day==31) {

month++; break; }

day=1;

else day=day+1; break;

case 11: if( day==30) {

month++; day=1; break;

}

else day=day+1;

break;

case 12: if( day==31) { year++;

month=1; day=1; break;

}

else day=day+1;

break;

default:break;

} }

}

/*日历显示调整模块*/ void calendar(void) {

if(P1_3==0) /*日历调整键盘扫描子程序*/ //日期调整, p1_0日, {

//日的调整,下降沿有效

if(P1_0!=a)

{ delay(10); if(P1_0==0) {

if(month==1||month==3||month==5||month==7||month==8||month==10) {

if(day==31) { day=1;month++; } else day=day+1; }

if(month==12) {

if(day==31){

day=1;month=1;year++;} else day=day+1;

}

else if(month==4||month==6||month==9||month==11) {

if(day==30){

p1_1月,p1_2年 day=1;month++;} else day=day+1; }

else if(month==2) {

if((year%400==0)||(year%4==0&&year%100!=0)) {

if(day==29){ day=1;month++;} else day=day+1; }

else if(day==28){ day=1; month++;} else day=day+1; } }a=P1_0; }

if(P1_1!=b) //月的调整,下降沿有效 {

delay(10); if(P1_1==0) {

if(month==12) { month=1;year++;} else month=month+1;

if((day==31)&&(month==2||month==4||month==6||month==9||month==11)) day=1;

if(day==30&&month==2) day=1;

if(day==29&&month==2)

if(!((year%400==0)||(year%4==0)&&(year%100!=0))) }

if(P1_2!=c) {

delay(10); if(P1_2==0) {

year=year+1;

if(!((year%400==0)||(year%4==0)&&(year%100!=0))) if(month==2&&day==29)

day=1; }c=P1_2;

day=1; }b=P1_1;

}

/*日历显示模块*/ P3=0Xfe;

P0=dispcode[(year/1000)];//年千位 delay(2); P3=0Xfd;

P0=dispcode[((year/100)%10)];//年百位 delay(2); P3=0Xfb;

P0=dispcode[((year/10)%100)];//年十位 delay(2); P3=0Xf7;

P0=dispcode[(year%10)];//年个位 delay(2); P3=0Xf7;

P0=dispcode[11];//. delay(2); P3=0Xef;

P0=dispcode[(month/10)];//月十位 delay(2); P3=0Xdf;

P0=dispcode[month%10];//月个位 delay(2); P3=0Xdf;

P0=dispcode[11];//年个位 delay(2); P3=0Xbf;

P0=dispcode[day/10];//日十位 delay(2); P3=0X7f;

P0=dispcode[day%10];//日个位 delay(2); } }

void timer0(void) interrupt 1 //定时器0方式1,10ms中断一次 {

TH0=0xd8; //手动加载计数脉冲次数 TL0=0xf0;

TMOD=0x11; //使用16位定时器

mstcnt++; //用于计算时间,每隔10ms加1 if(mstcnt==100)//mstcnt满10即为一秒 {

seconde++;//秒+1

mstcnt=0; //对计数单元的清零,重新开始计数

} } /*主函数*/ void main(void) { P1=0Xff;

TMOD = 0x11; //time0为定时器,方式1 TH0=0xd8;

TL0=0xf0; //预置计数初值,10ms EA=1; //总中断开

ET0=1; //允许定时器0中断 ET1=1;

TR0=1; //开启定时器0 TR0=1; while (1) {

time_pro( ); //时间处理 display( ); //显示时间

dateadd(dateadd1); //日历处理子程序 calendar( ); //日历显示子程序 } }

六、成品:

七、

总结

本次是我第一次参加电子竞赛,通过这次电子竞赛使我基本掌握了51单片机、数码管、74LS245芯片等的运用。同时使我深化了对keil、protues、Altium designer等单片机设计必用软件的理解。在整个设计过程中,充分发挥人的主观能动性,自主学习,学到了许多课本上学不到的知识。虽然在设计中出现了一些不应该出现的问题,但是经过我不断的努力,可以说是较好的完成了作品,达到了预期的目的。在电路焊接时虽然没什么大问题,但从中也知道了焊接在整个作品中的重要性,完美性,电路工程虽小,但是不能急,一个个慢慢来不能急于求成。

对电路的设计、布局要先有一个好的构思,才显得电路板美观、大方。程序编写中,由于思 路不清晰,开始时遇到了很多的问题,经过静下心来思考,理清了思路,反而得心应手。在此次设计中,知道了做凡事要有一颗平常的心,不要想着走捷径,一步一脚印,也练就了我的耐心。

总之通过此次单片机设计大赛不仅使我学到了很多东西,而且使我的能力得到了全方位的提高。

因篇幅问题不能全部显示,请点此查看更多更全内容