比赛计分器电路设计
目录
前言
近几年来,随着科技的飞速发展,单片机领域正在不断的走向社会各个角落,还带动传统控制检测日新月异更新。
在实时运作和自动控制的单片机应用到系统中,单片机如今是作为一个核心部件来使用,仅掌握单片机方面知识是不够的,还应根据其具体硬件结构,以及针对具体应用对象特点的软件结合,加以完善。
提示:以下是本篇文章正文内容,下面案例仅供参考
一、设计方案
1.1 总设计框图
以AT89C51单片机为核心,起着控制作用。系统包括数码管显示电路、复位电路、时钟电路、按键调整电路和蜂鸣器电路。
设计思路分为六个模块:复位电路、晶振电路模、STC89C51RC、数码管显示电路、按键调整电路和蜂鸣器电路这六个模块。
1.2功能简述
比赛计分器,主要用于比赛记录分数。采用矩阵式键盘作为输入,用户可分别对两队比分进行加2操作,并通过数码管显示其每次按下加分键所加的分值。
同时可以进行上下半场比分的交换。比分通过1个四位一体数码管显示时间精确到秒,2个2位一体数码管显示两队的分数。
每次进行按键操作时,蜂鸣器响,比赛结束时,蜂鸣器响。
1.3硬件仿真图
1.4 主函数程序中断和定时器代码
void main() //定义主程序
{
EX0=1;//外部中断0的分开关打开
EX1=1;//外部中断1的分开关打开
IT0=1;//外部中断0为下降沿触发
IT1=1;//外部中断1为下降沿触发
PX1=1;//外部中断1为高优先级
PX0=0;//外部中断0为低优先级
TMOD=0x01; //初始化程序
EA=1; //开关总中断打开
ET0=1;
P3_7=0;
P0=0xff;
P2=0x00;
if(P1_0==0) //第一次按下P1_0,单片机启动,显示初始值
{ //由于调用了一次暂停功能,会显示初始值
TH0=0xb1;
TL0=0x10;
TR0=1; //启动定时器
P3=0xff;
P1=0x7f;
P3_7=0;
while(1)
{
timing(); //调时子程序
exchange(); //比分交换程序
suspend(); //暂停程序
alertor(); //报警程序
if((u_m==0)&&(u_n==1)) //判断子程序结束调用条件
{
h=1;
}
conclude(); //结束子程序
}
}
}
1.5程序函数组成
该系统由延时子函数、蜂鸣器子函数、初始化子函数、调节比赛时间数码管显示子函数、
比赛开始数码管显示子函数、甲队得分数码管显示子函数、乙队得分数码管显示子函数、按键扫描子函数、定时器0中断子函数、主函数和数据定义这几部分组成。
二、比赛计分器的电路设计
2.1单片机AT89C51芯片功能简述
单片机是在一块芯片内集成了CPU、RAM、ROM、定时器/计数器和多功能I/O口等计算机所需要的基本功能部件的大规模集成电路,又称为MCU。51系列单片机内包含以下几个部件:
一个8位CPU;一个片内振荡器及时钟电路;
4KB的ROM程序存储器;
一个128B的RAM数据存储器;
寻址64KB外部数据存储器和64KB外部程序存储空间的控制电路;
32条可编程的I/O口线;
两个16位定时/计数器;
一个可编程全双工串行口;
5个中断源、两个优先级嵌套中断结构。
VCC:供电电压。
P0口:P0口是一组8 位漏极开路型双向I/O口,也即地址/数据总线复用口。作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。
P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:P3口是一组带有内部上拉电阻的8位双向I/O口。P3口输出缓冲级可驱动4个TTL逻辑门电路。对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。做输入端时,被外部拉低的P3口将用上拉电阻输出电流。P3口除了作为一般的I/O口线外,还有重要的第二功能。
表2-1 P3组主要功能描述
端口引脚 | 第二功能 |
---|---|
P3.0 | RXD(串行输入口) |
P3.1 | TXD(串行输出口) |
P3.2 | INT0*(外中断0) |
P3.3 | INT1*(外中断1) |
P3.4 | T0(定时/计数器0外部输入) |
P3.5 | T1(定时/计数器1外部输入) |
P3.6 | WR*(外部数据存储器写选通) |
P3.7 | RD*(外部数据存储器读选通) |
RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。
2.2单片机AT89C51最小系统电路构建
2.3 中断系统
中断技术主要用于实时监测与控制,要求单片机能及时地响应中断请求源提出的服务请求,并快速响应与及时处理。
当中断请求源发出中断请求时,如中断请求被允许,单片机暂时中止当前正在执行的主程序,转到中断服务处理程序处理中断服务请求,
处理完中断服务请求后,再回到原来被中止的程序之处(断点),继续执行被中断的主程序。
中断系统有5个中断请求源(简称中断源),2个中断优先级,可实现2级中断服务程序嵌套。
每一中断源可用软件独立控制为允许中断或关闭中断状态;每一个中断源的优先级均可用软件设置。
由图2-4,中断系统共有5个中断请求源,它们是:
(1)INT0*—外部中断请求0,外部中断请求信号(低电平或负跳变有效)由INT0*引脚输入,中断请求标志为IE0。
(2)INT1*—外部中断请求1,外部中断请求信号(低电平或负跳变有效)由INT1*引脚输入,中断请求标志为IE1。
(3)定时器/计数器T0计数溢出的中断请求,标志为TF0。
(4)定时器/计数器T1计数溢出的中断请求,标志为TF1。5个中断请求源的中断请求标志分别由特殊功能寄存器TCON和SCON相应位锁存。
(5)串行口中断请求,标志为发送中断TI或接收中断RI。TF1—定时器/计数器T1的溢出中断请求标志位。
(6)当启动T1计数后,T1从初值开始加1计数,当最高位产生溢出时,硬件 置TF1为“1”,向CPU申请中断,响应TF1中断时,TF1标志硬件自动清“0”,TF1也可由软件清0
(7)TF0—定时器/计数器T0溢出中断请求标志位。
(8)IE1—外部中断请求1中断请求标志位。
(9)IE0—外部中断请求0中断请求标志位,
(10)IT1—选择外中断请求1为跳沿触发还是电平触发方式。
0--电平触发方式,加到INT0*脚上的外中断请求输入信号为低电平有效,并把IE1置“1”。转向中断服务程序时,则由硬件自动把IE1清“0”。
1--跳沿触发方式,加到INT1*脚上的外中断请求输入信号从高到低的负跳变有效,并把IE1置“1”。转向中断服务程序时,则由硬件自动把IE1清“0”。
(11)当AT89C51复位后,TCON被清“0”,5个中断源的中断请求标志均为0。
SCON标志位功能:
(1)TI—串口发送中断请求标志位。CPU将1字节的数据写入串口的发送缓冲器SBUF时,就启动一帧串行数据的发送,每发送完一帧串行数据后,硬件使TI自动置“1”。CPU响应串口发送中断时,并不清除TI中断请求标志,TI标志必须在中断服务程序中用指令对其清“0”。
(2)RI—串行口接收中断请求标志位。在串口接收完一个串行数据帧,硬件自动使RI中断请求标志置“1”。CPU在响应串口接收中断时,RI标志并不清“0”,须在中断服务程序中用指令对RI清“0”。
2.4 显示系统
倒计时数码管显示电路
数码管倒计时设计示例:
void timing() //定义调时程序
{
if(P1_2==0) //当按下P1_2时
{
delay(1); //延时消抖
if(P1_2==0)
{
u_n++; //秒位加1
if(u_n==60)//当秒位到60时
{
u_m++;//分位加1,秒变1
u_n=1;
}
}
}if(P1_3==0) //当按下P1_3时
{
delay(1);
if(P1_3==0)
{
u_n--;//秒位减1
if(u_n<0) //当秒位减到0时,分位减1,秒位变59
{ u_n=59;
u_m--;
}}}}
A队数码管计分显示电路
B对数码管计分显示电路
2.5按键调整电路
开始按键调整电路
中断加分按键调整电路
中断控制程序示例:
void t0() interrupt 1 //定义中断程序,调用定时器T0
{
TH0=0xb1; //对定时器T0送入初值,TH0=0xb1
TL0=0x10; //TL0=0X10定时器定时为20ms
if(u_n<0) //每20ms调用一次
{
u_n=59;
u_m--;
}
u_i++;
if(u_i==50) //定义I为50,50*20ms=1s
{
u_n--;
u_i=0;
}
display(u_m,u_n,u_x,u_y);//调用数码管显示程序,每20ms刷新
}
void int0() interrupt 0 //外部中断0的控制程序,每次按键按下,加2操作
{u_x+=2;if(u_x>98)u_x=98;}
void int1() interrupt 2 //外部中断1的控制程序,每次按键按下,加2操作
{u_y+=2;if(u_y>98)u_y=98;}
蜂鸣器电路
蜂鸣器设计代码示例:
void alertor() //定义报警程序
{
if(((u_m==0)&&(u_n==0))|(P3_2==0)|(P3_3==0)|(P1_0==0)|(P1_1==0)|(P1_2==0)|(P1_3==0))
{
P3_7=1;
P3_6=1;//P3_7和P3_6间隔输出高低电平,使蜂鸣器响
delay(5);
P3_7=0;
P3_6=0;
delay(5);
}
}
三、设计结果验证
仿真过程测试
仿真最终结果显示
总结
设计最大的亮点就是模块化设计,将执行功能的各个部分封装成一个个模块,即子函数。
在主函数中编写需要调用功能的子函数名即可执行相应的功能,目的是便于修改,减小了对程序大规模的修改,降低了程序编写过程中的出错率。
设计的仿真图考虑到实际应用的需求和视觉审美,尽最大程度的减少电路设计过程中线路的繁杂和无条理性,所以选择标号的方式,既能使电路处于连通的状态又能使电路整体整洁美观。
考虑到实际应用的需求,所以增加了倒计时数码管并充分利用P0组IO的功能,在添加上拉电阻的条件下,使IO充分得到利用。
因为实验是两个队进行分数计分,考虑到IO的性能和实验的最大优化,选择了2个两位一体共阳数码管,段码段公用,这样减少了IO的占用,而且充分利用了资源而且还能达到实验的效果。