您的当前位置:首页正文

基于51单片机电子万年历设计

2023-12-12 来源:星星旅游


大连民族学院机电信息工程学院

自动化系

单片机系统课程设计报告

题 目: 专 业: 班 级: 学生姓名: 指导教师:

电子万年历 自动化 106

设计完成日期: 2012年 11月30日

课程设计任务书 题目: 电子万年历 课程设计时间: 2012.11.12~2012.11.30 一、设计任务 给定时钟芯片(DS12C887)和单片机最小系统,学习使用单片机最小系统,设计万年历电路和闹钟报时电路,完成相关的软件设计并进行万年历显示。 二、设计内容及要求 ⒈ 系统设计的方案; ⒉ 检测电路和过程通道的设计; ⒊ 系统软件设计与实现; ⒋ 需要的详细材料和工具清单; ⒌ 设计的性能指标; ⒍ 撰写设计报告; ⒎ 资料归档。 三、设计重点 检测电路和过程通道设计; 系统软件设计、调试。 四、课程设计进度要求 ⒈ 12.11.12~12.11.14 系统方案设计; ⒉ 12.11.15~12.11.16 检测电路和过程通道设计; ⒊ 12.11.19~12.11.21 完成系统硬件设计与实现; ⒋ 12.11.22~12.11.23 完成系统软件编程; ⒌ 12.11.26~12.11.29 系统调试及撰写设计报告; ⒍ 12.11.30 验收答辩。 五、参阅书目 [1] 郭天祥.新概念51单片机C语言教程[M].北京:电子工业出版社,2009. [2] 胡汉才.单片机原理与接口技术[M].北京: 清华大学大学出版社,2004.1-505. [3] 邢国泉. LM35温度传感器的温度特性及其应用[J]. 医疗设备信息.2007,11,25-28.

目 录

1任务分析和性能指标 ...................................................... 1 1.1任务分析............................................................. 1 1.2性能指标............................................................. 1 1.3显示部分............................................................. 1 1.4键盘部分............................................................. 2 2总体方案设计 ............................................................ 2 2.1硬件方案如图:....................................................... 2 2.2设计过程............................................................. 2 2.3合理分配内存......................................................... 3 2.4整个系统的流程框图如图:............................................. 3 2.5软件方案............................................................. 4 3硬件设计与实现 .......................................................... 4 3.1显示电路如图: ...................................................... 5 3.2控制电路 ............................................................ 6 3.3芯片功能特性简述..................................................... 8 4软件设计与实现 .......................................................... 9 4.1 主程序 .............................................................. 9 4.2子程序.............................................................. 10 5 调试及性能分析 ......................................................... 19 5.1 调试原理图如图: .................................................. 19 5.2 软件调试 ........................................................... 19 5.3 硬件调试 ........................................................... 19 5.4 系统性能分析 ....................................................... 19 六 总 结 ................................................................ 20 七 参考文献 .............................................................. 20 八 附录 .................................................................. 20 附录1 元器件清单 ....................................................... 20 附录2 调试系统照片 ..................................................... 23

1

电子万年历

1任务分析和性能指标

1.1任务分析

设计一个具有报时功能、停电正常运行(来电无需校时)、闹钟功能、带有年月日、时分秒及星期显示的电子日历。

电子万年历是日常生活中常见的小型电子产品,其形式多种多样,小到带有日期的电子腕表,大到公共场所悬挂的大型电子日历,此外,眼下我们还常能在宾馆、饭店等场所见到一种带有年、月、日、时、分、秒、星期甚至节气等信息的电子日历牌。

电子日历的主要功能是给人们提供时间和日期信息,无论其形式如何,从外部都可分为显示和校准两部分。为使电子日历协调工作,整个系统从功能上可分为实时时钟、显示和键盘三个模块,分别完成时间和日期的计算以及人机交互的管理等。

1.2性能指标

