单片机课程设计---电子万年历设计

合集下载

单片机课程设计-万年历

单片机课程设计-万年历

一、课程设计名称万年历二、课程设计目的1、掌握单片机的原理、应用。

2、学会利用单片机设计电路。

3、培养大家的创新意识及动手能力。

三、课程设计内容(一)方案设计我们组设计的万年历是以一片40引脚的单片机AT89C52为主体,结合16位定时器/计数器和LED数码管等元器件来实现的,主要有几个单元电路构成,分别是复位电路、振荡电路、按键电路、整点报时电路和显示电路,下面给出了电路框图及其分析和说明。

1、复位电路此单元电路为手动复位电路,由按键、电解电容、电阻等构成,与单片机的RST引脚相连接,在单片机运行过程中可以随时按键复位,电路图如图1所示:图-1 复位电路2、振荡电路此单元电路由晶振和电容构成,其中的晶振频率为12MHz,与单片机的XTAL1和XTAL2引脚相连接,具体电路如图2所示:图-2振荡电路3、调整电路此单元电路主要由多个弹性按键构成,在所设计的电路中与单片机的I/O(P1)口相连接,具体电路可参考图3:图-3按键调整电路图中的按键K0、K1、K2、K3分别具有不同的功能,其中K0、K1、K2用于校准,K0调节小时(或年)、K1调节分(或月)、K2调节秒(或日);K3用于切换,启动时万年历显示的为时分秒,当按下K3时可以切换到年月日显示界面。

4、整点报时电路此部分电路通过采用晶体管驱动蜂鸣器实现的,每当显示时间出现整点时(如12:00:00),蜂鸣器会发出短暂响声,起到整点报时功能。

实际电路中与单片机的P1.3相连接,具体电路可参照图4:图-4整点报时电路5、显示电路此单元电路为万年历的显示屏,由共阳数码管构成,采用动态扫描的方式来显示年月日和时分秒,示意图如图5所示:图-5数码管显示电路注意:实际中电路与上述电路不同,稍复杂些,而且采用的是两个四位一体的数码管,还要接限流电阻(较小,如470欧)和晶体管(如9012)。

(二)系统硬件设计该系统主要由时钟电路部分、中央处理单元、数码管显示部分组成,各组成部分如图所示。

单片机课设 电子万年历

单片机课设 电子万年历

《单片机原理及应用》课程设计题目:万年历设计姓名:学号:系别:专业:年级:2008起讫日期:2010.11.22 ~2010.12.3指导教师:职称:目录1.设计概述 (1)2.硬件电路图 (3)3.软件设计 (5)3.1流程图 (5)3.2程序 (7)4. 结论4.1测试结果 (12)4.2遇到问题 (12)5.3如何解决 (12)5.参考文献 (13)附录:电路图 (15)组员分工 (14)1、设计概述单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。

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

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

本设计就是应用单片机强大的控制功能制作而成的电子万年历,该电子万年历包括三大功能:实时显示年、月、日、时、分、秒、周期。

本设计采用的是AT89S52单片机,该单片机采用的MCU51内核,因此具有很好的兼容性,内部带有8KB的ROM,能够存储大量的程序。

计时芯片采用DALLAS公司的涓细充电时钟芯片DS1302,该芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时分、秒信息。

显示器件采用通用型1602液晶,可显示32个字符,如果使用数码管来做显示器件需消耗大量的系统资源,因此采用低功耗的1602液晶,该液晶显示方便,功能强大,完全能满足数字万年历的显示要求。

综上各方案所述,对此次作品的方案选定: 采用AT89S52作为主控制系统; DS1302提供时钟;LCD液晶显示屏作为显示。

通过此次设计能够更加牢固的掌握单片机的应用技术,增强动手能力、硬件设计能力以及软件设计能力。

