1、。 目录1、设计目的22、系统方案设计22.1 设计任务及要求22.1.1 设计任务22.1.2 设计要求22.2 方案设计32.2.1 设计原理32.2.2 模块分析32.2.3总原理图以及主程序流程图82.2.4 proteus仿真结果92.2.5实验结果93、设计总计104、参考文献11附录:源程序111、设计目的单片机项目设计是以课题或设计方式开展的一门课程,具有较强的综合性、实践性,是工科、工程类院校或职业类院校电类专业在校生的必修课,是将单片机原理与应用课程的理论知识转变为应用技术的重要教学环节。这一环节不但能加深对单片机原理的理解,而且还能培养学生的实践动手能力,开发学生的分析、
2、解决问题的能力。单片机项目设计环节的训练能够让学生知道单片机工程项目的制作过程,使学生尽早了解单片机系统的开发流程。掌握单片机系统的开发应用,巩固和加深已学过的知识,提高动手能力及解决实际问题的能力,同时培养团队合作精神。将自己学到的知识更好地运用于实际当中。2、系统方案设计2.1 设计任务及要求2.1.1 设计任务 (1)根据技术要求和现有开发环境,制作智能电子钟(LCD);(2)设计系统实现方案;(3)设计并绘制电路原理图;(4)画出功能模块的程序流程图;(5)使用汇编语言(或C语言)编写实现程序(6)结合硬件调试、修改并完善程序;(7)编写课程设计报告。2.1.2 设计要求(1) 计时:
3、秒、分、时、天、周、月、年。(2) 闰年自动判别。(3)自定任意时刻自动开/关屏。(4) 计时精度:误差1秒/月(具有微调设置)。(5) 键盘采用动态扫描方式查询。所有的查询、设置功能均由功能键K1、K2完成。(6)选作内容:编写上位机程序,通过串口发送指令来调整时钟。2.2 方案设计2.2.1 设计原理此设计原理框图如图2-1所示,此电路包括以下四个部分:单片机,键盘,DS1302时钟采集模块及LCD1602液晶显示屏。经过编译程序仿真后,89C51的4K空间不够用,就选用更大空间的89C52单片机了。本设计用的元器件如列表2-1所示DS1302时钟采集模块89C52CPU控制模块按键处理模
4、块LCD显示模块 图2-12.2.2 模块分析 1DS1302时钟采集模块(1)DS1302电路图(2)DS1302芯片分析 DS1302是DALLAS公司推出的涓流充电时钟芯片。内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。DS1302芯片广脚介绍:X1、X2为32.768KHz晶振管脚。GND 为地。RST复位脚。I/O数据输入/输出引脚。SCLK串行时钟。Vcc1,Vcc2电源供电管脚。与单片机连接的信号线为: DS1302_SCLK 接P16 ; 实时时钟时钟线引脚 D
5、S1302_IO 接P17; 实时时钟数据线引脚 DS1302_RST 接P15; 实时时钟复位线引脚特别注意DS1302芯片在读取或写入数据时,都是一位一位传送的,并且每传送一位,SCLK信号线要有一个负跳变。数据时通过IO进行传送的。(3)数据处理流程图是否调用时间获取子程序 否 是调用Read1302函数,读取各个时间参数。对各个时间参数数据进行转换,转换成十进制数,并赋给Time指针中。调用年份转换成可供lcd显示的字段子程序。时间转换成可供lcd显示的字段子程序。结束2. LCD1602液晶显示模块 (1)LCD1602模块电路图(2)LCD1602芯片以及连线分析 液晶显示器是一种
6、功耗极低的被动式显示器件,1602广脚介绍:D0D7数据传送引脚,VSS为接地线,VDD为电源线,VEE为 LCD驱动电压调节,由此可以调节显示亮度。RS为寄存器选择信号,高电平选择数据寄存器,低电平选择指令寄存器。RW为读写控制信号,高电平读,低电平写。EN使能信号,读状态下高电平有效,写状态下下降沿有效。RS连接P20; 寄存器选择信号RW连接P21; 读写控制信号线EN连接P22; 使能信号线写指令0x38,显示模式设置(3)LCD初始化程序流程图:写指令,显示光标写指令,光标移动清屏 3.按键模块 (1)按键模块电路图 其中按键key1为选择键,按键key2为加1键,按键key3为减1
7、键。与单片机连线如下:Key1连接P30; Key2连接P31;Key3连接P32; (2)按键扫描流程图Key1键是否按下 将key1按键次数存放于变量key1n中1n=1 ?1n=5 ?1n=4 ?1n=3 ?1n=2 ? 否 否 否 否 是是是是是 1n=7?1n=6? 否 否 是 是移动光标3.加减键处理子程序流程图判断是否为修改模式 否判断是否为加1键 是转减1键程序 否 是判断key2=3判断key2=2?判断key2=1? 否 否 是 是 是修改day值修改mon值修改year值判断key2=4?判断key2=6?判断key2=5? 否 否 是修改分值修改day值修改week值
8、是 是 判断key2=7?修改秒值是减1子程序与加1子程序区别只在于修改数值处理不一样,其他都一样。2.2.3总原理图以及主程序流程图1.总原理图2.主程序流程图 初始化lcd初始化内部定时器初始化DS1302从DS1302读取日期和时间移动光标并显示日期移动光标并显示时间重复进行按键扫描2.2.4 proteus仿真结果2.2.5实验结果1、在该电子钟的设计中修改定时或调整时间时采用了闪烁,在编程上,首先进行了初始化定义了程序的入口地址以及中断的入口地址,在主程序的开始定义了一组固定单元用来存储计数的秒,分,时以及定时时间的序号等。其次,时,分,秒显示用了软件译码(查表)的方式,再用了一段固
9、定的程序段进行进制转化。最后,用查询方式对按键进行判断,若有键按下,则进行软件延时消抖,避免了抖动引起的干扰,执行相应的定时,选时或调时程序段。对当前时间或定时时间修改后又返回到最初的显示程序段,如此循环下去。2、在硬件上,选用DS1302,LCD1602相结合,首先DS1302内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作,这样读取数据简单。其次,选用LCD1602进行显示时,数据位串行输入,接口连线少,低功耗,显示清晰。并且本实验的电子钟即要实现时间的现实,还要实现日期的现实
10、,所以若是运用数码管进行显示的话,就算运用动态显示,所占用的IO口多,并且所需的数码管个数多,硬件复杂。3、proteus是一个非常好用的仿真软件,其具有强大的电路原理图绘制功能,且可以实现模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统仿真、键盘、LCD系统仿真等多种功能;和keil联合使用时可以检测所编写的程序的正确与否。将keil和proteus联合起来使用是实现电子设计制作的初步阶段,可避免在实际的硬件操作中因为电路原理图或向单片机烧录的程序有误而造成的难以修改的为题。3、设计总计通过本次智能电子时钟的课程设计,我学习将理论和实践相结合,初步掌握综合运用所学知识分析和设计一般数
11、字系统的基本方法,增强动手解决实际问题的能力。通过这次设计,我学会了了初步设计电路的整体思想。学会了怎样查找资料,设计电路。熟悉了绘制电路原理图和电路的调试整个过程,是所学的知识应用到实践,进一步所学的知识。本次实验也使我认识到了自身的许多缺点和不足,因为自身水平有限,要自己编写C程序很难,但在此实验中,最大的收获莫过于看懂别人的程序,分析之后,自己拼凑编写以实现不同的功能。使我明白现实生活中电子钟的工作原理,锻炼了查找资料的能力。通过这次课程设计,让我体会到今天认真的进行课程设计,学会脚踏实地迈开这一步,就是为明天能稳健地在社会大潮中奔跑打下坚实的基础。通过这次智能电子时钟设计,人在多方面都
12、有所提高。通过这次智能电子时钟设计,综合运用本专业所学课程的理论和生产实际知识进行智能电子时钟设计工作的实际训练从而培养和提高学生独立工作能力,巩固与扩充了课程所学的内容,智能电子时钟设计的方法和步骤,握智能电子时钟设计的工艺方案,解了智能电子时钟的基本结构,悉了规范和标准,时各科相关的课程都有了全面的复习,立思考的能力也有了提高。整个设计过程让我收获很多,前所学过的理论知识又再次重现在我们的脑海中,经过了自己的亲手实践使我们更好的理解和掌握了那些知识。同时,经过这短短几天的课程设计也使我提高了自己与其他同学交流沟通的能力。这次课程设计也使我明白了“实践是检验真理的唯一标准”,要想更好的掌握以
13、前学过的知识除了定期的“温故知新”外,还需要进行一些实验和实践。使我们的理论和实践能力同步提高,这次课程设计也使我深刻的认识到了团队合作的重要性。4、参考文献1 张毅刚.单片机原理及应用J.高等教育出版社,2009.22.孙育才,王荣兴,孙华芳,新型AT89S52系列单片机及其应用. 北京:清华大学出版社,2005.1.13.朱清慧,张凤蕊,王志奎,Proteus教程电子线路设计、制版与仿真,北京:清华大学出版社,2008.9.14.侯玉宝,陈忠平,李成群等,基于Proteus 的51系列单片机设计与仿真,北京:电子工业出版社,2008.9.15.彭小军用单片机实现电子时钟J新余高专学报,20
14、04,9(2):54-576.徐宏亮,艾学忠等实现多功能电子时钟设计J吉林化工学院学报,2001,5(1):26-297.朱路,朱清慧,连续补充充电实时时钟芯片DS1302及其应用,河南:南阳理工出版社,20068.杨将军,李华军,刘东骏,单片机程序设计及应用,北京:电子工业出版社,2006.3附录:源程序#include#define uint unsigned int#define uchar unsigned char#define yh 0x80 /第一行的初始位置#define er 0x80+0x40 /第二行初始位置#define true(x) x = 1#define fal
15、s(x) x = 0sbit du = P26;sbit we = P27;sbit wr = P21;sbit rs = P20;sbit en = P22;sbit SCLK = P16; sbit IO = P17; sbit RST = P15; sbit ACC0 = ACC0;sbit ACC7 = ACC7;sbit key1 = P30;sbit key2 = P31;sbit key3 = P32;uchar code tab1=20 - - ;uchar code tab2= : : ;uchar a,sec,hour,min,day,mon,year,week,flag,
16、temp,key1n=0;void delay(uchar xms) /延时函数uchar y;while(xms-)for(y = 0;y 0;a -)IO = ACC0;fals(SCLK);true(SCLK);ACC = ACC 1;uchar readds1302_1byte() /读出ds1302的一个数据true(RST);for(a = 8;a 0;a -)ACC7 = IO;true(SCLK);fals(SCLK);ACC = ACC 1;return(ACC);void write_ds1302(uchar add,uchar dat) /向ds1302中写入数据fals
17、(RST);fals(SCLK);true(RST);writeds1302_1byte(add); /给ds1302输入寻址指令writeds1302_1byte(dat); /ds1302寻到上面地址后写入相应数据true(SCLK);fals(RST);uchar read_ds1302(uchar add) /读出相应地址上的数据 uchar temp;fals(RST );fals(SCLK);true(RST );writeds1302_1byte(add ); /给ds1302输入寻址指令temp=readds1302_1byte(); /找到相应地址后,读出其数据true(SC
18、LK);fals(RST );return temp;uchar BCD_Decimal(uchar bcd) /将相应的BCD码转换为10进制(各个位上不会出现大于9的数)uchar Decimal;Decimal = bcd 4 ;return(Decimal = Decimal * 10 + (bcd &= 0x0F);void write_1602sfm(uchar add,uchar dat) /写时分秒uchar gw,sw;gw = dat % 10;sw = dat / 10;write_1602com(er + add);write_1602dat(0x30 + sw );w
19、rite_1602dat(0x30 + gw );void write_1602nyr(uchar add,uchar dat)uchar gw,sw;gw = dat % 10;sw = dat / 10;write_1602com(yh + add); /给液晶1602写入一个地址write_1602dat(0x30 + sw );write_1602dat(0x30 + gw ); /给那个地址上写入一个2位数void write_1602week(uchar week) /写星期函数write_1602com(yh + 0x0d); /要写星期的地址switch(week)case 1
20、: write_1602dat(M);write_1602dat(O);write_1602dat(N);break;case 2: write_1602dat(T);write_1602dat(U);write_1602dat(E);break;case 3: write_1602dat(W);write_1602dat(E);write_1602dat(D);break;case 4: write_1602dat(T);write_1602dat(H);write_1602dat(U);break;case 5: write_1602dat(F);write_1602dat(R);writ
21、e_1602dat(I);break;case 6: write_1602dat(S);write_1602dat(T);write_1602dat(A);break;case 7: write_1602dat(S);write_1602dat(U);write_1602dat(N);break;void deal_3day()if(mon=1|mon=3|mon=5|mon=7|mon=8|mon=10|mon=12)day=32;else if(mon=4|mon=6|mon=9|mon=11)day=31;else if(mon=2&(year%4=0&year%100!=0|year%
22、400=0)day=30;elseday=29;void keyscan()if(key1 = 0) /key1为功能键delay(5);if(key1 = 0)while( !key1);delay(10);while( !key1); /松手检测key1n +;if(key1n = 9)key1n = 1;switch(key1n)case 1: fals(TR0); /关闭定时器 write_1602com(er+0x0b); /写入光标位置write_1602com(0x0f ); /设置光标为闪烁write_ds1302(0x8e,0x00); write_1602com(yh +
23、0x05); /nianwrite_ds1302(0x8e,0x80);break;case 2: write_1602com(yh + 0x08); /月break; case 3: write_1602com(yh + 0x0b); /日break;case 4: write_1602com(yh + 0x0f); /星期break;case 5: write_1602com(er + 5); /时break;case 6: write_1602com(er+8); /分break;case 7: write_1602com(er+0x0b); /因为设置液晶的模式是写入数据后,指针自动加
24、一,在这里是写回原来的位置break;case 8:write_1602com(0x0c ); /设置光标不闪烁true(TR0); /打开定时器temp = (sec)/10*16 + (sec)%10;write_ds1302(0x8e,0x00);write_ds1302(0x80,0x00|temp); /秒write_ds1302(0x8e,0x80);key1n=0;break;if(key1n != 0) /当key1按下以下。再按以下键才有效if(key2 = 0) /上调键delay(5);if(key2 = 0)while( !key2);delay(10);while(
25、!key2);switch(key1n)case 1: year +;if(year = 100)year = 0;write_1602nyr(4,year);temp = (year)/10*16 + (year)%10;write_ds1302(0x8e,0x00);write_ds1302(0x8c,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 5);break;case 2: mon+;if(mon = 13)mon = 1;write_1602nyr(7,mon);temp = (mon)/10*16 + (mon)%10;writ
26、e_ds1302(0x8e,0x00);write_ds1302(0x88,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 8);break; case 3: day +; if(mon=1|mon=3|mon=5|mon=7|mon=8|mon=10|mon=12) if(day = 32) day = 1; else if(mon=4|mon=6|mon=9|mon=11) if(day = 31) day = 1; else if(mon=2&(year%4=0&year%100!=0|year%400=0) if(day = 30) d
27、ay = 1; else if(day = 29) day = 1; if(day = 32)day = 1;write_1602nyr(10,day);temp = (day)/10*16 + (day)%10;write_ds1302(0x8e,0x00);write_ds1302(0x86,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 11);break; case 4: week +;if(week = 8)week = 1;write_1602week(week);write_ds1302(0x8e,0x00);write_ds13
28、02(0x8a,week);write_ds1302(0x8e,0x80);write_1602com(yh + 0x0f);break; case 5: hour +;if(hour =24)hour = 0;write_1602sfm(4,hour);temp = (hour)/10*16 + (hour)%10;write_ds1302(0x8e,0x00);write_ds1302(0x84,temp);write_ds1302(0x8e,0x80);write_1602com(er + 5);break; case 6: min +;if(min = 60)min = 0;write
29、_1602sfm(0x07,min);temp = (min)/10*16 + (min)%10;write_ds1302(0x8e,0x00);write_ds1302(0x82,temp);write_ds1302(0x8e,0x80);write_1602com(er + 8);break;case 7: sec +;if(sec = 60)sec = 0;write_1602sfm(0x0a,sec); /写入新的秒数temp = (sec)/10*16 + (sec)%10;write_ds1302(0x8e,0x00);write_ds1302(0x80,0x80|temp);wr
30、ite_ds1302(0x8e,0x80);write_1602com(er+0x0b); /因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置break;if(key3 = 0)delay(5);if(key3 = 0)while( !key3);delay(10);while( !key3);switch(key1n) case 1: year -; if(year =-1)year = 99;write_1602nyr(4,year);temp = (year)/10*16 + (year)%10;write_ds1302(0x8e,0x00);write_ds1302
31、(0x8c,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 5);break;case 2: mon -; if(mon = 0)mon = 12;write_1602nyr(7,mon);temp = (mon)/10*16 + (mon)%10;write_ds1302(0x8e,0x00);write_ds1302(0x88,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 8);break;case 3: day -; if(day = 0)deal_3day(); day = 31;wr
32、ite_1602nyr(10,day);temp = (day)/10*16 + (day)%10;write_ds1302(0x8e,0x00);write_ds1302(0x86,temp);write_ds1302(0x8e,0x80);write_1602com(yh + 11);break;case 4: week -; if(week =0 )week = 7;write_1602week(week);write_ds1302(0x8e,0x00);write_ds1302(0x8a,week);write_ds1302(0x8e,0x80);write_1602com(yh +
33、0x0f);break;case 5: hour -; if(hour = -1)hour = 23;write_1602sfm(4,hour);temp = (hour)/10*16 + (hour)%10;write_ds1302(0x8e,0x00);write_ds1302(0x84,temp);write_ds1302(0x8e,0x80);write_1602com(er + 5);break;case 6:min -; if(min = -1)min = 59;write_1602sfm(7,min);temp = (min)/10*16 + (min)%10;write_ds130