倒计时秒表

发布时间:2018-01-09 09:53:52   来源:文档文库   
字号:

单片机课程设计

课题:倒计时秒表

别:电气与控制工程学院

业:

名:

号:

绩:

河南城建学院

2018 01 3



目录

, 设计目的 2

二,设计任务及要求 2

三,方案设计 2

四,硬件设计 3

五,软件设计 6

六,仿真及调试 6

七, 设计总结 8

参考文献 9

附录: 9



, 设计目的

通过课程设计,使自己深刻理解并掌握基本概念,掌握单片机的基本应用程序设计及综合应用程序设计的方法。通过做倒计时秒表这个题目,达到对所学知识的消化、理解并提高解决问题的能力的目的。

任选一款51单片机来做这个倒计时秒表,显示方式可以自选,成品必须可以实现正常秒表的所有功能,包括启动、暂停、复位等,可以自由设定倒计时时间,并进行倒计时。做好之后可以扩展功能,在秒表的基础上增加时钟功能,倒计时完成时加入报警单元,如声音、灯光等。

二,设计任务及要求

1、可以以实现正常秒表的所有功能,包括启动、暂停、复位等;

2、可以自由设定倒计时时间(10s20s30s···),并进行倒计时;

3、显示方式自选;

4、任选一款51单片机;

5、扩展功能:在秒表的基础上增加时钟功能,倒计时完成时加入报警单元,如声音、灯光等。

三,方案设计

倒计时数字秒表的设计主要考虑以下几个问题:一,LED如何显示数字09;二,如何用单片机来控制LED的显示;三,单片机最小模式下的设计。处理好这些问题此设计才能完整,为此必须先了解LED的显示原理和接线方 1系统结构框图

法,再了解单片

机的组成原理和控制方法。硬件电路的绘制和软件程序的编写是此次设计的关键和基础,只有硬件电路的设计是正确的、合理的,软件设计才可以根据硬件电路编程,以下的设计才能够进行。系统结构框图如图1

四,硬件设计

1)CPU部分如图2所示 

XTAL1XTAL2跟时钟振荡模块链接

P0.0-P0.7与排阻相连,做上拉电阻

P1.2口是“设置模式”num 10,num20,num30,num50,num100 

P1.1口是“开始”倒计时端口 

 P1.0口是“暂停”口

P2.3口是给轰鸣器送触发信号口

2 CPU引脚接图

2)时钟振荡模块 

时钟振荡电路用于产生单片机正常工作时所需要的时钟信号,电路由两个20pF的瓷片电容和一个12MHz的晶振组成,并接入到单片机的XTAL1XTAL2引脚处,使单片机工作于内部振荡模式。此电路在加电后延迟大约10ms振荡器起振,在XTAL2引脚产生正弦波时钟信号,其振荡频率主要由石英晶振的频率决定。电路中两个电容C1C2的作用使电路快速起振,提高电路的运行速度。时钟振荡电路图如图3所示。

3时钟振荡电路图

3)数码管显示部分

数码管是一种显示屏,可以通过对其不同的管脚输入相对的电流 并使其发亮,发光从而显示出数字能够显示出时间、日期、温度 等所有可用数字表示的参数。由于它的价格便宜,使用简单,在电器,特别是家电领域应用极为广泛。在空调,热水器,冰箱,等等绝大多数,热水器用的都是数码管,其他家电 也用液晶屏与,荧光屏等等。在做倒计时秒表的时候选用的是SMG_2型号的数码管。ADP依次接单片机的的P0.0——P0.7口,如图4所示。

4数码管显示电路图

4)蜂鸣器部分如图5所示。

蜂鸣器部分选用的电阻的大小是1K,三极管的型号是90329012是现在常用的PNP三极管,放大倍数β一般在160~210之间。PNP型三极管,由2P型半导体中间夹着1N型半导体所组成的三极管,称为PNP型三极管。晶体三极管按材料分有两种:锗管和硅管。而每一种又有NPNPNP两种结构形式,但使用最多的是硅NPNPNP两种三极管,两者除了电源极性不同外,其工作原理都是相同的。

5蜂鸣器报警电路图

5)硬件总体电路图如图6所示。