2、硬件电路图1.时钟芯片2.LCD1602液晶显示屏3.单片机芯片C523、软件设计3.1流程图主程序流程图3.2程序#include <REG51.H>#include <intrins.h>//#include "LCD1602.h"//#include "DS1302.h"#define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //实时时钟时钟线引脚sbit DS1302_IO = P1^6; //实时时钟数据线引脚sbit DS1302_RST = P1^5; //实时时钟复位线引脚sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;charhide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数sbit Set = P2^0; //模式切换键sbit Up = P2^1; //加法按钮sbit Down = P2^2; //减法按钮sbit out = P2^3; //立刻跳出调整模式按钮char done,count,temp,flag,up_flag,down_flag;uchar TempBuffer[5],week_value[2];void show_time(); //液晶显示程序/***********1602液晶显示部分子程序****************///PortDefinitions********************************************************** sbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口//内部等待函数//******************************************************************* *******unsigned char LCD_Wait(void){LcdRs=0;LcdRw=1; _nop_();LcdEn=1; _nop_(); LcdEn=0;return DBPort;}//向LCD写入命令或数据//************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){LcdEn=0;LcdRs=style;LcdRw=0; _nop_();DBPort=input;_nop_();//注意顺序LcdEn=1; _nop_();//注意顺序LcdEn=0; _nop_();LCD_Wait();}//设置显示模式************************************************************#define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关#define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标#define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动void LCD_SetDisplay(unsigned char DisplayMode){LCD_Write(LCD_COMMAND, 0x08|DisplayMode); }//设置输入模式************************************************************#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default#define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //defaultvoid LCD_SetInput(unsigned char InputMode){LCD_Write(LCD_COMMAND, 0x04|InputMode);}//初始化LCD************************************************************void LCD_Initial(){LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}//液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}//将字符输出到液晶显示void Print(unsigned char *str){while(*str!='\0'){LCD_Write(LCD_DATA,*str);str++;}}/***********DS1302时钟部分子程序******************/typedef struct __SYSTEMTIME__{unsigned char Second;unsigned char Minute;unsigned char Hour;unsigned char Week;unsigned char Day;unsigned char Month;unsigned char Year;unsigned char DateString[11];unsigned char TimeString[9];}SYSTEMTIME; //定义的时间类型SYSTEMTIME CurrentTime;#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 0x8Cvoid DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) { unsigned char i;ACC = d; for(i=8; i>0; i--){DS1302_IO = ACC0; //相当于汇编中的 RRCDS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } }unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) { unsigned char i; for(i=8; i>0; i--){ ACC = ACC >>1; //相当于汇编中的 RRCACC7 = 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_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组{unsigned char ReadValue;ReadValue = Read1302(DS1302_SECOND);Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);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); } void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22{ Time->DateString[0] = '2';Time->DateString[1] = '0';Time->DateString[2] = Time->Year/10 + '0';Time->DateString[3] = Time->Year%10 + '0';}else{ Time->DateString[0] = ' '; Time->DateString[1] = ' ';Time->DateString[2] = ' '; Time->DateString[3] = ' ';}Time->DateString[4] = '/';if(hide_month<2){Time->DateString[5] = Time->Month/10 + '0';Time->DateString[6] = Time->Month%10 + '0';}else{ Time->DateString[5] = ' '; Time->DateString[6] = ' ';}Time->DateString[7] = '/';if(hide_day<2){Time->DateString[8] = Time->Day/10 + '0';Time->DateString[9] = Time->Day%10 + '0';}else{Time->DateString[8] = ' ';Time->DateString[9] = ' '; } if(hide_week<2){week_value[0] = Time->Week%10 + '0'; } //星期的数据另外放到week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示} else { week_value[0] = ' ';}week_value[1] = '\0';Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符}void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];{ if(hide_hour<2){ Time->TimeString[0] = Time->Hour/10 + '0';Time->TimeString[1] = Time->Hour%10 + '0';}else{ Time->TimeString[0] = ' ';Time->TimeString[1] = ' ';}Time->TimeString[2] = ':';if(hide_min<2){ Time->TimeString[3] = Time->Minute/10 + '0';Time->TimeString[4] = Time->Minute%10 + '0';}else {Time->TimeString[3] = ' ';Time->TimeString[4] = ' '; }Time->TimeString[5] = ':';if(hide_sec<2){Time->TimeString[6] = Time->Second/10 + '0';Time->TimeString[7] = Time->Second%10 + '0';}else{Time->TimeString[6] = ' ';Time->TimeString[7] = ' '; } Time->DateString[8] = '\0';}void Initial_DS1302(void) //时钟芯片初始化{ unsigned char Second=Read1302(DS1302_SECOND);if(Second&0x80) //判断时钟芯片是否关闭{Write1302(0x8e,0x00); //写入允许Write1302(0x8c,0x07); //以下写入初始化时间日期:07/07/25.星期: 3.时间: 23:59:55Write1302(0x88,0x07);Write1302(0x86,0x25);Write1302(0x8a,0x07);Write1302(0x84,0x23);Write1302(0x82,0x59);Write1302(0x80,0x55);Write1302(0x8e,0x80); //禁止写入}}void Delay1ms(unsigned int count){unsigned int i,j;for(i=0;i<count;i++)for(j=0;j<120;j++);}/*延时子程序*/void mdelay(uint delay){ uint i;for(;delay>0;delay--){for(i=0;i<62;i++) //1ms延时. {;}}}void outkey() //跳出调整模式,返回默认显示{ uchar Second;if(out==0) { mdelay(8); count=0;hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_mon th=0,hide_year=0;Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0; while(out==0); }}///////////////////////////////////////////////////////////////////// //////////void Upkey()//升序按键{ Up=1;if(Up==0){mdelay(8);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=temp+1; //秒数加1up_flag=1; //数据调整后更新标志if((temp&0x7f)>0x59) //超过59秒,清零temp=0; break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=temp+1; //分数加1up_flag=1;if(temp>0x59) //超过59分,清零temp=0;break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=temp+1; //小时数加1up_flag=1;if(temp>0x23) //超过23小时,清零temp=0; break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数temp=temp+1; //星期数加1up_flag=1;if(temp>0x7)temp=1;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=temp+1; //日数加1up_flag=1;if(temp>0x31)temp=1;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=temp+1; //月数加1up_flag=1;if(temp>0x12)temp=1;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=temp+1; //年数加1up_flag=1;if(temp>0x85)temp=0;break;default:break;}while(Up==0); }}///////////////////////////////////////////////////////////////////// //////////void Downkey()//降序按键{ Down=1;if(Down==0){ mdelay(8);switch(count){case 1:temp=Read1302(DS1302_SECOND); //读取秒数temp=temp-1; //秒数减1down_flag=1; //数据调整后更新标志if(temp==0x7f) //小于0秒,返回59秒temp=0x59;break;case 2:temp=Read1302(DS1302_MINUTE); //读取分数temp=temp-1; //分数减1down_flag=1;if(temp==-1)temp=0x59; //小于0秒,返回59秒break;case 3:temp=Read1302(DS1302_HOUR); //读取小时数temp=temp-1; //小时数减1down_flag=1;if(temp==-1)temp=0x23;break;case 4:temp=Read1302(DS1302_WEEK); //读取星期数temp=temp-1; //星期数减1down_flag=1;if(temp==0)temp=0x7;;break;case 5:temp=Read1302(DS1302_DAY); //读取日数temp=temp-1; //日数减1down_flag=1;if(temp==0)temp=31;break;case 6:temp=Read1302(DS1302_MONTH); //读取月数temp=temp-1; //月数减1down_flag=1;if(temp==0)temp=12;break;case 7:temp=Read1302(DS1302_YEAR); //读取年数temp=temp-1; //年数减1down_flag=1;if(temp==-1)temp=0x85;break;default:break;}while(Down==0); }}void Setkey()//模式选择按键{Set=1;if(Set==0){ mdelay(8); count=count+1; //Setkey按一次,count就加1 done=1; //进入调整模式while(Set==0); }}void keydone()//按键功能执行{ uchar Second;if(flag==0) //关闭时钟,停止计时{ Write1302(0x8e,0x00); //写入允许temp=Read1302(0x80);Write1302(0x80,temp|0x80);Write1302(0x8e,0x80); //禁止写入flag=1; }Setkey(); //扫描模式切换按键 switch(count){case 1:do //count=1,调整秒{ outkey(); //扫描跳出按钮Upkey(); //扫描加按钮Downkey(); //扫描减按钮if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据{Write1302(0x8e,0x00); //写入允许Write1302(0x80,temp|0x80); //写入新的秒数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_sec++; //位闪计数if(hide_sec>3)hide_sec=0;show_time(); //液晶显示数据}while(count==2);break;case 2:do //count=2,调整分{ hide_sec=0;outkey();Upkey();Downkey();if(temp>0x60)temp=0;if(up_flag==1||down_flag==1){ Write1302(0x8e,0x00); //写入允许Write1302(0x82,temp); //写入新的分数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_min++;if(hide_min>3)hide_min=0;show_time();}while(count==3);break;case 3:do //count=3,调整小时{ hide_min=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){ Write1302(0x8e,0x00); //写入允许Write1302(0x84,temp); //写入新的小时数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_hour++;if(hide_hour>3)hide_hour=0;show_time();}while(count==4);break;case 4:do //count=4,调整星期{ hide_hour=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){ Write1302(0x8e,0x00); //写入允许Write1302(0x8a,temp); //写入新的星期数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0;}hide_week++;if(hide_week>3)hide_week=0;show_time();}while(count==5);break;case 5:do //count=5,调整日{hide_week=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){Write1302(0x8e,0x00); //写入允许Write1302(0x86,temp); //写入新的日数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_day++;if(hide_day>3)hide_day=0;show_time();}while(count==6);break;case 6:do //count=6,调整月{ hide_day=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){ Write1302(0x8e,0x00); //写入允许Write1302(0x88,temp); //写入新的月数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_month++;if(hide_month>3)hide_month=0;show_time();}while(count==7);break;case 7:do //count=7,调整年{ hide_month=0;outkey();Upkey();Downkey();if(up_flag==1||down_flag==1){ Write1302(0x8e,0x00); //写入允许Write1302(0x8c,temp); //写入新的年数Write1302(0x8e,0x80); //禁止写入up_flag=0;down_flag=0; }hide_year++;if(hide_year>3)hide_year=0;show_time();}while(count==8);break;case 8: count=0;hide_year=0; //count8, 跳出调整模式,返回默认显示状态Second=Read1302(DS1302_SECOND);Write1302(0x8e,0x00); //写入允许Write1302(0x80,Second&0x7f);Write1302(0x8E,0x80); //禁止写入done=0;break; //count=7,开启中断,标志位置0并退出default:break; }}void show_time() //液晶显示程序{ DS1302_GetTime(&CurrentTime); //获取时钟芯片的时间数据TimeToStr(&CurrentTime); //时间数据转换液晶字符DateToStr(&CurrentTime); //日期数据转换液晶字符GotoXY(0,1);Print(CurrentTime.TimeString); //显示时间GotoXY(0,0);Print(CurrentTime.DateString); //显示日期GotoXY(15,0);Print(week_value); //显示星期GotoXY(11,0);Print("Week"); //在液晶上显示字母 weekDelay1ms(400); //扫描延时}void main(){ flag=1; //时钟停止标志LCD_Initial(); //液晶初始化Initial_DS1302(); //时钟芯片初始化up_flag=0;down_flag=0;done=0; //进入默认液晶显示while(1){ while(done==1) keydone(); //进入调整模式while(done==0){ show_time(); //液晶显示数据flag=0; Setkey(); //扫描各功能键}}}4、结论4.1测试结果经过多次的反复测试与分析,可以对电路的原理及功能更加熟悉,同时提高了设计能力与及对电路的分析能力。

