完整版基于51单片机的万年历的设计.docx
- 文档编号:28575098
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:36
- 大小:180.93KB
完整版基于51单片机的万年历的设计.docx
《完整版基于51单片机的万年历的设计.docx》由会员分享,可在线阅读,更多相关《完整版基于51单片机的万年历的设计.docx(36页珍藏版)》请在冰豆网上搜索。
完整版基于51单片机的万年历的设计
单片机课程实训
SCMPRACTICALTRAINING
实训设计题目
TitleOfTraining
万年历的设计
分院(系别)
Department
专 业
Speciality
班级
Class
设计作者
Author
完成日期
Date
组别
Team
指导教师
Advisor
第一部分课程设计任务书
一、课程设计题目
用中小规模集成芯片设计制作万年历。
二、课程设计时间
五天
三、实训提交方式
提交实训设计报告电子版与纸质版
四、设计要求
(1)显示年、月、日、时、分、秒和星期,并有相应的农历显示。
(2)可通过键盘自动调整时间。
(3)具有闹钟功能。
(4)能够显示环境温度,误差小于±1℃
(5)计时精度:
月误差小于20秒。
第二部分课程设计报告
一、单片机发展概况
单片机诞生于20世纪70年代末,它的发展史大致可分为三个阶段:
第一阶段(1976-1978):
初级单片机微处理阶段。
该时期的单片机具有8位CPU,并行I/O端口、8位时序同步计数器,寻址范围4KB,但是没有串行口。
第二阶段(1978-1982):
高性能单片机微机处理阶段,该时期的单片机具有I/O串行端口,有多级中断处理系统,15位时序同步技术器,RAM、ROM容量加大,寻址范围可达64KB。
第三阶段(1982-至今)位单片机微处理改良型及16位单片机微处理阶段民用电子产品、计算机系统中的部件控制器、智能仪器仪表、工业测控、网络与通信的职能接口、军工领域、办公自动化、集散控制系统、并行多机处理系统和局域网络系统。
二、MCS-51单片机系统简介
MCS-51系列单片机产品都是以Intel公司最早的典型产品8051为核心构成的。
MCS-51单片机由CPU、RAM、ROM、I/O接口、定时器/计数器、中断系统、内部总线等部件组成。
8051单片机的基本性能有:
◆8位CPU;
◆布尔代数处理器,具有位寻址能力;
◆128B内部RAM,21个专用寄存器;
◆4KB内部掩膜ROM;
◆2个16位可编程二进制加1定时器/计数器;
◆32个(4×8位)双向可独立寻址的I/O口;
◆1个全双工UART(异步串行通信口);
◆5个中断源,两级中断结构;
◆片内振荡器及时钟电路,晶振频率为1.2MHz~12MHz;
◆外部程序/数据存储器寻址空间均为64KB;
◆111条指令,大部分为单字节指令;
◆单一+5V电源供电,双列直插40引脚DIP封装。
三、设计思想
整体设计以单片机技术为核心,采用C语言进行软件设计,增加了程序的可读性和可移植性,为了便于扩展和更改,软件的设计采用模块化结构。
程序先向LCD更新时钟芯片的时间与温度传感器的时间,然后进行初始化工作。
程序由一个主函数,两个定时器中断程序,一个时钟设置子程序,一个农历设置子程序,一个温度设置子程序,一个延时子程序,一个调时子程序,一个显示子程序构成。
程序通过按键扫描程序来确定是否调用中断程序来对时间进行调整。
用一子程序完成时分的调整,通过循环扫描四个按键的电平变化来判断对应按键是否按下,并带有去抖动功能,四个按键分别有增加,减小,退出与功能选择的作用。
通过功能选择时钟设置与闹钟设置,使用加或减按键进行预置,完成后可点退出键完成操作。
可分为以下几个功能模块:
1)主程序:
定时器中断初始化、时钟与温度更新程序与键盘监控。
2)计时:
为定时器中断服务子程序,完成刷新计时缓冲区的功能。
3)农历:
由阴历换算对照表得出阳历并显示。
4)闹钟:
采用定时器中断方式实现闹钟与整点报时。
5)温度:
由温度传感器将温度传送到LCD显示。
6)设置:
由按键设置闹钟时间或时钟时间。
7)键盘扫描:
判断是否有键按下,并确定键号。
8)LCD显示:
完成8位动态显示。
四、硬件电路设计
1.总体设计
系统包括单片机主控模块,温度传感器采集模块,日历时钟模块,按键调整模块,蜂鸣器模块,闹钟模块。
如图1所示为系统设计图。
图1系统设计图
如图2所示为系统仿真图。
图2系统仿真图
2.晶振电路
如图3所示,51单片机的内部有一个用于构成振荡器的高增益反相放大器,它的输入端为XTAL1引脚,输出端为XTAL2引脚,两个跨接石英晶体及两个电容就可以构成稳定的自激振荡器。
电容器通常取30pF左右。
图3晶振电路图4复位电路
3.复位电路
往单片机的复位引脚上输入24个时钟周期以上的高电平,即执行复位操作。
按键复位是指系统在运行时,按下一个开关,就能在RST引脚产生一段时间的高电平,使系统复位,常见的按键复位电路如图4所示。
对12MHz晶振频率而言,电路中C取10pF,R取1KΩ。
4.DS1302时钟电路
DS1302是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
图5示出DS1302的引脚排列,其中Vcc1为后备电源,Vcc2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接32.768KHz晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RSTS置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电动行时,在Vcc大于等于2.5V之前,RST必须保持低电平。
中有在SCLK为低电平时,才能将RST置为高电平,I/O为串行数据输入端(双向)。
SCLK始终是输入端。
图5DS1302时钟芯片图6温度采集系统电路
5.温度采集系统电路
在本万年历当中温度的采集采用数字温度传感器DS18B20。
它属于单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
具有如下的经济特点:
(1)只要求一个端口即可实现通信。
(2)在DS18B20中的每个器件上都有独一无二的序列号。
(3)实际应用中不需要外部任何元器件即可实现测温。
(4)测量温度范围在-55。
C到+125。
C之间。
(5)数字温度计的分辨率用户可以从9位到12位选择。
(6)内部有温度上、下限告警设置。
如图6所示。
6.按键调整电路
按键采用4个独立的按键,一个功能键、一个退出键、一个加按键、一个减按键通过这四个按键可以来合理的设置时钟的调整和闹铃的设置等。
如图7所示与51单片机的P0.0~P0.3的连接示意图。
图7按键调整电路
7.闹钟提示电路
当到达整点时或者当前的时间等于51单片机中设置闹钟时间时蜂鸣器便会发出声音进行提示。
与单片机P0.5引脚的连接电路如图8所示。
图8闹钟提示电路图9LCD显示电路
8.LCD显示电路
在本万年历当中12864液晶显示当前的实时时间重要的阴阳历节日等功能。
12864液晶具有如下的特性:
1)提供8位,4位并行接口及串行接口可选
2)并行接口适配M6800时序
3)自动电源启动复位功能
4)内部自建振荡源
64×16位字符显示RAM(DDRAM最多16字符×4行,LCD显示范围16×2行)(改为半角输入)2M位中文字型ROM(CGROM),总共提供8192个中文字型(16×16点阵)16K位半宽字型ROM(HCGROM),总共提供126个西文字型(16×8点阵)64×16位字符产生RAM(CGRAM)15×16位总共240点的ICONRAM(ICONRAM)其与单片机的连接电路如图9所示。
五、软件设计框图
1.主程序流程图:
2.阴阳历转换流程图:
六、程序源代码
1.主程序
#include
#include
#include
#include
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
/********************************************************************
sbitbell=P2^0;//定义蜂鸣器端口
/********************************************************************
定时器设置整点报时
********************************************************************/
voidTimer0_Service()interrupt1
{
staticucharcount=0;
staticucharflag=0;//记录鸣叫的次数
count=0;
TR0=0;//关闭Timer0
TH0=0x3c;
TL0=0XB0;//延时50ms
TR0=1;//启动Timer0
count++;
if(count==20)//鸣叫1秒
{
bell=~bell;
count=0;
flag++;
}
if(flag==6)
{
flag=0;
TR0=0;//关闭Timer0
}
}
/********************************************************************
中断服务程序整点报时一分钟
********************************************************************/
ucharHexNum_Convert(ucharHexNum)//将16进制数转换成十进制数
{
ucharNumtemp;
Numtemp=(HexNum>>4)*10+(HexNum&0X0F);
returnNumtemp;
}
/********************************************************************
*函数名称:
main()
*功能:
*入口参数:
*出口参数:
********************************************************************/
voidmain(void)
{
ucharclock_time[6]={0X00,0X59,0X23,0X09,0X04,0X11};//定义时间变量秒分时日月年
ucharalarm_time[2]={10,06};//闹钟设置
alarm_time[0]:
分钟alarm_time[1]:
小时
uchartemperature[2];//定义温度变量temperature[0]低8位temperature[1]高8位
Lcd_Initial();//LCD初始化
Clock_Fresh(clock_time);//时间刷新
Clock_Initial(clock_time);//时钟初试化
/***********************中断初始化***************************/
EA=1;//开总中断
ET0=1;//Timer0开中断
ET2=1;//Timer2开中断
TMOD=0x01;//Timer0工作方式1
RCAP2H=0x3c;
RCAP2L=0xb0;//Timer2延时50ms
while
(1)
{
switch(Key_Scan())//按键扫描
{
caseup_array:
{
Key_Idle();//检测按键松开
}
break;
casedown_array:
{
Key_Idle();//检测按键松开
}
break;
caseclear_array:
{
Key_Idle();//检测按键松开
}
break;
casefunction_array:
{
Key_Function(clock_time,alarm_time);
}
casenull:
{
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==HexNum_Convert(*(clock_time+1)))//分钟相吻if(*(alarm_time+1)==HexNum_Convert(*(clock_time+2)))//小时相吻合
{
bell=0;
TR2=1;//启动Timer2
}
}
break;
}
}
}
2.温度控制程序
#ifndef_SENSOR
#define_SENSOR
#defineucharunsignedchar
#defineuintunsignedint
/***************DS18B20管脚配置*******/
sbitdq=P2^1;
/********************************************************************DS18B20软件延时专用
********************************************************************/
voidSensor_Delay(ucharcount)//延时函数
{
while(count--);
}
/********************************************************************从DS18B20读一个字节
********************************************************************/
ucharSensor_Read_Byte(void)
{
uchari=0;
uchartemp=0;
for(i=8;i>0;i--)
{
dq=0;//给脉冲信号
temp>>=1;
dq=1;//给脉冲信号
if(dq)
temp|=0x80;
Sensor_Delay(20);
}
return(temp);
}
/********************************************************************向DS18B20写一个字节
********************************************************************/
voidSensor_Write_Byte(uchartemp)
{
uchari=0;
for(i=8;i>0;i--)
{
dq=0;
dq=temp&0x01;
Sensor_Delay(20);
dq=1;
temp>>=1;
}
}
/********************************************************************
DS18B20初始化
********************************************************************/
ucharSensor_Initial(void)
{
uchari=0;
dq=1;//DQ复位
Sensor_Delay
(1);//稍做延时
dq=0;//单片机将DQ拉低
Sensor_Delay(100);//精确延时,大于480us
dq=1;//拉高总线
Sensor_Delay(6);//稍做延时后
i=dq;//若x=0则初始化成功,若x=1则初始化失败
Sensor_Delay(130);
return(~i);
}
/********************************************************************
读取并显示温度
********************************************************************/
voidSensor_Fresh(uchar*temperature)
{
Sensor_Initial();
Sensor_Write_Byte(0xCC);//跳过读序号列号的操作
Sensor_Write_Byte(0x44);//启动温度转换
Sensor_Initial();
Sensor_Write_Byte(0xCC);//跳过读序号列号的操作
Sensor_Write_Byte(0xBE);//读取温度寄存器
temperature[0]=Sensor_Read_Byte();//低位
temperature[1]=Sensor_Read_Byte();//高位
}#endif
3.日历设置程序
#ifndef_SUN_MOON
#define_SUN_MOON
/*************************************************************************/
#defineucharunsignedchar
#defineuintunsignedint
#include
#include
/********************************************************************
*功能:
读取数据表中农历的大月或小月,如果大月返回1,小月返回0
********************************************************************/
bitget_moon_day(ucharmonth_p,uintcalendar_address)
{
uchartemp,temp1;
temp1=(month_p+3)/8;
temp=0x80>>((month_p+3)%8);
temp=year_code[calendar_address+temp1]&temp;
if(temp==0){return(0);}else{return
(1);}
}
/********************************************************************
*功能:
输入BCD的阳历数据,输出BCD阴历数据(1901-2099)
c_flag:
阳历的世纪标志clock_time:
时钟地址
*说明:
c_flag=0:
21世纪c_flag=1:
19世纪
********************************************************************/
voidCalendar_Convert(ucharc_flag,uchar*clock_time)
{
bitflag_month,flag_year;
ucharyear,month,day,month_point;//定义年月天
uchartemp1,temp2,temp3;
uintcalendar_address;//定义农历地址
uintday_number;
ucharclock_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=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整版 基于 51 单片机 万年历 设计