点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87775018添加链接描述
源码获取
主要内容:
设计一个电子秒表,至少具有以下功能:开始/暂停、记录、复位等。设计方案主要分为实验的系统分析,具体的设计方案,以及最终的测试,最终完成实验设计。
基本要求:
1、具有电路设计图;
2、设计源程序;
3、keil运行源程序;
4、protus中仿真;
5、运行结果分析。
主要参考资料:
[1]刘守义等.单片机技术基础[M].西安电子科技大学出版社,2007.
[2]王东峰等.单片机C语言应用100例[M].电子工业出版社,2009.
[3]马忠梅等.单片机的C语言应用程序设计.北京航空航天大学出版社,2003.
[4]王晋凯.简简单单学通51单片机开发 [M].清华大学出版社,2014.
[5]夏继强.单片机实验[M].北京: 航空航天大学出版社,2001.
完 成 期 限:12 月 11 日 - 12 月 26 日
指导教师签名:
课程负责人签名:
摘 要
近年来随着科技的飞速发展,单片机的应用正在不断地走向深入,同时带动着传统控制检测日新月异的更新。在实时检测和自动控制的单片机应用系统中,单片机往往是作为一个核心部件来使用,仅单片机方面的知识是不够的,还要根据具体的硬件结构,以及针对具体的应用对象的软件结合,加以完善。秒表的出现,解决了传统的由于人为因素造成的误差和不公平性。
本次设计是采用AT89C52单片机为中心,利用其定时器/计数器定时和记数的原理,结合显示电路、电源电路、LCD1602液晶以及键盘电路来设计计时器。将软、硬件有机的结合起来,使得系统能够实现四位LCD显示,最大显示时间为09:59:99,有开始/暂停、复位、记录和查看功能,并设有每秒提醒功能。
关 键 词:电子秒表;仿真;单片机;
目 录
摘 要 I
1概述 1
1.1选题背景 1
1.2 单片机简单介绍 1
1.3 设计的作用及目的 1
2系统分析 2
2.1 系统方案 2
2.2 原理分析 2
2.2.1计数器中断过程分析 2
2.2.2计时器定时机器分析 3
3系统设计 4
3.1 总体设计 4
3.2 硬件设计 4
3.2.2按键电路 5
3.2.3蜂鸣器电路 5
3.2.4复位电路 6
3.2.5时钟电路 6
3.3 软件设计 7
3.3.1程序流程设计 7
3.3.2源程序 8
4 仿真测试 16
4.1 开始/暂停 16
4.3 查看下一条记录 16
4.4 查看上一条记录 16
4.4 复位 16
5 心得体会 17
参考文献 18
1概述
1.1选题背景
在当下这个信息科技迅猛发展的时代,各领域对于时间精确要求越来越高,比如在物理界,做实验需要精确的计时工具来测量时间参数;在体育界,比赛场上需要精确的计时工具来区分运动员速度之间的细微差距;在IT行业,时间的要求更是越来越高;最基本的在生活中,计时工具也是常被人使用。所以电子秒表实用域广,性价比高,实用性强,市场前景一片光明。
1.2 单片机简单介绍
单片机微型计算机简称单片机,是典型的嵌入式微控制器,常用英文字母MCU表示单片机,它最早是被用在工业控制领域。单片机由芯片内仅有CPU的专用处理器发展而来。最早的设计理念是通过将大量外围设备和CPU集成在一个芯片内,是计算机系统更小,更容易集成进复杂的而对提及要求严格的控制设备当中。INTEL的Z80是最早按照这种设计思想设计出的处理器,之后,单片机和专用处理器被分开。早期的单片机是8位或4位的,其中最成功的是8031,因为简单可靠性能好而获好评。之后在8031基础上发展了MCS51系列单片机系统。但性价比不理想而未被广泛应用。90年代随着电子产品飞速发展,单片机技术大大提高,处理能力也提高了数倍。现代生活的几乎所有电子和机械产品都集成有单片机。手机,电话,计算机,家庭电器,医疗仪器,电子玩具,掌上电脑等等都会配有单片机。汽车上一般要配有50多部单片机,复杂的工业控制系统上甚至可能有数百台单片机子同时工作!
因此,本次大作业设计以单片机为核心,设计简单的电子秒表,使它能够正确的运行,并且可以用数码管显示,在现实中生活中应用广泛,也有实现意义。
1.3 设计的作用及目的
本设计利用单片机原理,结合显示电路,用四位数码显示管及按键来实现0电子秒表。将软硬件合理结合,以实现系统正常运行,数码管正常显示的最终目的。本次课设是对电子秒表设计的基本功能,软件模块硬件模块的设计思路及如何实现功能的主要概述。本次课程设计加深了对单片机课程的全面认识和对单片机课程的应用。培养了自己运用所学基础理论解决实际问题的能力。 学习到设计课设写作方法和用文与图相结合直观,详细,具体地阐述设计成果。对数字电子秒表的设计、检测、制作有了有更进一步的理解与操作,学会了把所学知识知识理论与动手实践相结合。
2系统分析
2.1 系统方案
本系统采用AT89C52单片机为中心器件,利用其定时器/计数器定时和记数的原理,结合硬件电路来设计计时器、将软硬件有机地结合起来。其中软件系统采用c语言编写程序,硬件系统利用PROTEUS强大的功能来实现,简单且易于观察,在仿真中就可以观察到实际的工作状态。
2.2 原理分析
2.2.1计数器中断过程分析
中断是指cpu在执行某一过程中由于外界原因必须暂停现在的事情,处理别的事情,处理完了再回去执行暂停的事情。中断的优点,分时操作,实时响应 ,可靠性高。IE寄存器:
1.单路开关:EX0 ET0 EX1 ET1 ES
EX0:外部中断0允许位
ET0:定时/计数器T0中断允许位
EX1:外部中断1允许位
ET1:定时/计数器T1中断允许位
ES:串行口中断允许位
2.总开关
EA:CPU中断允许位
EA=1打开
IP寄存器:
作用是选择优先级的,解决中断优先级问题。
IT0寄存器:选择低电平有效还是下降沿有效,上电默认电平触发方式,IT0=1是下降沿有效
T0 T1为定时器中断,RX TX为串行口中断
中断优先级顺序由高到低:
外部中断0(IE0)->定时/计数器0(TF0)->外部中断1(IE1)->定时/计数器1(TF1)->串行口(R1或T1)
首先响应的是优先级高的中断请求,正在中断的不会被新的中断请求打断,正在进行低优先级中断服务,能被高优先级中断请求中断。
中断函数一般形式:void 函数名() interrupt n{}
n代表中断号,中断号是编译器识别不同中断的唯一编号
中断函数和普通函数的异同:
同:函数的形式非常类似,中断响应过程和普通函数调用过程也非常相似
异:中断函数不需要声明,普通函数需要声明
使用中断函数需要遵循以下规则:
(1)中断函数不能进行参数传递
(2)在任何情况下,都不能直接调用中断函数
2.2.2计时器定时机器分析
加1计数器输入的计数脉冲有两个来源,一个是由系统的时钟震溃器输出脉冲经12分频后送来;一个是T0或T1引脚输入的外部脉冲源。
作为定时器使用时,定时器计数8051单片机片内振荡器输出经过12分频后的脉冲个数,即:每个机器周期使定时器T0/T1的寄存器值自动累加1,直到溢出,溢出后继续从0开始循环计数;所以,定时器的分辨率是时钟振荡频率的1/12;
作为计数器使用时,通过引脚T0(P3.4)或T1(P3.5)对外部脉冲信号进行计数,当输入的外部脉冲信号发生从1到0的负跳变时,计数器的值就自动加1由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个机器周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2微秒;计数器的最高频率一般是时钟振荡频率的1/24;
由此可知,不论是定时器还是计数器工作方式,定时器T0和T1均不占用cpu的时间,除非定时器/计数器T0和T1溢出,才可能引起CPU中断,转而去执行中断处理程序。所以说,定时器/计数器是单片机中效率高而工作灵活的部件。
本实验使用工作模式0:
由TL0的低5位和TH0的全部8位共同构成一个13位的定时器/计数器,定时器/计数器启动后,定时或计数脉冲个数加到TL0上,从预先设置的初值(时间常数)开始累加,不断递增1,当 TL0计满后,向TH0进位,直到13位寄存器计满溢出,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求。并且定时器/计数器硬件会自动地把13位的寄存器值清0,如果需要进一步定时/计数,需要使用相关指令重置时间常数,并把定时器/计数器的中断标记TF0置0。
3系统设计
3.1 总体设计
此次的设计是采用定时器进行计时并且在LCD1602上显示时间,使用P2.0、P2.1、P2.2控制LCD的RE、RW、EN端口。P1.0控制蜂鸣器、P1.1控制开始/暂停、P1.2、P1.3控制查看上一条、下一条、P1.4控制记录、P1.5控制复位、P1.6控制每秒提醒。当按下开始的时候,秒表开始计数,当按下暂停的时候暂停计数,当按下记录的时候,可以记录当前计数时间,按下上一条记录的时候显示屏上可以显示上一次记录的时间。并且每秒都有提醒。确定用P0并行端口进行LCD1602控制输入,使用P2.0、P2.1、P2.2控制LCD的RE、RW、EN端口。P1.0控制蜂鸣器、P1.1控制开始/暂停、P1.2、P1.3控制查看上一条、下一条、P1.4控制记录、P1.5控制复位、P1.6控制每秒提醒。如下图3-1所示。
图3-1 总电路图
3.2 硬件设计
3.2.1LCD1602显示电路
所谓的1602是指显示的时候,有两行内容每行有16个字符。如下图3-2所示。
基本操作时有:
1.读状态:输入:RS=L,RW=H,E=H
–输出:D0-D7=状态字
2.写指令:输入:RS=L,RW=L,D0-D7=指令码
–输出:无
3.读数据:输入:RS=H,RW=H,E=H
–输入:D0-D7=数据
4.写数据:输入:RS=H,RW=L,D0-D7=数据,E=高脉冲
–输入:无
图3-2 显示电路图
3.2.2按键电路
需要实现秒表的开始/暂停、记录、查看上一条、查看下一条、复位、每秒提醒的开关。用6个按键实现。P1.1控制开始/暂停、P1.2、P1.3控制查看上一条、下一条、P1.4控制记录、P1.5控制复位、P1.6控制每秒提醒。如下图3-3所示。
图3-3 按键电路图
3.2.3蜂鸣器电路
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。由于题目内容有计时时间每秒都得有提醒功能,因此我们还得用蜂鸣器。如图3-4所示:
图3-4 蜂鸣器电路图
3.2.4复位电路
采用上电加按键复位电路,也就是手动复位,上电后,由于电容充电,使这RET持续一段高电平时间,当单片机运行时,按下复位键也能使RET持续一段时间的高电平,从而实现上电加开关复位的操作上电加复位电路。如下图3-5所示。
图3-5 复位电路图
3.2.5时钟电路
利用12分频的晶振的一个机器周期为一微妙,通过循环延时产生0.1秒的延时,通过XTAL1和XTAL2外接晶体振荡器构成内部振荡方式。由于单片机内部有一个高增益反相放大器,当外接晶振后,就构成了自激振荡器并产生振荡时钟脉冲。51单片机内部的振荡电路是一个高增益反相放大器,引线XTAL1和XTAL2引脚分别为振荡器的反相放大器输入端,振荡器的反相放大输出端,再接上晶振形成一个完整电路,产生震荡。如图3-6所示。
图3-6 时钟电路图
3.3 软件设计
3.3.1程序流程设计
图3-7 系统流程图
3.3.2源程序
#include<reg52.h>
#include<intrins.h>
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0
//按键定义
sbit key1=P1^3;
sbit key2=P1^2;
sbit key3=P1^1;
sbit key4=P1^4;
sbit key5=P1^5;
sbit key6=P1^6;
//蜂鸣器定义
sbit Beep=P1^0;
//全局变量定义
unsigned int RecordTableH[11];
unsigned char RecordTableL[11];
unsigned int CountTimeH;
unsigned char CountTimeL;
unsigned char DataRecordFlag = 0;
unsigned char DataFlag = 0;
unsigned int buzzer=0;
code unsigned char NumTable[]="0123456789";
bit Counting = 0;
//函数声明
void LCD1602_WriteCom(unsigned char com);
void LCD1602_WriteData(unsigned char Data);
void LCD1602_Clear(void);
void LCD1602_PutString(unsigned char x,unsigned char y,unsigned char *s);
void LCD1602_PutChar(unsigned char x,unsigned char y,unsigned char Data);
void LCD1602_Init(void);
void LCD1602_Delay(unsigned int t);
void delay_ms(unsigned int t);
void IniTC0(void) ;
void KeyWork(void);
void DisplayCountTime(void);
void main()
{
IniTC0();
LCD1602_Init();
Beep = 1;
LCD1602_PutString(4,0,"Well Come");
LCD1602_PutString(2,1," Stopwatch ");
delay_ms(1000);
LCD1602_Clear();
while(1)
{
DisplayCountTime();
KeyWork();
}
}
void LCD1602_WriteCom(unsigned char com)
{
LCD1602_Delay(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
_nop_();
EN_CLR;
}
void LCD1602_WriteData(unsigned char Data)
{
LCD1602_Delay(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
void LCD1602_Clear(void)
{
LCD1602_WriteCom(0x01);
LCD1602_Delay(5);
}
void LCD1602_PutString(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD1602_WriteCom(0x80 + x);
}
else
{
LCD1602_WriteCom(0xC0 + x);
}
while (*s)
{
LCD1602_WriteData( *s);
s ++;
}
}
void LCD1602_PutChar(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD1602_WriteCom(0x80 + x);
}else {
LCD1602_WriteCom(0xC0 + x);
}
LCD1602_WriteData( Data);
}
void LCD1602_Init(void)
{
LCD1602_WriteCom(0x38);
LCD1602_Delay(5);
LCD1602_WriteCom(0x38);
LCD1602_Delay(5);
LCD1602_WriteCom(0x38);
LCD1602_Delay(5);
LCD1602_WriteCom(0x38);
LCD1602_WriteCom(0x08);
LCD1602_WriteCom(0x01);
LCD1602_WriteCom(0x06);
LCD1602_Delay(5);
LCD1602_WriteCom(0x0C);
LCD1602_Clear();
}
void LCD1602_Delay(unsigned int t)
{
unsigned char c;
while(t--)
{
for(c = 50; c > 0; c--);
}
}
void delay_ms(unsigned int t)
{
unsigned char c;
while(t--)
{
for(c = 50; c > 0; c--);
}
}
void IniTC0(void)
{
TMOD=0x01;
TR0 = 0;
TF0 = 0;
TH0=0xFC;
TL0=0x18;
ET0 = 1;
EA=1;
}
void KeyWork(void)
{
if(key1 == 0)
{
if(!Counting && DataRecordFlag != 0)(DataRecordFlag表示记录的数据条数)
{
DataFlag++;
if(DataFlag >= DataRecordFlag)
{
DataFlag = DataRecordFlag;
}
if(DataFlag >= 10)
{
LCD1602_PutString(0,1,"10: ");
}else {
LCD1602_PutChar(0, 1, NumTable[DataFlag]);
LCD1602_PutString(1,1,": ");
}
LCD1602_PutChar(4, 1, NumTable[(RecordTableH[DataFlag]/6000)%6]);
LCD1602_PutChar(5, 1, NumTable[(RecordTableH[DataFlag]/600)%10]);
LCD1602_PutChar(6, 1, ':');
LCD1602_PutChar(7, 1, NumTable[(RecordTableH[DataFlag]/100)%6]);
LCD1602_PutChar(8, 1, NumTable[(RecordTableH[DataFlag]/10)%10]);
LCD1602_PutChar(9, 1, ':');
LCD1602_PutChar(10, 1, NumTable[((RecordTableL[DataFlag]%10)%10)%10]);
LCD1602_PutChar(11, 1, NumTable[RecordTableL[DataFlag]/10]);
}
delay_ms(5);
while(!key1)
DisplayCountTime();
}
if(key2 == 0)
{
if(!Counting && DataRecordFlag != 0)
(DataRecordFlag表示记录的数据条数)
{
DataFlag--;
if(DataFlag == 0)
{
DataFlag = 1;
}
LCD1602_PutChar(0, 1, NumTable[DataFlag]);
LCD1602_PutString(1,1,": ");
LCD1602_PutChar(4, 1, NumTable[(RecordTableH[DataFlag]/6000)%6]);
LCD1602_PutChar(5, 1, NumTable[(RecordTableH[DataFlag]/600)%10]);
LCD1602_PutChar(6, 1, ':');
LCD1602_PutChar(7, 1, NumTable[(RecordTableH[DataFlag]/100)%6]);
LCD1602_PutChar(8, 1, NumTable[(RecordTableH[DataFlag]/10)%10]);
LCD1602_PutChar(9, 1, ':');
LCD1602_PutChar(10, 1, NumTable[((RecordTableL[DataFlag]%10)%10)%10]);
LCD1602_PutChar(11, 1, NumTable[RecordTableL[DataFlag]/10]);
}
delay_ms(5);
while(!key2)
DisplayCountTime(); }
if(key3 == 0)
{
Counting = !Counting;
if(Counting)
{
TR0 = 1;
}else {
TR0 = 0;
}
delay_ms(5);
while(!key3)
DisplayCountTime();
}
4 仿真测试
4.1 开始/暂停
图4-1开始/暂停图
4.2 记录
图4-2记录时间图
4.3 查看下一条记录
图4-3查看下一条记录图
4.4 查看上一条记录
图4-4查看上一条记录图
4.4 复位
文章来源:https://www.toymoban.com/news/detail-571804.html
图4-5复位图
5 心得体会
经过我的不懈努力终于完成了对电子秒表的设计,收获颇多。也明白了自己在单片机学习上存在的一些问题,并且在用C语言编程方面也有缺点与不足。经过课程设计使我明白做一个完整的系统要用到我们学到的很多方面的知识,一个完整的系统包含的C语言知识很多,要有好强的综合运用能力才能开发一个完整的系统。在程序操作过程中要有耐心,更要细心。同时,也体会到学本专业要有好强的动手能力,而实训操作完成小系统锻炼了我的动手能力,今后,在动手操作方面要加强,毕竟熟能生巧,练多了才能提高自己的编写程序的能力。毕竟,对于本专业的初学者来说,起初的编程还属于经验编程,靠自己的学习及动手操作获得经验,以便为今后开发出新的程序打下基础。
这次的课程设计也是一次很好的对自我的检查。它让我知道了自己对单片机的学习还不够认真刻苦,很多知识点还是没有很好的掌握,甚至有些知识点很生疏,这也许就是我在编写代码时老碰壁的原因所在! 从这一点上来看,发现我对待学习的态度还不够端正,有待加强。
不管怎么说,经过这一次课程设计,在Java语言方面的收获最大,让我读代码的能力大大提升了不少,也巩固了很多知识。同时也受到了老师的细心指导,非常感
参考文献
[1] 何立民.单片机高级教程[M].北京: 航空航天大学出版社,2001.
[2] 王东峰等.单片机C语言应用100例[M].电子工业出版社,2009.
[3] 马忠梅等.单片机的C语言应用程序设计.北京航空航天大学出版社,2003.
[4] 王晋凯.简简单单学通51单片机开发 [M].清华大学出版社,2014.
[5] 夏继强.单片机实验[M].北京: 航空航天大学出版社,2001.文章来源地址https://www.toymoban.com/news/detail-571804.html
到了这里,关于基于AT89C51单片机的电子秒表设计与仿真的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!