单片机课程设计报告电子万年历

单片机课程设计报告电子万年历

单片机课程设计报告电子万年历单片机课程设计报告:电子万年历一、设计简介在本次单片机课程设计中,我们选择了电子万年历作为设计主题。

电子万年历是一种结合了数字电路、单片机技术和实时时钟(RTC)技术的电子产品,它具有显示年份、月份、星期、日、时、分、秒的功能,还可以根据用户的需求进行定时、闹钟、报时等功能。

二、硬件设计我们采用了基于8051内核的单片机作为主控芯片。

该单片机具有丰富的I/O 端口,适于实现各种复杂的输入输出操作。

此外,它还内置了定时器和中断控制器,可以很方便地实现实时时钟功能。

1.显示模块:为了方便用户查看时间信息,我们选用了LCD显示屏作为显示设备。

LCD屏具有功耗低、体积小、显示内容丰富等优点。

2.实时时钟(RTC)模块:我们采用了常用的DS1302芯片作为实时时钟模块。

该芯片可以提供秒、分、时、日、星期、月、年的信息,而且还有可编程的报警功能。

3.按键模块:为了实现人机交互,我们设计了一组按键。

用户可以通过按键来调整时间、设置闹钟等。

4.电源模块:为了保证系统的稳定工作,我们采用了稳定的5V直流电源。