实时时钟(RTC:Real Time Clock)是系统的核心,其运行精度直接影响产品质量。实时时钟的实现有两种方案可选,一是利用单片机系统时钟和中断完成时间和日期的计算;二是利用专用时钟芯片。前者不用附加芯片,系统简单,但是累计误差较大,只有短时计时才可使用。长时间计时一般都采用后者。后者采用32.768KHz晶体振荡器振作为脉冲源,内部的15位计数器刚好产生标准秒脉冲。该类芯片除时钟计时外,还有年月日和星期的计算功能,并且还可计算闰年。芯片初始化后可脱离CPU自动运行,有些芯片内部带有电池,出厂时芯片即开始运行。专用时钟芯片的种类很多,与CPU的通信方式有并行,也有串行。常见的芯片有DALLAS 公司生产的DS1302和DS12C887,前者为串行,需要外加后备电池;后者为并行,芯片内置锂电池和晶体振荡器,无外加电源的情况下可运行10年。此外,还有许多时钟芯片,如Epson、Holtek、深圳兴威帆等公司都推出自己的时钟芯片。这次我们选用的芯片是DS12C887。

1.3显示部分

简单的数据显示常采用液晶显示或数码管显示。液晶显示有耗电低、外形美观的优点,并且,点阵液晶可显示较复杂的字符或图案。其缺点是通用液晶显示器的显示方案构建不够灵活,在较暗的环境下液晶需要背光,而且,液晶显示成本较高。相对液晶显示器来讲,由于数码管种类繁多,其显示方案构建灵活,成本较低。由于本身即是发光体,所以,数码管显示无需额外光源。数码管的缺点是功耗较大,字符较多时,必须交流供电,而且,数码管不能显示复杂字型。所以,液晶和数码管两个方案的选择要根据

1

电子万年历

显示的具体情况而定。值得一提的是,数码管串行静态显示和并行动态显示在位数较多时都会出现显示不稳定现象。所以这次我们选用LED1602液晶。

1.4键盘部分

时钟的设置虽包含数字,但是我们不建议使用数字键盘,应为数字键盘将增加系统的复杂程度。为使系统尽可能简化,键盘部分的设计在能够完成系统要求的前提下,越简单越好。所以,时钟系统的键盘可以设置四个键:功能选择键、加1键、减1键,闹钟键。

2总体方案设计

2.1硬件方案如图:

显示系统 DS12C887 单片机 图1 电子万年历的系统框图

键盘 2.2设计过程

⒈认真领会设计要求:

确定系统功能,包括显示信息、按键个数、报时功能、闹 钟功能等; ⒉样品外观设:

确定系统显示信息,显示器种类(液晶、数码管)、显示器尺寸等; ⒊硬件初步设计:

选定DS12C887芯片、选定显示方式(动态、静态、串行、并行)、按键个数; ⒋系统原理图设计按照前几步规划,设计系统原理图:

此时应认真研究学习DS12C887芯片的使用方法,正确连接DS12C887芯片,设计键盘及显示电路。 ⒌系统软件设计

系统软件可分为键盘管理、显示管理、报时管理和DS12C887管理三部分。软件可由汇编语言完成,也可由C语言完成,我选择C语言。

2

电子万年历

2.3合理分配内存

内存是系统宝贵的资源之一,为合理利用内存,应对内存使用通盘考虑,并反复修改使用方案,使之达到最合理利用。应尽量少使用全局变量,以提高内存的利用率。有效利用CPU内存和外围器件内存,一般情况下不建议扩展系统内存。

2.4 整个系统流程图

系统硬件初始化: N 上电复位 Y Y 内存变量初始化: 报时点、显示缓冲区等 开始

显示器、DS12C887芯片等

系统硬件初始化: 显示器、DS12C887芯片等 扫描键盘 键盘分析处理 显示管理

图2 软件部分程序流程图

3

电子万年历

2.5软件方案