单片机的P0.0-P0.7与排阻连接,P1.0口连接暂停键,P1.1口连接开始键,P1.2连接设置按钮,P2.3连接蜂鸣器报警模块。XTAL1XTZL2与时钟振荡模块连接。时钟振荡模块电路连接两个20PF的电容和一个12MHz的晶振,电路中两个电容C1C2的作用使电路快速起振,提高电路的运行速度。数码管ADP依次接单片机的的P0.0——P0.7口。

6硬件总体电路图

五,软件设计

软件流程图,如图7所示。

1)本电路应用TIMER0 MODE 16位计数器的计时中断法。

21秒等于1000000微秒,而每一计时脉冲是1微秒,因此需输入100000个计时脉冲,方可达到1秒的时间。本设计中,设定中断每次溢出时间50ms

3)由上式得知,循环20次即可达到1秒定时,即:

N=t/Tcy=0.05s/0.000001=5000

X=65536-5000=15536=3CB0H

4)由上式得知5000个脉冲,首先需设定TL0=3CH,TH0=0B0H,此时第1次只要输入5000个脉冲输入,就会溢出;第2次至第20次,则需每1000000个计时脉冲,定时1秒。

5)上电时,显示60,开始倒数计时按下开关实现复位。

7软件流程图

六,仿真及调试

Proteus中的仿真如图8所示。

单片机的P0.0-P0.7与排阻连接,P1.0口连接暂停键,P1.1口连接开始键,P1.2连接设置按钮,P2.3连接蜂鸣器报警模块。XTAL1XTZL2与时钟振荡模块连接。时钟振荡模块电路连接两个20PF的电容和一个12MHz的晶振,电路中两个电容C1C2的作用使电路快速起振,提高电路的运行速度。数码管ADP依次接单片机的的P0.0——P0.7口。

8仿真图

实物效果图如图9所示。

焊接的时候,整个过程还是比较顺利的,但是在焊接电源按钮开关时出现了一些问题。电源开必须一直按着整个电路才能通电,按一下松开电路不会通电,经过几次试验仍然没有找到原因,只能把电源开关拆了重新焊接,仔细检查焊接的过程发现是开关的引脚没有穿过洞洞板,焊接的时候开关引脚没有与洞洞板相连,解决了这个问题之后整个电路才正常工作。。电路的正常工作电压是5V,正常工作时通过的电流是2A

9实物效果图

7,设计总结

通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。

焊接的时候,整个过程还是比较顺利的,但是在焊接电源按钮开关时出现了一些问题。电源开必须一直按着整个电路才能通电,按一下松开电路不会通电,经过几次试验仍然没有找到原因,只能把电源开关拆了重新焊接,仔细检查焊接的过程发现是开关的引脚没有穿过洞洞板,焊接的时候开关引脚没有与洞洞板相连,解决了这个问题之后整个电路才正常工作。电路的正常工作电压是5V,正常工作时通过的电流是2A

这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说不懂一些元器件的使用方法,对单片机汇编语言掌握得不好……通过这次课程设计之后,一定把以前所学过的知识重新温故。

参考文献

[1] 张毅刚,俞洋,刘丹,邓立宝。单片机原理与应用设计,电子工业出版社2015.6

[2] 赵建领,薛圆圆。51单片机开发与应用,电子工业出版社,2009.1

[3]张迎辉 贡雪梅。单片机实训教程,北京大学出版社,2008.6

附录:

#include

#define uchar unsigned char

#define uint unsigned int //无符号整型 宏定义 变量范围0~65535

#include

uchar code smg_du[]={0x90,0xf5,0x1c,0x34,0x71,0x32,0x12,0xf4,0x10,0x30,

0xff}; //断码//数码管位选定义

sbit we2 = P2^5;

sbit we1 = P2^7;

uchar dis_smg[8] = {0x90,0xf5,0x1c,0x34,0x71,0x32,0x12,0xf4};

bit flag_500ms;

sbit beep = P2^3;

uchar a_a;

uchar menu_1; //设置参数用

uchar num; // 倒计时数

uchar num_value; // 用做中间的变量

bit flag_num_en ; // 倒计时器开始计时使能标志位

uchar set_num = 30; // 设置倒计时数的启始值

/***********************1ms延时函数*****************************/

void delay_1ms(uint q)