三、软件设计我们采用了C语言编写程序。

程序主要由以下几个部分组成:1.主程序:主程序主要负责读取RTC模块的时间信息,并控制LCD显示屏显示时间。

同时,主程序还要检测按键输入,根据用户的需求进行相应的操作。

2.RTC驱动程序:为了正确地读取和设置DS1302芯片的时间信息,我们编写了相应的驱动程序。

驱动程序包括初始化和读写寄存器两部分。

3.按键处理程序:按键处理程序用于检测按键输入,并根据按键值执行相应的操作。

比如,用户可以通过按键来增加或减少时间,设置闹钟等。

4.LCD显示程序:LCD显示程序用于控制LCD显示屏的显示内容。

在本设计中,我们使用了点阵字符库,将时间信息以字符的形式显示在LCD屏上。

四、测试与验证为了确保我们的电子万年历设计正确无误,我们进行了以下的测试和验证:1.硬件测试:首先,我们对硬件电路进行了测试,确保每个模块都能正常工作。

单片机课程设计(论文)电子万年历的设计

单片机课程设计(论文)电子万年历的设计

目录1设计要求 (2)2方案论证与对比 (2)液晶显示器控制方式选择 (2)2.2并行接口动态显示电路选择 (2)2.3LCD液晶显示器的接口方法选择 (3)液晶显示器限流电阻选择 (4)3系统硬件电路的设计 (5)主控模块AT89C52 (5)3.2显示模块电路设计 (6)4系统软件设计 (7)4.1系统软件概述 (7)4.2主要子程序设计 (8)4.2.1 时钟中断服务子程序设计 (8)时间调整子程序设计 (9)4.2.3 判断闰年子程序设计 (9)4.2.4 精度分析分析与计算 (10)4.2.5 第一次初值的设置 (10)4.2.6 重载初值的方法 (10)5系统仿真与测试 (11)5.1系统仿真 (11)功能测试 (11)6总结 (12)参考文献 (13)1设计要求本课题以AT89C52单片机为核心,设计并制作出智能LCD电子钟,具有以下基本功能:能进行时间、年份、日期、星期显示;能区分是否闰年;能检测室温并显示。