C语言编属于高级语言,具有可移植性,能够结构化编程。使用标准C语言的程序,几乎都可以不作改变移植到不同的微机平台上,对于嵌入式等的微控制芯片,属于标准C语言的部分也很少需要修改,而且程序很容易读懂。 C语言编写程序结构清晰,移植性好,容易维护和修改。

汇编语言针对不同的操作系统平台,不同的微控制器,指令都是完全不同的,即使指令相似,也不具有可移植性。但是汇编语言是针对专门的控制器的,所以运行速度可以精确到一个指令周期。汇编语言的程序读懂需要借助微控制器的指令手册以及各个寄存器的说明,所以很难读懂。

汇编语言编写代码实时性强,能够直接控制硬件的工作状态,但是不具有可移植性,维护和修改困难。

经过我们三人的讨论我们决定使用c语言来编写程序 ,因为c语言程序容易学,也很容易读懂,编写程序结构清晰,易于我们组员之间的讨论和学习。而且相对于汇编我们更加擅长c语言。

3硬件设计与实现

由于 DS12C887 能够自动产生世纪、 年、月、日、时、分、秒等时间信息,其内部又增加了世纪寄存器,从而利用硬件电路 解决子“千年”问题;DS12C887 中自带有锂电 池,外部掉电时,其内部时间信息还能够保 持 10 年之久;对于一天内的时间记录,有12 小时制和 24 小时制两种模式。在 12 小时 制模式中,用 AM 和 PM 区分上午和下午; 时间的表示方法也有两种,一种用二进制数 表示,一种是用 BCD 码表示;DS12C887 中 带有 128 字节 RAM,其中有 11 字节 RAM 用来存储时间信息,4 字节 RAM 用来存储 DS12C887 的控制信息,称为控制寄存器,113 字节通用 RAM 使用户使用;此外用户还 可对 DS12C887 进行编程以实现多种方波输 出,并可对其内部的三路中断通过软件进行 屏蔽。使用其于单片机89C52控制DS12C877就能很好的实现时钟需要的基本功能。而显示部分我们采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示文字,图形,显示多样,清晰可见,而其体积较小,使用方便,可以使电路更加简洁,所以选择了液晶显示器。

4

电子万年历

3.1显示电路如图:

图3 LED液晶显示

5

电子万年历

3.2控制电路

图4 单片机最小系统原理图

图5 时钟芯片原理图

6

电子万年历

图6 按键原理图

3.3芯片功能特性简述

P1.0 P1.1 P1.2 P1.3P1.4P1.5P1.6P1.7RST/VPDP3.0/RXDP3.1/TXDP3.2/INT0P3.3/INT1P3.4/T0P3.5/T1P3.6/WRP3.7/RDXTAL2XTAL1VSS1 2 3 4 5 6 7 8 9 101112131415161718192040393837363534333231302928 27 26 25 24 23 22 21 VCCP0.0P0.1P0.2P0.3P0.4P0.5P0.6P0.7EA/VPPALE/PROGPSENP2.7P2.6P2.5P2.4P2.3P2.2P2.1P2.0STC89C52

图7 单片机引脚

7

电子万年历

STC89C52 是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。使用高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在线系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 STC89C52具有以下标准功能: 8k字节Flash,256字节RAM, 32 位I/O 口线,看门狗定时器,2 个数据指针,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,STC89C52可降至0Hz静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。8 位微控制器 8K字节在系统可编程 Flash。

4软件设计与实现

#include

#define uchar unsigned char #define uint unsigned int sbit S1=P1^0; sbit S2=P1^1; sbit S3=P1^2; sbit S4=P1^3;

sbit rs=P3^5; // 数据/命令选择端(H/L) sbit lcden=P3^4; //使能信号 sbit beep=P3^6;

sbit dscs=P1^4; //片选端,低电平有效 sbit dsas=P1^5; sbit dsrw=P1^6;

