单片机课设
华 南 理 工 大 学 广 州 学 院
单片机课程设计报告
题 目: 简易电子时钟
评 分 专业: 自动化
班级: 15级自动化一班 姓名: 黎泽钧 同组队员: 郑立涵、曾迪濠、佘庭枫、
李明志、 方昊辉
学号/座位序号: [1**********]4
日 期: 2017 年 03 月
一、 设计目的
通过本次课程设计可以灵活运用单片机的基础知识,依据课程设计内容,能够完成从硬件电路图设计,到软件编程及系统调试实现系统功能,完成课程设计,加深对单片机基础知识的理解并灵活运用。
二、设计要求和方案选择
1.设计要求:
(1)通过程序直接对实时时钟时间进行设置,启动时钟运行。用8位数码管显示。
(2)通过按钮对实时时钟时间进行设置,使时钟能正常运行。
(3)其他发挥功能。
2.设计方案的选择
(1)计时方案
方案1:采用现成实时时钟芯片
使用一些实时时钟集成电路,如DS1287、DS12887、DS1302等。这些实时时钟芯片具备年、月、日、时、分、秒计时功能和多点定时等功能,计时数据的更新每秒自动进行一次,不需要程序干预。因此,在工业实时测控系统中多采用这类专用芯片来实现实时时钟功能。
方案2:使用单片机内部的可编程定时器
利用单片机内部的定时计数器进行中断定时,配合软件延时实现时、分、秒的计时。该方案优点是节省硬件成本,可以利用程序代替。缺点是程序设计相对微型控制器时钟电路声光报时校时输入数据显示较为复杂,精确度不高,同时还可能会和延时冲突,导致显示效果不佳。
鉴于以上原因,我们采用了方案二,使用了单片机内部的可编程定时器。
(2)显示器件的选择与对比
方案一:采用LED数码管显示。
LED显示器可以分为有静态显示方式和动态显示方式两种。静态显示就是当数码管显示某个字符时,相应的段恒定的导通,直到要显示下一个字符为止。数码管工作在静态显示方式时,共阴极COM端要接地;若为共阳极COM端接在+5V电源。每位的段选线应分别与一个8位数据口的输出端相连,数码管的各位是相互独立的,且要显示字符一经确定,相应数据的输出将必须维持不变。静态显示数码管一直在工作,因而数码管静态显的亮度较高。在这种显示方式编程比较容
易,管理也较简单,但占用I/O口线资源较多,因而在显示位数较多的情况下,我们大都都采用数码管动态显示方式进行显示。而对于动态显示方式,虽可以避免静态显示的问题,但设计上如果处理不当,易造成亮度低,有闪烁等问题。 方案二:采用LCD显示。
LCD液晶显示具有丰富多样性、灵活性、电路简单、易于控制而且功耗小等优点,对于一般的段式液晶屏,需要专门的驱动电路,而且也经显示作为一种被动显示,可视性相对较差;对于具有驱动电路和微处理器接口的液晶显示模块(字符或点阵),一般多采用并行机接口,对于微处理器的接口要求较高,占用资源多。另外,89C52本身没有专门的液晶驱动接口。
鉴于上述原因,我们采用方案一,采用了数码管显示方式。数码管作为一种主动显示器件,具有亮度高、价格便宜、功耗低、驱动简单等优点。
三、硬件部分
1. STC89C52单片机
(1)结构
STC89C52RC是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有 8K字节系统可编程Flash存储器。STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
同时具有以下标准功能: 8k字节Flash,512字节RAM, 32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,3个16 位定时器/计数器,4个外部中断,一个7向量4级中断结构(兼容传统51的5向量2级中断结构),全双工串行口。另外 STC89C52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35MHz,6T/12T可选。
(2)主要特性
8K字节程序存储空间;
512字节数据存储空间;
内带4K字节EEPROM存储空间;
可直接使用串口下载;
(3)器件参数
1. 增强型8051单片机,6 时钟/机器周期和12 时钟/机器周期可以任意 选择,指令代码完全兼容传统8051.
2. 工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V 单片机)
3.工作频率范围:0~40MHz,相当于普通8051 的0~80MHz,实际工作 频率可达48MHz
4. 用户应用程序空间为8K字节
5. 片上集成512 字节RAM
6. 通用I/O 口(32 个),复位后为:P1/P2/P3 是准双向口/弱上拉, P0 口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为 I/O 口用时,需加上拉电阻。
7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无 需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程 序,数秒即可完成一片
8. 具有EEPROM 功能
9. 共3 个16 位定时器/计数器。即定时器T0、T1、T2
10.外部中断4 路,下降沿中断或低电平触发电路,Power Down 模式可 由外部中断低电平触发中断方式唤醒
11. 通用异步串行口(UART),还可用定时器软件实现多个UART
12. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)
13. PDIP封装
STC89C52单片机的引脚如图所示:
2.时钟电路
STC89C52内部有一个用于构成振荡器的高增益反相放大器,引脚RXD和TXD分别是此放大器的输入端和输出端。时钟可以由内部方式产生或外部方式产生。内部方式的时钟电路如图(a) 所示,在RXD和TXD引脚上外接定时元件,内部振荡器就产生自激振荡。定时元件通常采用石英晶体和电容组成的并联谐振回路。晶体振荡频率可以在1.2~12MHz之间选择,电容值在5~30pF之间选择,电容值的大小可对频率起微调的作用。外部方式的时钟电路如图(b)所示,RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。如图所示,RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。 RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把
2.时钟电路
STC89C52内部有一个用于构成振荡器的高增益反相放大器,引脚RXD和TXD分别是此放大器的输入端和输出端。时钟可以由内部方式产生或外部方式产生。内部方式的时钟电路如图(a) 所示,在RXD和TXD引脚上外接定时元件,内部振荡器就产生自激振荡。定时元件通常采用石英晶体和电容组成的并联谐振回路。晶体振荡频率可以在1.2~12MHz之间选择,电容值在5~30pF之间选择,电容值的大小可对频率起微调的作用。外部方式的时钟电路如图(b)所示,RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。如图所示,RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。 RXD接地,TXD接外部振荡器。对外部振荡信号无特殊要求,只要求保证脉冲宽度,一般采用频率低于12MHz的方波信号。片内时钟发生器把
振荡频率两分频,产生一个两相时钟P1和P2,供单片机使用。
内部时钟电路如图所示,在XTAL1和XTAL1引脚上外接定时元件,内部振荡电路就产生自激振荡。定时元件是石英晶体和电容组成的并联谐振回路,晶体振荡器选择11.0532MHz,电容采用30PF。
3. 按键输入电路
独立式按键采用每个按键单独占有一个I/O口的结构,这是最简单的键盘输入设计。当按下和释放按键时,输入到I/O口端的电平是不一样的,单片机程序根据不同端口的电平变化判断是否有键按下以及是哪一个键被按下。独立式键盘的原理简单,每个按键的电路是独立的,占用一条数据线。
LED数码管电路
LED显示器工作方式有两种:静态显示方式和动态显示方式。静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优点是占用CPU时间少,显示便于监测和控制。缺点是硬件电路比较复杂,成本较高。动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。 一个八段数码管称为一位,多个数码管并列在一起可构成多位数码管,它们的段选线连在一起,而各自的公共端称为位选线。显示时,都从段选线送入字符编码,而选中哪个位选线,那个数码管便会被点亮。
四、软件设计
#include
unsigned char code
dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40}; //显示0~f,最后一位为无显示
Unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数码管位置
unsigned char dispbuf[8]={0,0,16,0,0,16,2,1};
unsigned char dispbitcnt;
unsigned char second;
unsigned char minite;
unsigned char hour;
unsigned int tcnt;
unsigned char mstcnt;
unsigned char i,j;
void main(void)
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(P0_0==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_0==0)
{
second++;
if(second==60)
{
second=0;
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
while(P0_0==0);
}
}
if(P0_1==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--); if(P0_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
dispbuf[3]=minite%10; dispbuf[4]=minite/10; while(P0_1==0); }
}
if(P0_2==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--); if(P0_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
dispbuf[6]=hour%10; dispbuf[7]=hour/10; while(P0_2==0); }
}
}
}
void t0(void) interrupt 1 using 0 {
mstcnt++;
if(mstcnt==8)
{
mstcnt=0;
P3=0xff; //关闭所有显示
P1=dispcode[dispbuf[dispbitcnt]]; P3=dispbitcode[dispbitcnt]; dispbitcnt++;
if(dispbitcnt==8) {
dispbitcnt=0; }
}
tcnt++;
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==60) {
second=0; minite++;
if(minite==60) {
minite=0; hour++;
if(hour==24) {
hour=0; } }
}
dispbuf[0]=second%10; dispbuf[1]=second/10; dispbuf[2]=17;
dispbuf[3]=minite%10; dispbuf[4]=minite/10; dispbuf[5]=17;
dispbuf[6]=hour%10; dispbuf[7]=hour/10; }
}
五、调试及运行结果