扩展功能部分可以通过控制按键使时间暂停、可以调整校正时间并通过按键切换轮流显示时间、年份、日期、星期。

2方案论证与对比2.1液晶显示器控制方式选择采用LCD液晶显示,具有超精致影像画质、十足平面显示、节省空间、节省能源等优点,但按控制方式不同,LCD可分为被动矩阵式LCD及主动矩阵式LCD两种。

可根据不同需要采用不同的方式。

方案一被动矩阵式LCD被动矩阵式LCD在亮度及可视角方面受到较大的限制,反应速度也较慢。

由于画面质量方面的问题,使得这种显示设备不利于发展为桌面型显示器,但成本低廉。

方案二主动矩阵式LCD目前应用比较广泛的主动矩阵式LCD,也称TFT-LCD(Thin Film Transistor-LCD,薄膜晶体管LCD)。

TFT液晶显示器是在画面中的每个像素内建晶体管,可使亮度更明亮、色彩更丰富及更宽广的可视面积。

与CRT显示器相比,LCD显示器的平面显示技术体现为较少的零件、占据较少的桌面及耗电量较小,但CRT技术较为稳定成熟。

单片机课程设计报告 电子万年历

单片机课程设计报告 电子万年历

题目:电子万年历设计报告课程名称单片机课程设计学院物理与光电工程学院专业班级 09级电子科学与技术5班学号姓名王周英联系方式任课教师陈国鼎2011年12月12日电子万年历设计报告1)设计题目题目:电子万年历设计2)设计任务和要求1、显示年月日时分秒及星期信息。

2、具有可调整日期和时间功能3、增加闰年计算功能4、实现语音报时3)原理电路和程序设计:(1)方案比较;一:控制MCU方案一:STM8,STM公司推出的新款MCU,性能高,外设资源丰富,带有12位AD、12位DA、脉宽调制PWM、最高机器周期16MHz等。

且其功耗非常小,价格便宜,性价比非常高。

缺点是只能用官方开发的S-Link下载器进行下载,其价格比较高,一般学习者手上都没有。

方案二:AT89S52,AT公司的51单片机。

优点是支持ISP在线下载;缺点是价格比较高。

方案三:STC89C52,宏晶公司的51系列单片机,价格便宜,在国内使用者非常多。

支持串口下载,使用非常方便,且具有很大的价格优势。

缺点是仅支持串口下载,不支持在线下载,使用中会有些不方便。

由于本设计对控制芯片的要求不高,因此选用方案三。

二:时钟模块方案一:用单片机的定时器产生1S的时基信号,然后用程序来实现时钟的时、分、秒计时,同时用程序来产生年、月、日。

该方案优点是减少使用外设芯片;缺点是用单片机模拟时钟,使编程量增大,且用定时器产生时基信号,精度不高。

方案二:使用时钟芯片DS12C887。

优点是8位数据线并行控制,控制简单;自带有锂电池,外部掉电时,其内部时间信息还能够保持 10年之久。

缺点是并行控制,占用太多的IO口,且价格很高,不适合一般的电子制作。

方案三:使用时钟芯片DS1302。

优点是同步串行通信,仅使用3个IO口,占用最少的单片机资源;其内部功能强大。

更重要的是其价格便宜,具有非常高的性价比。

缺点是串行通信,控制比较复杂。

综上,本设计选择方案三。

三:语音报时模块方案一:使用语音芯片BLA902。

电子万年历单片机课程设计

电子万年历单片机课程设计

目录1 前言 (1)2 需求分析 (1)2.1 任务和要求 (1)2.2 运行环境 (1)2.3 开发工具 (1)3 分析和设计 (1)3.1 系统分析及设计思路 (1)3.2 主要数据结构及算法 (2)3.3 函数流程图....................................................... 错误!未定义书签。

