基于51单片机的万年历设计.docx
《基于51单片机的万年历设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机的万年历设计.docx(23页珍藏版)》请在冰豆网上搜索。
基于51单片机的万年历设计
单片机课程设计
题目基于51单片机的万年历设计学生姓名
专业班级学号院(系)
指导教师
完成时间
1课程设计的目的1.
2课程设计的任务与要求1.
2.1设计任务1.
2.2设计要求1.
3单片机发展概况1.
4设计原理与功能说明4.
4.1设计思想4.
4.2总体电路图5.
4.3时钟模块5.
4.4液晶显示模块6.
4.5按键模块7.
5系统测试7.
5.1硬件测试7.
5.2软件测试8.
6总结8.
参考文献1.0.
附录一:
总体电路原理图1.1..
附录二:
主程序1..2.
附录三:
元器件清单2.6.
附录四:
实物图2..7.
1课程设计的目的
1.通过制作万年历,可以对单片机这门课程更好的认识。
2.理论与实践结合,提高自己的动手能力。
3.学会与合作者更好的交流学习,共同进步和提高。
4.能够增长查阅资料的能力,视野更加开阔。
5.拓展其他学科的联系,全面发展。
6.培养自我发现问题,解决问题的能力。
2课程设计的任务与要求
2.1设计任务
1.可以去学校图书馆或者网上,搜集整理相关的资料,做好前期理论准备,为以后设计电路,看懂电路图做理论支持。
2.构想万年历电路图,并且具有可行性,画出电路图。
3.列举电路所需的电子元件,仔细对比所需的元件的参数,通过去电子元件经销商或者网购购买。
2.2设计要求
1.显示年、月、日、时、分、秒。
2.可通过键盘自动调整时间。
3.计时精度:
月误差小于20秒。
3单片机发展概况
单片机诞生于20世纪70年代末,它的发展史大致可分为三个阶段:
第一阶段(1976-1978):
初级单片机微处理阶段。
该时期的单片机具有8位CPU,并行I/O端口、8位时序同步计数器,寻址范围4KB,但是没有串行口。
第二阶段(1978-1982):
高性能单片机微机处理阶段,该时期的单片机具有I/O串行端口,有多级中断处理系统,15位时序同步技术器,RAM、ROM容量加大,寻址范围可达64KB。
第三阶段(1982-至今)位单片机微处理改良型及16位单片机微处理阶段民用电子产品、计算机系统中的部件控制器、智能仪器仪表、工业测控、网络与通信的职能接口、军工领域、办公自动化、集散控制系统、并行多机处理系统和局域网络系统。
STC系列单片机是由STMicroelectronics公司生产,并有宏晶公司做大陆代理的。
本设计使用STC89C52作为控制核心,其管脚兼容其他51系列的单片机,以下对STC89C52进行简单讲解。
STC89C52单片机包含中央处理器、程序存储器(ROM)、数据存储器(RAM)、定时/计数器、并行接口、串行接口和中断系统等几大单元及数据总线、地址总线和控制总线等三大总线。
采用40Pin封装的双列直接DIP结构,图3.1是它们的引脚配置,40个引脚中,正电源和地线两根,外置石英振荡器的时钟线两根,4组8位共32个I/O口,中断口线与P3口线复用。
现在对各引脚功能说明如下(图3.2):
(1)主电源引脚
Vcc:
接+5V电源正端。
Vss:
接+5V电源地端。
(2)输入/输出引脚
P.0~P0.7:
P0口的8个引脚。
在不接片外存储器与不扩展I/O接口时,可作为准双向输入/输出接口。
在接有片外存储器或扩展I/O接口时,P0口分时复用为低8位地址总线和双向数据总线。
P1.0~P1.7:
P1口的8个引脚。
可作为准双向I/O接口使用。
对于52子系列,P1.0与P1.1还有第二种功能:
P1.0可用作定时器/计数器2的Word资料
计数脉冲输入端T2。
P1.1可用作定时器/计数器2的外部控制端T2EX。
P2.0~P2.7:
P2口的8个引脚。
可作为准双向I/O接口;有接有片外存储器或扩展I/O接口且寻址范围超过256个字节时,P2口用作高8位地址总线。
P3.0~P3.7:
P3口的8个引脚。
除作为准双向I/O接口使用外,还具有第二种功能,详见图3.2。
图3.1STC89C52单片机管脚图
引脚
第二功能
P3.0
RXD(串行口输入)
P3.1
TXD(串行口输出)
P3.2
IˉNˉTˉ0ˉ(外部中断0输入)
P3.3
IˉNˉTˉ1ˉ(外部中断1输入)
P3.4
P3.5
T0(定时器0的外部输入)
P3.6
T1(定时器1的外部输入)
P3.7
WˉRˉ(片外数据存储器写控制信号)
RˉDˉ(片外数据存储器读控制信号)
图3.2P3口第二功能表
4设计原理与功能说明
4.1设计思想
以STC89C52单片机为核心,外接单片机复位电路,单片机晶振电路,时钟芯片DS1302,按键电路,液晶显示电路,通过控制STC89C52单片机的接口来控制时钟芯片DS1302模块,按键电路,液晶显示模块,使液晶能显示阳历年、月、日、星期相应的农历时间。
图4-1硬件系统设计框架
4.2总体电路图
图4-2总电路图
4.3时钟模块
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
图4-3时钟电路图
4.4液晶显示模块
本系统选择的LCD是AMPIRE128×64的汉字图形型液晶显示模块,可显示汉字及图形。
单片机P1口作为数据输出口,RS,R\W,E分别通过10K的上拉电阻连接到单片机的P0.0,P0.1,P0.2。
VDD接5V电源,VSS接地。
VEE为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
R/W为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作。
E(或EN)端为使能(enable)端,下降沿使能。
DB0-DB7为双向数据总线,同时最高位DB7也是忙信号检测位。
BLA、BLK分别为显示器背光灯的正、负极。
图4-4液晶显示电路图
4.5按键模块
本系统使用5个button元件分别设置为增加键、减小键、退出键、设置/OK键。
4个按键与一个4个驱动电阻相连,作为整个按键控制功能系统,以触发AT89C52中断为方式使用设置功能。
5系统测试
5.1硬件测试
在调试硬件时遇到过很多问题,但只要细心、认真检查这些问题都是
可以避免的,主要问题及解决办法现列如下:
认真检查电路是否有短路的地方,线与线之间,管脚刺破邻近的漆包线之间是否连接在一起,有的话要用刀划开,或者重新焊接。
检查完毕后接通电源后LCD1602没有正确的显示。
在不通电状态下用万用表检测电路是否正常连接,在检查回路时发现有的点之间看似连接,但由于虚焊导致其并无电气连接,只能对焊脚进行在加工直到解决问题。
5.2软件测试
由于本系统涉及到多个子程序,多个芯片的编程。
首先必须对可编程芯片的控制字即其控制指令要熟记于心。
其次,芯片很多都有时钟输入端,需要晶振支持。
对芯片的读写都需要在相应的触发沿到来时才能进行。
由于DS18B20是串行通信数据,只用一个口线传输,在处理采集的模拟信号时需要一定的时间,会对延时有较高要求。
所以在调用温度子程序时,先关闭定时器1中断允许,在温度子程序反回时再打开定时器1中断允许。
6总结
在这几天的单片机课程设计中,老师先给我们介绍各种电子原件,让我们了解了各种原件的不同以及注意事项,这次课程不仅仅让我们动了手动了脑,更让我们体会到了理论与实践相结合的重要性,使我又不得不承认理论的重要,我们必须打好基础。
在实验设计的过程中,让我们体会到以前从来没有过的动手能力,以及新颖的思维方式,让我从中获益非浅。
实验过程中,刚开始就参看电路指导书,画出了多电路图,进行了仿真,但是由于实验元件选择的不恰当,是的电灯不能依次闪烁,许但最后用万用表才得以发现问题的所在,并在老师的指导下,终于完成了实验设计,虽然道路艰难,但我们却也乐在其中,既锻炼了动手能力,有培养了动脑能力,更加利于我们在社会上工作。
经过我们组员三天的不懈努力,终于成功完成了万年历的设计,完成了任务给出的所有要求,期间遇到了很多问题,相关资料的搜集、整理,编写、调试程序的时候所出现的错误,硬件电路的选择、连接。
例如:
液晶屏时间显示出现了错误即乱码现象,我们通过查找书籍和上网搜索的形式知道了问题所在,与延时程序有关,修改了延时程序之后问题得到了解决。
在画原理图的时候,刚开始每个原件是用线连接的,但是后来发现越连越多,越连越乱,可视性太差了,很容易连错线,而且一旦出现错误,很难检查出错误,所以我们换了一种更好的方法,对其进行标号处理,从而使得原理图更加的简洁、直观,而且操作起来很方便。
最终还是解决了这个难题,诸如此类的错误在本次设计中有不少,但是通过我们组员之间的通力合作与不懈努力终于克服了这些困难,本次实训不仅巩固了我们所学的知识,而且学到了很多课本之外的东西,真正做到了学以致用,加强了逻辑思维能力,对我们大学生来说试一次很好的经历,同时也让我们深刻体会到了团结合作的重要性,组员之间合理分工,更加高效、迅速。
另外对于了解较少的知识,我们不要气馁,我们可以通过上网查阅、到图书馆借书浏览等方式了解学习,一定要相信自己,要持之以恒,这次经历加强了我们分析问题、解决问题的能力,为我们以后的工作学习打下坚实的基础。
本次设计中同学之间明确分工,互相帮助,才有了本次设计的圆满成功。
参考文献
[1]
.北京:
北京航空航
2006.
何立民.MCS-51单片机应用系统设计(系统配置与接口技术)天大学出版社,2003.
[2]周立功.单片机实验与实践教程(三).北京航空航天大学出版社,
[3]谭浩强.C语言程序设计.北京:
清华大学出版社,2006.
[4]付家才.单片机实验与实践.北京:
高等教育出版社,2006.
[5]淡海英.关于单片机控制的数字万年历设计[J].电子制作,2014.
[6]鲁广英.基于单片机电子万年历的设计与实现[J].硅谷,2010.
附录二:
主程序
#include"lcd.h"
/**
*函数名
:
Lcd1602_Delay1ms
*函数功能
:
延时函数,延时1ms
*输
入
:
c
*输
出
:
无
*说
名
:
该函数是在12MHZ晶振下,12分频单片机的延时。
voidLcd1602_Delay1ms(uintc)//误差0us
{
uchara,b;
for(;c>0;c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
*函数名
:
LcdWriteCom
*函数功能
:
向LCD写入一个字节的命令
*输入
:
com
*输出
:
无
**/
#ifndefLCD1602_4PINS//当没有定义这个LCD1602_4PINS时voidLcdWriteCom(ucharcom)//写入命令
{
LCD1602_E=0;//使能
LCD1602_RS=0;//选择发送命令
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=com;//放入命令
Lcd1602_Delay1ms
(1);//等待数据稳定
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);//保持时间
LCD1602_E=0;
}
#else
voidLcdWriteCom(ucharcom)//写入命令
{
//选择写入命令
LCD1602_E=0;//使能清零
LCD1602_RS=0;
//由于4位的接线是接到P0口的高四位,所以传
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=com;
送高四位不用改
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
//Lcd1602_Delay1ms
(1);
LCD1602_DATAPINS=com<<4;//发送低四位
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
#endif
/**
*函数名
:
LcdWriteData
*函数功能
:
向LCD写入一个字节的数据
*输入
:
dat
*输出
:
无
**/
#ifndefLCD1602_4PINS
voidLcdWriteData(uchardat)//写入数据{
LCD1602_E=0;//使能清零
LCD1602_RS=1;//选择输入数据
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=dat;//写入数据
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);//保持时间
LCD1602_E=0;
}
#elsevoidLcdWriteData(uchardat)//写入数据{
LCD1602_E=0;//使能清零
LCD1602_RS=1;//选择写入数据
LCD1602_RW=0;//选择写入
LCD1602_DATAPINS=dat;//由于4位的接线是接到P0口的高四位,所以传送高
四位不用改
Lcd1602_Delay1ms
(1);
LCD1602_E=1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E=0;
LCD1602_DATAPINS=dat<<4;//写入低四位
Lcd1602_Delay1ms
(1);
LCD1602_E=1;
//写入时序
*函数名
*函数功能
*输入
*输出
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
#endif
/**
:
LcdInit()
:
初始化LCD屏
:
无
:
无
**/
//LCD初始化子程序
//开显示
//开显示不显示光标
//写一个指针加1
//清屏
LcdWriteCom(0x80);//设置数据指针起点
}
#else
voidLcdInit()
{
LcdWriteCom(0x32);
LcdWriteCom(0x28);
LcdWriteCom(0x0c);
LcdWriteCom(0x06);
LcdWriteCom(0x01);
LcdWriteCom(0x80);
//LCD初始化子程序
//将8位总线转为4位总线
//在四位线下的初始化
//开显示不显示光标
//写一个指针加1
//清屏
//设置数据指针起点
}
#endif/*******************************************************************************
*实验名:
定时器实验
*使用的IO:
*实验效果:
1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒,按K2选择
*选择设置加1。
*注意:
*******************************************************************************/#include
#include"lcd.h"sbitK1=P3^6;
sbitK4=P3^4;
Word资料
sbitK3=P3^5;
sbitK2=P3^3;
unsignedcharTime;
//用来计时间的值
voidDelay1ms(unsignedintc);
voidTimerConfiguration();
voidInt0Configuration();
unsignedcharSetPlace;
*函数名
:
main
*函数功能
:
主函数
*输入
:
无
*输出
:
无
*****************************************************************************voidmain(void)
{
unsignedcharhour,minit,second;
unsignedinti;
TimerConfiguration();
Int0Configuration();
LcdInit();
hour=12;
LcdWriteData('0'+hour/10);
LcdWriteData('0'+hour%10);
LcdWriteData('-');
LcdWriteData('0'+minit/10);
LcdWriteData('0'+minit%10);
LcdWriteData('-');
LcdWriteData('0'+second/10);
LcdWriteData('0'+second%10);
while
(1)
{
if(TR0==0)
{
if(K1==0)//检测按键K2是否按下
{
Delay1ms(10);//消除抖动
if(K1==0)
{
SetPlace++;
if(SetPlace>=3)
SetPlace=0;
}
while((i<50)&&(K1==0))
//检测按键是否松开
Delay1ms
(1);
i++;
}
i=0;
}
if(K2==0)//检测按键K3是否按下
{
Delay1ms(10);//消除抖动
if(K2==0)
{
if(SetPlace==0)
{
second++;
if(second>=60)
second=0;
}
elseif(SetPlace==1)
{
minit++;
if(minit>=60)
minit=0;
}
else
{
hour++;
if(hour>=24)
hour=0;
}
//检测按键是否松开
}
while((i<50)&&(K2==0))
{
Delay1ms
(1);
i++;
}
i=0;
}
}
if(Time>=20)//一秒钟来到改变数值
{
Time=0;
second++;
if(second==60)
{
second=0;
minit++;
if(minit==60)
{
minit=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
//--显示时钟--//
LcdWriteCom(0x80);
LcdWriteData('0'+hour/10);
LcdWriteData('0'+hour%10);
LcdWriteCom(0x83);
LcdWriteData('0'+minit/10);
LcdWriteData('0'+minit%10);
LcdWriteCom(0x86);
LcdWriteData('0'+second/10);
LcdWriteData('0'+second%10);
}
}
*函数名
:
Delay1ms()
*函数功能
:
延时1ms
*输入
:
c
*输出
:
无
voidDelay1ms(unsignedintc)//误差0us{
unsignedchara,b;
for(;c>0;c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
/**
*函数名
:
TimerConfiguration()
*函数功能
:
配置定时器值
*输入
:
无
*输出
:
无
**/
voidTimerConfiguration()
{
TMOD=0x01;//选择工作方式1
TH0
0x3C;
//设置初始值
TL0=
0x0B0;
EA=
1;
//打开总中断
ET0=
1;
//打开定时器
0中断
TR0
1;
//启动定时器
0
*函数名
:
Timer0()
*函数功能
:
定时器0中断函数
*输入
:
无
*输出
:
无
**/
voidTimer0()interrupt1{
TH0=0x3C;//设置初始值TL0=0x0B0;
Time++;}
*函数名
:
Int0Configuration()
*函数功能
:
配置外部中断0
*输入
:
无
*输出
:
无
voidInt0Configuration()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
EA=1;//打开总中断
}
*函数名
:
Int0()interrupt0
*函数功能
:
外部中断0的中断函数
*输
入
:
无
*输
出
:
无
*****************************