毕业论文基于PIC16F877的智能电子钟设计.docx
《毕业论文基于PIC16F877的智能电子钟设计.docx》由会员分享,可在线阅读,更多相关《毕业论文基于PIC16F877的智能电子钟设计.docx(32页珍藏版)》请在冰豆网上搜索。
![毕业论文基于PIC16F877的智能电子钟设计.docx](https://file1.bdocx.com/fileroot1/2023-2/1/d676b94b-6e25-45a0-9698-90e9ba4dbc39/d676b94b-6e25-45a0-9698-90e9ba4dbc391.gif)
毕业论文基于PIC16F877的智能电子钟设计
基于PIC16F877的智能电子钟设计
1引言
随着电子技术产业结构调整,生产工艺的飞速发展,人们生活水平的不断提高,家用电器逐渐普及,而随着人们对周围环境便利程度的要求,市场对于智能时钟控制系统的需求也越来越大。
智能钟应实现的主要功能为:
能实现二十四小时制的时分秒显示,具有快速手动校时电路,具有整点报时功能,具有闹钟表功能(可设置时分),具有倒计时功能。
2 设计原理及方案
2.1设计原理
单片机是一门技术性、应用性很强的学科,实践教学是它的一个极为重要的环节。
不论是硬件扩展、接口应用还是编程方法、程序调试,都离不开实践。
本次设计的目的是通过完成一个涉及PIC单片机都种资源应用并具有综合功能的小系统目标板的设计与编程应用,能够对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排版调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立进行某些单片机应用系统的开发设计工作打下一定的基础。
ﻫ 该电子时钟不但具有显示时、分、秒的作用,而且用按键还可以实现时间的调整和闹铃的设定。
本次综合实践完成了在单片机数据采集与定时系统的硬件电路设计后的基础上,焊接制作电路板,完成该系统的软件设计与调试。
待仿真成功后,再将程序烧写入单片机中。
2.2 设计方案
系统结构整个电子时钟系统电路可分为五大部分:
中央处理单元(CPU)、电源电路部分、显示部分、键盘输入部分。
系统由PIC16F877、LED数码管、按键、发光二极管等部分构成,能实现时间的调整、定时时间的设定,输出等功能。
系统的功能选择由SB0、SB1、SB2、SB3、SB4 完成。
其中SB0为时间校对,定时器调整功能键,按SB0 进入调整状态。
SB1为功能切换键。
第一轮按动 SB1依次进入一路、二路、三路定时时间设置提示程序,按SB3进入各路定时调整状态。
定时时间到,二极管发亮。
到了关断时间后灭掉。
如果不进入继续按SB1键,依次进入时间年位校对、月位校对、日位校对、时位校对、分位校对、秒位校对状态。
不管是进入那种状态,按动SB2 皆可以使被调整位进行不进位增量加1变化。
各预置量设置完成后,系统将所有的设置存入RAM中,按SB1退出调整状态。
上电后,系统自动进入计时状态,起始于00时 00 分。
SB4为年月日显示转换键,可使原来显示时分秒转换显示年月日。
3硬件设计
3.1 原理图设计
智能钟原理图如图3.1所示
图3.1智能钟原理图
3.2元器件选择
3.2.1 中央处理单元
CPU选用PIC16F877对整个系统进行控制:
1)它将定时数据输出到LED,实现时间的显示;ﻫ2)根据键盘输入调用相应键处理子程序,实现时间的调整和闹铃的设定;ﻫ3.2.2电源电路部分
在各种电子设备中,直流稳压电源是必不可少的组成部分,它是电子设备唯一能量来源,它的设计思路是根据我们以前学过的模电电子技术,要想得到我们所要的+6V输出电压,就需将交流220V的电压经过变压器、整流电路、滤波电路和稳压电路四个部分。
3.2.3 显示部分
显示部分是整个电子时钟最为重要的部分,共需要6位LED显示器。
采用动态显示方式,所谓动态显示方式是时间(或温度)数字在LED上一个一个逐个显示,它是通过位选端控制在哪个LED上显示数字,由于这些LED数字显示之间的时间非常的短,使的人眼看来它们是一起显示时间数字的,并且动态显示方式所用的接口少,节省了CPU的管脚。
由于端口的问题以及动态显示方式的优越性,在此设计的连接方式上采用共阴极接法。
显示器LED有段选和位选两个端口,首先说段选端,它由LED八个端口构成,通过对这八个端口输入的不同的二进制数据使得它的时间显示也不同,从而可以得到我们所要的时间显示
3.2.4 位选电阻与段选电阻
位选电阻=(VCC-0.7-0.3)/IB=(5-0.7-0.3)/(48/80) =6.66千欧,取6.8千欧。
段选电阻=(VCC-VCEO-VD-0.3)/IB=(5-0.3-2-0.3)/6=400欧,取390欧。
其中,单片机I/O口为CMOS电路,均通过一个FET(场效应管)接地,因此在计算时均应减去0.3V。
3.2.5蜂鸣器电阻
蜂鸣器选用ZC17040,额定电压3V,额定电流小于1毫安。
限流电阻R=(5V-3V-0.3V)/1mA=1.7(千欧)取电阻为2千欧。
3.3PCB图设计
智能钟PCB图如图3.2所示
图3.2智能钟PCB图
4软件设计
4.1 流程图
4.1.1 主程序流程图
如图4.1.1
4.1.2时钟计时子程序流程图
如图4.1.2
图4.1.1智能钟主程序流程图 图4.1.2时钟计时子程序流程图
4.1.3键盘扫描子程序流程图
4.1.4R0中断服务子程序流图
图4.1.3键盘扫描流程图 图4.1.4 中断服务子程序流程图
4.2源程序
见附录
总 结
嵌入式测控系统设计及实践是一门实践性比较强的课程,也是我在大学期间学得最认真的一门课程。
通过这门课,使我受益匪浅,主要表现在以下几个方面:
(1)通过这对这门课的学习,我基本掌握了单片机原理,学会了用Protel99 SE画原理图并生成相应的PCB,学会了嵌入式系统的开发流程,并能够利用51或PIC系列单片机去设计一个小型的嵌入式系统。
而且我也充分认识到了单片机的重要性,对单片机开发产生了浓厚的兴趣。
(2)我们这一组是用PIC16F877去做,但做的过程中我们发现了很多问题,比如电子元器件的选择与购买,以及电路的焊接。
由此我认为,在单片机开发中,经验往往是很重要的,而多去做实践有利于经验的积累,这应该是我们这门课程与设计的意义所在。
(3)上完这门课后,我对单片机的总体感觉是:
单片机比较适合做产品研发或系统设计,而我们以前学的PLC则比较适合于工程控制,它比用单片机控制要简单一些。
相比PLC,用单片机做系统设计要难很多,而且网上的相关资料显示,PLC比较适合于环境比较恶劣的工业现场。
因此,学会用PLC做控制也是很重要的。
但我发现,PLC与单片机也有某些类似的地方,而且,学完单片机后,我发现PLC变得容易了。
由此我发现,其实任何学科都是相通的。
(4)我们以前学的是51系列单片机,而这次我们用PIC系列。
通过对比我们发现,51与PIC的在原理与编程方面有着类似的地方,尽管它的的指令系统不同,但它们基本思想是相同的,因此我们没有花很长时间就从51过渡到了PIC。
由此我发现,其实51也好,PIC也好,只要学会并精通其中的一种,对其它类型的8位单片机也能触类旁通,以不变应万变了。
8位单片机我学会了51和PIC,我下一步的计划是学习32位的ARM,因为我认为,32位单片机相比8位单片机有着更强大的功能和更好的发展前景。
致 谢
在做学习嵌入式系统设计的这段时间里,我们曾经遇到过很多的难题,也产生了很多的疑问。
但在老师和同学们的帮助以及自己的不断努力下,终于成功地完成了这门课的学习。
在这里,我们要首先感谢***老师,他给了我们很大的支持、鼓励和帮助。
在我们遇到问题的时候,他们总是很及时地给我们指点迷津,提出建议,使我们不致于在盲区内停留太久。
在学习过程中,老师以其严谨求实的治学态度,高度的敬业精神,孜孜以求的工作作风和大胆创新的进取精神对我们影响很大。
他们渊博的知识,开阔的视野和敏锐的思维让我们敬佩不已。
当然,在此期间我同组的同学们也是纷纷帮我们出谋划策,提出很真诚的建议,使我们受益匪浅,请我们表达对你们深深地谢意。
参考文献
[1]赵佩华.单片机接口技术及应用.北京:
机械工业出版社,2003.1
[2] 谢宜仁,谢伟,谢东辰.单片机使用技术问答.北京:
人民邮电出版社,2003.2
[3]薛宗祥,鹿树理,朱惠英.8位单片机原理与应用. 北京:
北京航空航天大学出版社,1999.9
[4] 何立民.MCS-51系列单片机应用系统设计.北京:
北京航空航天大学出版社,2002.7
[5]李荣正.PIC单片机原理与应用(第2版). 北京:
北京航空航天大学出版社,2005.1
附录
源程序:
//shizhong.h,头文件。
/***********************************************************
功能:
利用PIC16F877做的电子时钟程序
***********************************************************/
//shizhong.h文件,主要实现预编译、函数的申明以及全局变量的定义。
#defineucharunsignedcharﻩ//在程序中用uchar代替无符号字符型数据
#define uint unsignedint//在程序中用uint代替无符号整型数据
#defineDELAY_VALUE1ﻩﻩ//定义数码管显示延时值
#defineKEY_DELAY_VALUE 3ﻩ//定义按键去抖动延时值
#define speakerRD6//蜂鸣器
#define LEDRD7ﻩﻩ//LED
#definesw1RB1ﻩﻩﻩﻩﻩ//按键1
#definesw2RB2ﻩﻩﻩﻩ//按键2
#definesw3RB4ﻩﻩﻩ//按键3
#definesw4RB5ﻩﻩ//按键4
#definesmg1RD0ﻩﻩﻩ//数码管1的位选
#definesmg2ﻩRD1ﻩﻩ//数码管2的位选
#definesmg3RD2ﻩﻩ//数码管3的位选
#definesmg4RD3ﻩﻩ//数码管4的位选
#definesmg5ﻩRD4ﻩﻩﻩ//数码管5的位选
#definesmg6RD5ﻩﻩ//数码管6的位选
voidinterrupt tmr0(void);//申明定时器中断函数
voidPORT_INIT(void);ﻩ//申明端口初始化函数
voidTMR0_INIT(void);ﻩ//申明定时器初始化函数
voidTime_Tran(void);//申明时间数值个时位分离函数
voidTime_Dis(void);ﻩﻩﻩ//申明时间显示函数
voidDisplay(uchar i,ucharnum);//申明数码管显示函数
voidDelay(uintk);ﻩ//申明延时函数
void Time_init(void);ﻩ//申明时间初始化函数
voidSpeaking(uintspeak_value,uintstop_value);//申明蜂鸣器函数
ucharKeyscan(void);//申明按键函数
voidSw1_Press(void);//申明按键1计数函数
voidSet_Clock(void);ﻩﻩ//申明时间设置函数
ucharSw4_Press(void);ﻩ//申明按键4计数函数
void Set_Alarm(void);//申明闹钟设置函数
void Alarm(void);ﻩﻩ//申明闹钟函数
void Alarm_Speaking(void);ﻩ//申明闹钟报警函数
voidSpeaking_Delay(uint k);//申明蜂鸣器函数
void StopWatch(void);ﻩ//申明秒表函数
voidSW_Time(void);ﻩﻩ//申明秒表计时函数
void Sw2_Press(void);ﻩﻩﻩ//申明按键2计数函数
voidDaojishi(void);ﻩ//申明倒计时函数
void Djs_Time(void);ﻩﻩ//申明倒计时计时函数
//声明程序中用到的相关全局变量
externintyear;
externsignedcharmonth,day,hour,minu,sec,week;
externucharcount;
externucharmiao_ge,miao_shi,fei_ge,fei_shi,shi_ge,shi_shi;
externucharday_ge,day_shi,month_ge,month_shi,year_ge,year_shi,year_bai,year_qian;
extern ucharkeyword,sw1_press_num,sw4_press_num;
externucharhour_alarm,minu_alarm;
externucharalarm_hour_shi,alarm_hour_ge,alarm_minu_shi,alarm_minu_ge;
externuchar alarm_stop;
externucharsw_minu,sw_sec,sw_count;
extern ucharsw_minu_shi,sw_minu_ge,sw_sec_shi,sw_sec_ge,sw_count_shi,sw_count_ge;
externuchar sw2_press_num;
externuchar watch_stop;
externsignedchardjs_hour,djs_minu,djs_sec,djs_count;
externuchardjs_hour_shi,djs_hour_ge,djs_minu_shi,djs_minu_ge,djs_sec_shi,djs_sec_ge;
externuchardjs_start;
/clock.c文件,时钟计时程序。
#include
#include<pic.h>
#include"shizhong.h"
//TMR0中断程序
voidinterrupttmr0(void)
{
if(T0IE&&T0IF)
{
TMR0=100;
T0IF=0; //清除中断标志位
ﻩ count++;//中断产生秒信号
ﻩif(watch_stop==1)sw_count++;
ﻩ if(djs_start==1)djs_count++;
ﻩif(count>=150)
ﻩ{
ﻩﻩcount=0;
ﻩﻩsec++;
ﻩif(sec>=60)
ﻩﻩ{
ﻩsec=0;
ﻩﻩﻩ minu++;
ﻩﻩ if(minu>=60)
ﻩ {
ﻩ minu=0;
ﻩﻩ hour++;
ﻩﻩ//Speaking(100,0);
ﻩﻩ if(hour>=24)
ﻩﻩ{
ﻩhour=0;
ﻩ day++;
ﻩﻩﻩ{
ﻩﻩﻩﻩif(week<7)week++;
ﻩﻩﻩﻩelseweek=0;
ﻩﻩﻩﻩﻩ}
ﻩﻩﻩ if(day>=31)
ﻩ{
ﻩﻩday=1;
ﻩﻩﻩ month++;
ﻩﻩif(month>=13)
ﻩﻩﻩﻩ{
ﻩﻩﻩmonth=1;
ﻩﻩyear++;
ﻩﻩﻩﻩﻩ}
ﻩﻩﻩﻩ}
ﻩﻩ }
ﻩﻩﻩ }
ﻩﻩ}
}
}
}
//时间转换函数,将时间的个位与十位分离出来以便显示
voidTime_Tran(void)
{
miao_ge=sec%10;
miao_shi=sec/10;
fei_ge=minu%10;
fei_shi=minu/10;
shi_ge=hour%10;
shi_shi=hour/10;
day_ge=day%10;
ﻩday_shi=day/10;
ﻩmonth_ge=month%10;
month_shi=month/10;
ﻩyear_qian=year/1000;ﻩ
year_bai=(year/100)%10;
ﻩyear_shi=(year%100)/10;
ﻩyear_ge=year%10;
alarm_hour_shi=hour_alarm/10;
ﻩ alarm_hour_ge=hour_alarm%10;
ﻩalarm_minu_shi=minu_alarm/10;
ﻩalarm_minu_ge=minu_alarm%10;
sw_minu_shi=sw_minu/10;
sw_minu_ge=sw_minu%10;
ﻩsw_sec_shi=sw_sec/10;
sw_sec_ge=sw_sec%10;
sw_count_shi=sw_count/10;
sw_count_ge=sw_count%10;
djs_hour_shi=djs_hour/10;
djs_hour_ge=djs_hour%10;
ﻩdjs_minu_shi=djs_minu/10;
ﻩdjs_minu_ge=djs_minu%10;
djs_sec_shi=djs_sec/10;
ﻩ djs_sec_ge=djs_sec%10;
}
//时间显示子程序,按位显示时间
voidTime_Dis(void)
{
switch(sw1_press_num)
ﻩ{
ﻩ case0:
case 1:
ﻩcase 2:
case3:
ﻩﻩDisplay(1,shi_shi);
Display(2,shi_ge);
ﻩDisplay(3,fei_shi);
ﻩDisplay(4,fei_ge);
ﻩﻩDisplay(5,miao_shi);
ﻩDisplay(6,miao_ge);
ﻩbreak;
case4:
ﻩcase5:
ﻩﻩcase6:
Display(1,year_shi);
Display(2,year_ge);
Display(3,month_shi);
ﻩﻩDisplay(4,month_ge);
ﻩﻩDisplay(5,day_shi);
ﻩﻩﻩDisplay(6,day_ge);
ﻩﻩbreak;
ﻩﻩcase7:
ﻩﻩ
ﻩﻩDisplay(6,week);
ﻩﻩﻩbreak;
ﻩcase8:
ﻩﻩﻩ
ﻩﻩDisplay(3,alarm_hour_shi);
ﻩﻩDisplay(4,alarm_hour_ge);
ﻩDisplay(5,alarm_minu_shi);
ﻩDisplay(6,alarm_minu_ge);
break;
ﻩcase9:
ﻩﻩDisplay(1,sw_minu_shi);
ﻩﻩﻩDisplay(2,sw_minu_ge);
ﻩDisplay(3,sw_sec_shi);
ﻩDisplay(4,sw_sec_ge);
ﻩDisplay(5,sw_count_shi);
ﻩﻩDisplay(6,sw_count_ge);
ﻩﻩﻩbreak;
case10:
case11:
case 12:
ﻩcase13:
ﻩDisplay(1,djs_hour_shi);
Display(2,djs_hour_ge);
ﻩDisplay(3,djs_minu_shi);
ﻩDisplay(4,djs_minu_ge);
ﻩDisplay(5,djs_sec_shi);
ﻩDisplay(6,djs_sec_ge);
ﻩﻩbreak;
ﻩﻩdefault:
break;
}
}
/main.c文件,主程序。
#include //标准输入输出库
#include <pic.h>//PIC单片机自带的库
#include "shizhong.h"ﻩ//自己定义的头文件
//定义程序中用到的相关全局变量
intyear;
signedcharmonth,day,hour,minu,sec,week;
ucharcount;
ucharmiao_ge,miao_shi,fei_ge,fei_shi,shi_ge,shi_shi;
ucharday_ge,day_shi,month_ge,month_shi,year_ge,year_shi,year_bai,year_qian;
uchar keyword,sw1_press_num,sw4_press_num;
ucharhour_alarm,minu_alarm;
ucharalarm_hour_shi,alarm_hour_ge,alarm_minu_shi,alarm_minu_ge;
ucharalarm_stop;
uchar sw_minu,sw_sec,sw_count;
ucharsw_minu_shi,sw_minu_ge,sw_sec_shi,sw_sec_ge,sw_count_shi,sw_count_ge;
ucharsw2_press_num;
ucharwatch_stop;
signedchardjs_hour,djs_minu,djs_sec,djs_count;
uchardjs_hour_shi,djs_hour_ge,djs_minu_shi,djs_minu_ge,djs_sec_shi,djs_sec_ge;
uchar djs_start;
//主程序
void main(void)
{
ﻩTMR0=100; ﻩ //开启TMR0中断并赋初值
TMR0_INIT(); //定时器0初始化
ﻩTime_init();ﻩ //时间初始化
PORT_INIT(); ﻩ //端口初始化
while(1)
{ﻩ
ﻩTime_Tran(); //调用个十位分离函数
Time_Dis();ﻩ//调用时间显示函数
ﻩkeyword=Keyscan();//调用键盘扫描函数
ﻩﻩSw1_Press(); //调用按键1计数函数
Set_Clock();ﻩ //调用时间设计函数
ﻩSw4_Press();ﻩ//调用按键4计数函数
ﻩAlarm();ﻩ //调用闹钟函数
ﻩAlarm_Speaking();//调用闹钟报警函数
ﻩﻩStopWatch();//调用秒表函数
Daojishi();ﻩﻩ//调用倒计时函数
ﻩ}
}
//Set_Clock.c,时钟设置程序。
#include#include
#include "shizhong.h"
//时间设置函数
voidS