4 具体代码实现............................................................. 错误!未定义书签。

5 课程设计总结............................................................. 错误!未定义书签。

5.1 程序运行结果或预期运行结果....................... 错误!未定义书签。

5.2 设计结论........................................................... 错误!未定义书签。

参考文献......................................................................... 错误!未定义书签。

致谢............................................................................. 错误!未定义书签。

1 前言电子万年历是实现对年,月,日,时,分,秒数字显示的计时装置,广泛用于个人家庭,车站,码头,办公室,银行大厅等场所,成为人们日常生活中的必需品。

数字集成电路的发展和石英晶体振荡器的广泛应用,使得数字钟的精度远远超过老式钟表。

钟表的数字化给人们生产生活带来了极大的方便,在此基础上完成的万年历精度高,功能易于扩展。

可扩展成为诸如定时自动报警、按时自动打铃、时间程序自动控制、定时广播、自动起闭路灯、定时开关烘箱、通断动力设备、甚至各种定时电气的自动启用等电路。

单片机万年历课程设计

单片机万年历课程设计

单片机万年历课程设计一、课程目标知识目标:1. 让学生理解单片机的基本原理和万年历的功能需求。

2. 使学生掌握单片机编程的基本语法和逻辑结构。

3. 帮助学生掌握如何在单片机上实现日期、时间的计算与显示。

技能目标:1. 培养学生运用单片机进行项目设计的能力,特别是万年历的实际应用。

2. 培养学生独立编程和调试程序的能力,解决实际项目中遇到的问题。

3. 提高学生团队协作能力和项目管理的意识。

情感态度价值观目标:1. 培养学生对单片机及电子制作的兴趣,激发学生的创新意识和探索精神。

2. 增强学生面对困难的勇气和毅力,培养他们积极解决问题的态度。

3. 通过团队合作,培养学生的集体荣誉感和责任感。

课程性质:本课程为实践性强的设计与制作课程,以单片机技术为核心,结合编程和电子技术,实现万年历的制作。

学生特点:学生为高年级学生,已具备一定的单片机基础知识,有编程基础,具备独立思考和解决问题的能力。

教学要求:注重理论与实践相结合,强调动手操作和实际应用。

教学过程中要关注学生的个体差异,提供适当的指导与帮助,确保每个学生都能在原有基础上得到提升。

通过课程学习,使学生能够将所学知识应用于实际项目中,达到学以致用的目的。

二、教学内容1. 单片机基础回顾:复习单片机的硬件结构、工作原理及I/O口编程。

- 教材章节:第三章单片机硬件结构与工作原理;第四章I/O口编程。

2. 定时器与中断:学习单片机定时器的工作原理,掌握中断编程方法。

- 教材章节:第五章定时器与中断;第六章中断编程。

3. 日期时间计算:讲解日期时间的计算方法,如何在单片机中进行实现。

- 教材章节:第七章日期时间计算;第八章单片机实现日期时间计算。

4. 显示技术:学习LED显示技术,掌握动态扫描显示方法。

- 教材章节:第九章LED显示技术;第十章动态扫描显示。

5. 万年历设计与实现:结合所学知识,设计并实现单片机万年历。

- 教材章节:第十一章项目设计与实现;第十二章万年历设计与制作。

单片机万年历课程设计报告

单片机万年历课程设计报告

单片机万年历课程设计报告一、课程设计目标本课程设计旨在帮助学生掌握单片机应用基础知识,学习并完成万年历电路的设计和代码编写。

通过这个实践,学生将会深入理解单片机在实际生活中的应用,同时提升自己的程序设计和解决问题的能力。

二、课程设计内容1. 万年历电路的原理和设计本次课程设计要求学生完成一个万年历电路的设计,包括硬件电路和程序设计。

在电路设计中,学生需要考虑到显示器、时钟模块、日期模块和温湿度传感器等部分的连接和调试。

在程序设计方面,学生需要实现万年历的功能,包括显示当前日期和时间、自动确定闰年、节假日提示等。

2. 单片机基本原理和应用实践在万年历电路设计之前,本课程将会对单片机基本原理进行介绍,包括单片机内部结构、芯片选型和I/O口控制等。

另外,还将介绍单片机在各种应用场景中的应用实践,如遥控、电脑控制、机器人和智能家居等。

3. 问题解决和困难克服在学生完成万年历电路设计的过程中,难免会遇到各种问题和困难。

本课程将对学生进行相关的实用技巧和方法讲解,帮助他们解决问题和克服难关。