{

uint i,j;

for(i=0;i

for(j=0;j<120;j++);

}

/**************数码管位选函数*****************/

void smg_we_witch(uchar dat)

{

switch(dat)

{

case 1 : we1 = 0; we2 = 1; break; //打开个位

case 0 : we1 = 1; we2 = 0; break; //打开十位

}

}

/*************定时器0初始化程序***************/

void time_init()

{

EA = 1; //开总中断

TMOD = 0X01; //定时器0、工作方式1

ET0 = 1; //开定时器0中断

TR0 = 1; //允许定时器0定时

}

/***********************数码显示函数*****************************/

void display()

{

uchar i;

for(i=0;i<2;i++)

{

P0 = 0xff; //消隐

smg_we_witch(i); //位选

P0 = dis_smg[i]; //段选

delay_1ms(1);

}

}

/********************独立按键程序*****************/

uchar key_can; //按键值

void key() //独立按键程序

{

static uchar key_new;

key_can = 20; //按键值还原

P1 |= 0x07;

if((P1 & 0x07) != 0x07) //按键按下

{

delay_1ms(1); //按键消抖动

if(((P1 & 0x07) != 0x07) && (key_new == 1))

{ //确认是按键按下

key_new = 0;

switch(P1 & 0x07)

{

case 0x0e: key_can = 3; break; //得到k1键值

case 0x0d: key_can = 2; break; //得到k2键值

case 0x0b: key_can = 1; break; //得到k3键值

}

}

}

else

key_new = 1;

}

/****************按键处理数码管显示函数***************/

void key_with()

{

if(key_can == 1)

{

menu_1 ++;

if(menu_1 >= 2)

{

menu_1 = 0;

}

}

if(menu_1 == 0) //倒计时器按键操作开始 暂停

{

if(key_can == 2) //开始键

{

flag_num_en = 1;

beep = 0; //打开蜂鸣器

delay_1ms(30);

beep = 1; //关闭蜂鸣器

}

if(key_can == 3) //暂停键

{

flag_num_en = 0;

beep = 0; //打开蜂鸣器

delay_1ms(30);

beep = 1; //关闭蜂鸣器

}

}

if(menu_1 == 1) //设置倒计时器开始数

{

if(key_can == 2)

{

set_num ++ ; // 设置数加

if(set_num > 99)

set_num = 99; //最大加到99

dis_smg[0] = smg_du[set_num % 10]; //取个数显示

dis_smg[1] = smg_du[set_num / 10 % 10] ; //取十位显示

}

if(key_can == 3)

{

set_num -- ; // 设置数减

if(set_num <= 1)

set_num = 1; //最大减到1

dis_smg[0] = smg_du[set_num % 10]; //取个数显示

dis_smg[1] = smg_du[set_num / 10 % 10] ; //取十位显示

}

num = set_num; //倒计时数等于设置数

}

}

/******************主程序**********************/

void main()

{

time_init();

num = set_num; //开机显示设置数

while(1)

{

key(); //按键扫描函数

if(key_can < 10)

{

key_with(); //按键执行函数

}

if(menu_1 == 0) //扫描显示倒计时数

{

dis_smg[0] = smg_du[num % 10];

dis_smg[1] = smg_du[num / 10];

if(flag_500ms == 1)

{

flag_500ms = 0;

if(num <= 3)

beep = ~beep;

}

}

if(menu_1 == 1) //在设置的时候十位数闪烁

{

if(flag_500ms == 1)

dis_smg[1] = 0xff;

else

{

dis_smg[0] = smg_du[set_num % 10]; //取个位显示

dis_smg[1] = smg_du[set_num / 10 % 10]; //取十位显示

}

}

display(); //数码管显示函数

}

}

/*************定时器0中断服务程序***************/

void time0_int() interrupt 1

{

static uchar value;

TH0 = 0x3c;

TL0 = 0xb0; // 50ms

value ++;

if(value >= 10)

{

value = 0;

flag_500ms = ~flag_500ms;

}

if(flag_num_en == 1)

{

num_value ++;

if(num_value >= 20) //1s

{

num --; //倒计数减一次

if(num == 0)

{

beep = 1; //关闭蜂鸣器

num = set_num; //让显示最大数

flag_num_en = 0;

}

}

}

}

本文来源:https://www.2haoxitong.net/k/doc/400dc9752bf90242a8956bec0975f46527d3a70d.html

《倒计时秒表.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式