sbit dsds=P1^7; //数据选择或读输入引脚 sbit dsirq=P3^3;//中断请求输出,低电平有效 bit flag1,flag_ri; //定义两个变量 uchar count,s1num,flag,t0_num;

char miao,shi,fen,year,month,day,week,amiao,afen,ashi; uchar code table[]=\" 2012-11-16 \" ; uchar code table1[]=\" 20:06:12\" ; void write_ds(uchar,uchar);

void set_alarm(uchar,uchar,uchar); void read_alarm();

8

电子万年历

void set_time();

uchar read_ds(uchar); void delay(uint z) {

uint x,y;

for(x=z;x>0;x--) for(y=110;y>0;y--); }

void di() //蜂鸣器报警声音 {

beep=0;

delay(100); beep=1; }

void write_com(uchar com) //写液晶命令函数 {

rs=0; lcden=0; P2=com; delay(3); lcden=1; delay(3); lcden=0; }

void write_date(uchar date)//写液晶数据函数 {

rs=1; lcden=0; P2=date; delay(3); lcden=1; delay(3); lcden=0; }

void init() //初始化函数 {

uchar num;

EA=1; //总中断 EX1=1; // 外部中断1

IT1=1; //负跳变沿触发中断 flag1=0; //变量初始化 t0_num=0;

9

电子万年历

s1num=0; week=1; lcden=0;

write_ds(0x0a,0x20); //打开振荡器

write_ds(0x0b,0x26); //设置24小时模式,数据二进制格式,开启闹铃中断 //set_time();

write_com(0x38); //1602液晶初始化 write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80);

for(num=0;num<15;num++) //写入液晶固定部分显示 { write_date(table[num]); delay(1); }

write_com(0x80+0x40); for(num=0;num<10;num++) { write_date(table1[num]); delay(1); } }

void write_sfm(uchar add,char date) //1602液晶刷新时分秒函数2为时,5为分,8为秒 {

char shi,ge; shi=date/10; ge=date%10;

write_com(0x80+0x40+add); write_date(0x30+shi); write_date(0x30+ge); }

void write_nyr(uchar add,char date) //1602液晶刷新年月日函数3为年,6为月,9为日 {

char shi,ge; shi=date/10; ge=date%10;

write_com(0x80+add);

10

电子万年历

write_date(0x30+shi); write_date(0x30+ge); }

void write_week(char we) //1602液晶刷新星期函数 {

write_com(0x80+12); switch(we) { case 1: write_date('M');delay(5); write_date('O');delay(5); write_date('N'); break; case 2: write_date('T');delay(5); write_date('U');delay(5); write_date('E'); break; case 3: write_date('W');delay(5); write_date('E');delay(5); write_date('D'); break; case 4: write_date('T');delay(5); write_date('H');delay(5); write_date('U'); break; case 5: write_date('F');delay(5); write_date('R');delay(5); write_date('I'); break; case 6: write_date('S');delay(5); write_date('A');delay(5); write_date('T'); break; case 7: write_date('S');delay(5); write_date('U');delay(5); write_date('N'); break; } }

void keyscan() //取消时钟报警,按任意键取消报警 {

if(flag_ri==1) {

11

电子万年历

if((S1==0)||(S2==0)||(S3==0)||(S4==0)) { delay(5); if((S1==0)||(S2==0)||(S3==0)||(S4==0)) { while((S1==0)||(S2==0)||(S3==0)||(S4==0)); di(); flag_ri=0; //清除报警标志 } } }

if(S1==0) //检测S1 { delay(5); if(S1==0) { s1num++; if(flag1==1) if(s1num==4) s1num=1; flag=1; while(S1==0); di(); switch(s1num) //光标闪烁点定位 { case 1: write_com(0x80+0x40+8); write_com(0x0f); break; case 2: write_com(0x80+0x40+5); break; case 3: write_com(0x80+0x40+2); break; case 4: write_com(0x80+12); break; case 5: write_com(0x80+9); break; case 6: write_com(0x80+6); break; case 7: write_com(0x80+3); break; case 8:s1num=0; write_com(0x0c);

12

电子万年历

flag=0; write_ds(0,miao); write_ds(2,fen); write_ds(4,shi); write_ds(6,week); write_ds(7,day); write_ds(8,month); write_ds(9,year); break; } } }