三、课程设计流程1. 单片机基础知识介绍(2学时)讲解单片机内部结构及其原理,并介绍单片机应用实践2. 万年历电路设计(12学时)对万年历的硬件和软件进行介绍,包括连接显示器和外设、编写程序等3. 问题解决(2学时)介绍学生应对问题的技巧和方法,并帮助他们克服电路设计中的问题和难点四、课程设计评价标准1. 设计成果设计成果的好坏是课程设计的重要衡量标准之一,包括电路的设计完整性、软件功能实现等方面。

2. 实践能力课程设计是一种实践性强的学习形式,学生需要通过实践来掌握知识,因此他们的实践能力成为衡量标准之一。

3. 团队合作在课程设计的过程中,学生要协同工作,完成一个大型的项目,因此团队合作能力是衡量标准之一。

4. 学习的态度学习态度是衡量标准之一,包括学生在课程设计中的主动性、积极性和责任感等方面。

五、总结通过这个万年历课程设计,学生不仅学会了单片机应用的基础知识,还掌握了实际项目开发的方法和技巧。

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

《单片机原理及接口技术》课程设计论文题目电子万年历设计电子万年历设计摘要论文详细介绍了用单片机制作电子万年历的设计过程。

其中包括秒表、日期等。

利用单片机控制LED数码管并显示出来当前日历和秒表出来。

在论文里简要介绍了单片机AT89C51的引脚封装及引脚功能。

本设计中有keil4软件的C语言来编写程序,仿真电路图用proteus来仿真电路图。

关键词单片机,电子万年历,LED数码管ABSTRACTThe paper introduces in detail the design of the electronic perpetual calendar chip production process. Including the stopwatch, date etc.. SCM control LED digital tube and display the current calendar and stopwatch. In the thesis briefly introduces the AT89C51 MCU pins on the package and pin function. The design of keil4software in C language to write procedures, simulation circuit using Proteus to simulate the circuit diagram.Key Words MCU, electronic perpetual calendar chip, LED digital tube目录1.单片机原理及应用简介 (4)2.系统硬件设计 (4)2.1 80C51简介 (4)2.1.1 AT80C51的显着特点 (5)2.1.2 80C5140个引脚功能 (5)2.2外部时钟电路 (7)2.3 74HC138 (8)2.4 7段数码管 (8)3仿真电路 (10)4.设计总结 (11)参考文献 (12)附录 (12)1.单片机原理及应用简介随着国内超大规模集成电路的出现,微处理器及其外围芯片有了迅速的发展。

集成技术的最新发展之一是将CPU和外围芯片,如程序存储器、数据存储器、并行、串行I/O口、定时/计数器、中断控制器及其他控制部件集成在一个芯片之中,制成单片计算机(Single-Chip Microcomputer)。

而近年来推出的一些高档单片机还包括有许多特殊功能单元,如A/D、D/A转换器、调制解调器、通信控制器、锁相环、DMA、浮点运算单元等。

因此,只要外加一些扩展电路及必要的通道接口就可以构成各种计算机应用系统,如工业控制系统、数据采集系统、自动测试系统、万年历电子表等。

2.系统硬件设计2.1 80C51简介80C51是标准的40引脚双列直插式集成电路芯片,引脚分布请参照----单片机引脚图图1:图1 80C512.1.1 AT80C51的显着特点AT80C51应用普遍,价格便宜有如下显著特点:CPU系统:8为CPU,含布尔处理器,时钟电路,总线控制。

存储器系统:4K字节的程序存储器(ROM/EPROM/Flash,可扩展至64K);128字节的数据存储器(RAM,可扩展至64K);特殊功能寄存器SFR。

I/O口和其他功能单元:4个并行I/O口(P0,P1,P2,P3);2个16位定时、计数器;1个全双攻异步串行口(UART);中断系统(5个中断源,2个优先级)。

2.1.2 80C5140个引脚功能VCC:供电电压。

GND:接地。

P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。

当P1口的管脚第一次写1时,被定义为高阻输入。

P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。

P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。

在FLASH 编程和校验时,P1口作为第八位地址接收。

P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。

并因此作为输入时,P2口的管脚被外部拉低,将输出电流。

这是由于内部上拉的缘故。

P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。

在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。

P2口在FLASH编程和校验时接收高八位地址信号和控制信号。

P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL 门电流。

当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。

作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。

P3口也可作为AT89C51的一些特殊功能口,如下表所示:口管脚备选功能P3.0 RXD(串行输入口)P3.1 TXD(串行输出口)P3.2 /INT0(外部中断0)P3.3 /INT1(外部中断1)P3.4 T0(记时器0外部输入)P3.5 T1(记时器1外部输入)P3.6 /WR(外部数据存储器写选通)P3.7 /RD(外部数据存储器读选通)P3口同时为闪烁编程和编程校验接收一些控制信号。