if(s1num!=0) //只有当S1按下后,才检测S2和S3 {

if(S2==0) { delay(1); if(S2==0) { while(S2==0); di(); switch(s1num) //根据功能键次数调节相应数值 { case 1: miao++; if(miao==60) miao=0; write_sfm(8,miao); write_com(0x80+0x40+8) ; break; case 2: fen++; if(fen==60) fen=0; write_sfm(5,fen); write_com(0x80+0x40+5) ; break; case 3: shi++; if(shi==24) shi=0; write_sfm(2,shi); write_com(0x80+0x40+2) ; break; case 4: week++;

13

电子万年历

if(week==8) week=1;

write_week(week);

write_com(0x80+12) ; break; case 5: day++; if(day==32) day=1;

write_nyr(9,day); write_com(0x80+9) ; break;

case 6: month++; if(month==13) month=1;

write_nyr(6,month); write_com(0x80+6) ; break;

case 7: year++; if(year==100) year=0;

write_nyr(3,year); write_com(0x80+3) ; break;

}

} }

if(S3==0) { delay(1); if(S3==0) { while(S3==0); di(); switch(s1num) { case 1: miao--; if(miao==-1) miao=59; write_sfm(8,miao); write_com(0x80+0x40+8) break; case 2: fen--;

14

; 电子万年历

if(fen==-1) fen=59;

write_sfm(5,fen);

write_com(0x80+0x40+5) ; case 3: case 4: case 5: case 6: case 7: } } } }

if(S4==0) {

delay(5);

break; shi--; if(shi==-1) shi=23;

write_sfm(2,shi);

write_com(0x80+0x40+2) break;

week--; if(week==0) week=7;

write_week(week);

write_com(0x80+12) ; break; day--; if(day==0) day=31;

write_nyr(9,day); write_com(0x80+9) ; break;

month--; if(month==0) month=12;

write_nyr(6,month); write_com(0x80+6) ; break;

year--; if(year==-1) year=99;

write_nyr(3,year); write_com(0x80+3) ; break;

15

; 电子万年历

if(S4==0) { flag1=~flag1; while(S4==0); di(); if(flag1==0) { flag=0; write_com(0x80+0x40); write_date(' '); write_date(' '); write_com(0x0c); write_ds(1,miao); write_ds(3,fen); write_ds(5,shi); } else //进入闹钟设置 { read_alarm(); //读取原始数据 miao=amiao; //重新赋值用按键调节 fen=afen; shi=ashi; write_com(0x80+0x40); write_date('L'); //显示标志 write_date(' '); write_com(0x80+0x40+3); write_sfm(2,ashi); //送液晶显示闹钟时间 write_sfm(5,afen); write_sfm(8,amiao); } } } }

void write_ds(uchar add,uchar date) //12C887函数 {

dscs=0; dsas=1; dsds=1; dsrw=1; P2=add; //先写地址 dsas=0; dsrw=0;

P2=date; //再写数据

16

电子万年历

dsrw=1; dsas=1; dscs=1; }

uchar read_ds(uchar add) //读12C887函数 {

uchar ds_date; dsas=1; dsds=1; dsrw=1; dscs=0; P2=add; //先写地址 dsas=0; dsds=0; P2=0xff;

ds_date=P2; //再读数据 dsds=1; dsas=1; dscs=1;

return ds_date; }