RST:复位输入。

当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。

ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。

在FLASH编程期间,此引脚用于输入编程脉冲。

在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。

因此它可用作对外部输出的脉冲或用于定时目的。

然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。

如想禁止ALE的输出可在SFR8EH地址上置0。

此时, ALE 只有在执行MOVX,MOVC指令是ALE才起作用。

另外,该引脚被略微拉高。

如果微处理器在外部执行状态ALE禁止,置位无效。

/PSEN:外部程序存储器的选通信号。

在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。

但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。

/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。

注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。

在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。

XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。

XTAL2:来自反向振荡器的输出。

编辑本段振荡器特性XTAL1和XTAL2分别为反向放大器的输入和输出。

该反向放大器可以配置为片内振荡器。

石晶振荡和陶瓷振荡均可采用。

如采用外部时钟源驱动器件,XTAL2应不接。

有余输入至内部时钟信号要通过一个二分频触发器,因此对外部时钟信号的脉宽无任何要求,但必须保证脉冲的高低电平要求的宽度。

编辑本段芯片擦除整个PEROM阵列和三个锁定位的电擦除可通过正确的控制信号组合,并保持ALE管脚处于低电平10ms 来完成。

在芯片擦操作中,代码阵列全被写“1”且在任何非空存储字节被重复编程以前,该操作必须被执行。

此外,AT80C51设有稳态逻辑,可以在低到零频率的条件下静态逻辑,支持两种软件可选的掉电模式。

在闲置模式下,CPU停止工作。

但RAM,定时器,计数器,串口和中断系统仍在工作。

在掉电模式下,保存RAM的内容并且冻结振荡器,禁止所用其他芯片功能,直到下一个硬件复位为止。

2.2外部时钟电路80C51单片机的时钟信号通常有两种方式完成:内部时钟和外部时钟方式。

本设计中用内部时钟完成,在单片机的XTAL1和XTAL2引脚外接晶振即可,电容器C1和C2的作用是稳定频率和快速起振。

内部时钟方式如下图所示。

图2 内部时钟方式电路单片机内部晶振频率为11.0592Mhz.电容C1,C2为22pf,C3为10uf。

2.3 74HC13874HC138是一款高速CMOS器件,74HC138引脚兼容低功耗肖特基TTL(LSTTL)系列。

在本设计中主要起到地址所存的作用。

74HC138原件图如下图所示。

图3 74HC138原件图74HC138译码器可接受3位二进制加权地址输入(A0, A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。

74HC138特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。

除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。

利用这种复合使能特性,仅需4片74HC138芯片和1个反相器,即可轻松实现并行扩展,组合成为一个1-32(5线到32线)译码器。

任选一个低有效使能输入端作为数据输入,而把其余的使能输入端作为选通端,则74HC138亦可充当一个8输出多路分配器,未使用的使能输入端必须保持绑定在各自合适的高有效或低有效状态。

2.4 7段数码管本设计中用的7段数码管为7SEG-MPX8-CC-BLUE,本设计中该元器件主要显示日期和秒表,元器件图所下图所示。

图4 数码管7SEG-MPX8-CC-BLUE为共阴极数码管,ABCDEFG为段选信号,给高电平相应的段就会亮。

12345678引脚选中就会使相应的数码管起作用,为开关作用信号,如下图k1-k8的作用。

图5 LED灯图6 8位数码管显示3仿真电路本设计中在proteus里的仿真电路图如下图所示。

左边数码管显示日期,右边数码管显示秒表。

图7 仿真电路图本设计的目标显示12-06-27,秒表及时。

仿真结果若下图所示。

图8 仿真结果4.设计总结通过这一周的课程设计,我学到了不少的知识。

把以前没有学好的模拟电路的知识进行了补充和加强。

这使我受益很大。

加深了我对于单片机和数字电路的认识,相信在以后的学习和工作中碰到这些基础的元器件我会更加得心应手。

通过查阅大量的资料,我获得了以前在课堂上学不到的东西,我想这对于以后的毕业设计,或者工作也好,都是很有帮助的。

我很认真地对待这个过程中的每一个细节,希望自己能做得更好。

希望今后还有这样的机会,能够让我学到更多的知识。

在此次的数字钟设计过程中,更进一步地熟悉了芯片的结构及掌握了各芯片的工作原理和其具体的使用方法。

在连接六进制,十进制,六十进制的进位及十二进制的接法中,要求熟悉逻辑电路及其芯片各引脚的功能,那么在电路出错时便能准确地找出错误所在并及时纠正了。

相关文档
最新文档