/*void set_time() {

write_ds(0,0); write_ds(1,0); write_ds(2,0); write_ds(3,0); write_ds(4,0); write_ds(5,0); write_ds(6,0); write_ds(7,0); write_ds(8,0); write_ds(9,0); } */

void read_alarm() {

amiao=read_ds(1); afen=read_ds(3); ashi=read_ds(5); }

void main() {

init();

17

电子万年历

while(1) { keyscan(); //按键扫描 if(flag_ri==1) //当闹钟中断时进入这里 { di(); delay(100); di(); delay(500); } if(flag==0&&flag1==0) //正常工作时进入这里 { keyscan(); //按键扫描 year=read_ds(9); //读取12C887数据 month=read_ds(8); day=read_ds(7); week=read_ds(6); shi=read_ds(4); fen=read_ds(2); miao=read_ds(0); if(fen==0&&miao==0) { di(); delay(100); di(); delay(500); } write_sfm(8,miao);//送液晶显示 write_sfm(5,fen); write_sfm(2,shi); write_week(week); write_nyr(3,year); write_nyr(6,month); write_nyr(9,day); } } }

void exter()interrupt 2 //外部中断1服务程序 {

uchar c; //进入中断表示闹钟时间到

flag_ri=1; //设置标志位,用以大程序中报警提示

c=read_ds(0x0c); //读取12C887的C寄存器表示响应了中断 }

18

电子万年历

5 调试及性能分析

5.1 调试原理图如图:

图8 电子万年历整体原理图

5.2 软件调试

软件调试时,开始出现了很多错误,主要是液晶屏乱码,不显示数字。后来经过调试找出原因并改正得到想要的结果。

5.3 硬件调试

硬件主要是单片机,液晶,DS12C887芯片,我们的任务是主要将他们各个引脚的作用和芯片的功能弄清楚,通过软件操控它们,按照PCB原理图焊接到板上。

5.4 系统性能分析

功能主要有整点报时,掉电免校验,闹钟,按键校对功能等,通过键盘和软件设置来控制时钟功能,我们是按照顺序一个一个进行调试的,这样层次清晰写起程序来也容易。

19

电子万年历

六 总 结

这次课程设计,我们组三个人分工合作。从一开始的选题,然后确定方案、买零件,到最后的设计调试,我们组员都在一起研究讨论。经过这次设计,我们三个人都有了很大的收获,对单片机编程控制有了进一步的了解。

该设计涉及到了单片机的时序控制,数据接口同时用到了控制按键、数据显示处理等。这次设计,基本上涉及到了所有的单片机控制功能模块。因此,通过这次设计,基本能掌握单片机的所有基本控制,这也是我们组选择该题目的一个重要原因。

七 参考文献

[1] 郭天祥.新概念51单片机C语言教程[M].北京:电子工业出版社,2009. [2] 胡汉才.单片机原理与接口技术[M].北京: 清华大学大学出版社,2004.1-505. [3] 邢国泉. LM35温度传感器的温度特性及其应用[J]. 医疗设备信息.2007,11,25-28.

[4] 薛国红,赵修斌,卢艳娥等.零漂与增益控制对量化的影响分析[J].西安:空军工程大学,2008. [5] 马忠梅,刘滨等. 单片机C语言Windows环境编程宝典[M]. 北京: 北京航空航天大学出版社. 2003.

八 附录

附录1 元器件清单

元器件名称 单片机 时钟芯片 液晶显示器 晶振 电阻 电阻 电位器 瓷片电容 瓷片电容 型号 STC89C51 DS12C887 LCD1602 11.0596MHZ 1K 4.7K 10K 22pF 0.1uF 20

数量(个) 1 1 1 1 1 1 1 2 2 电子万年历

电源接口 杜邦线 排针 蜂鸣器 按键 总计 5V 1 30 5 1 4 25 21

电子万年历

附录2 调试系统照片

整体显示如图:

图9 电子万年历

显示部分如图:

图10 显示时间部分

22

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