物理动态电路论文

篮球比赛的30秒规则规定,进攻方在场上控球时必须在30秒内出手(NBA比赛24秒,NCAA比赛35秒),所以裁判在比赛过程中既要看球,又要看秒表,本文介绍的30秒倒计时器可以解决这个问题。

AT89C51单片机,30秒倒计时器,发光二极管

有很多方法可以设计和制作30秒倒计时器。本文介绍的30秒倒计时定时器以AT89C51为控制单元,用两个数码管显示时间,用三个按钮分别控制定时器的计时开始、复位和暂停。倒计时器的初始状态显示“30”。当裁判按下计时器键,30秒后开始倒计时。当计时时间减少到0时,计时器会发出声光警报,提醒裁判计时时间到了。

第一,电路设计

30秒倒计时器的电路主要由电源电路、单片机最小系统、按键输入、显示驱动电路和报警电路组成。30秒倒计时定时器的控制电路如图1所示。

图1 30秒倒计时定时器电路原理图

1,按键输入

“30秒倒计时器”使用三个按钮完成开始计数、复位、暂停/继续计数等功能。

(1)K1键:开始按钮(P3.2)。

按下K1键,计数器开始倒计时,数码管显示的数字从30开始每秒倒计时。当达到零时,报警电路会发出声光报警信号。当计数器处于暂停状态时,按下K1键将返回计时状态。

(2)K2键:复位按钮(P3.3)。

按K2键,无论计数器工作在什么状态,计数器都会立即复位到预设值“30”,在报警状态下按K2键取消报警。

(3)K3键:暂停/定时开关按钮(P3.4)。

当计数器处于计时状态时,按此键暂停计时器,数码管显示的数字不变;当计数器处于暂停状态时,按下该键,计数器将回到计时状态;密钥在初始状态下无效。

2.显示驱动电路

“30秒倒计时器”采用两个* * *数码管显示时间,数码管的显示方式为动态显示。在显示驱动电路中,数码管的段管脚通过一个470欧姆的电阻连接到单片机的P1端口,两个片选管脚通过一个9012连接到正5V电源,由P3.0和P3.1控制。

4.告警电路

当计时时间减少到0时,当显示数码管显示“00”时,LED D1由P3.5控制发出光报警,蜂鸣器由P3.7控制发出声报警。

二、软件编程思路

1,全局变量

“30秒倒计时器”的动作流程主要由三个全局变量控制。一是位变量“act”,当“act”为“1”时,倒计时开始,为“0”时停止,“act”的初始值为“0”,可以设置为“1”,也可以通过按钮操作清零。第二个全局变量是char变量“time ”,它存储倒计时时间。当倒计时时间为0时,将发出声光报警。变量“时间”的初始值是30。当“act”为1时,定时器中断服务程序会每隔1减去1,减为0时保持为0。按下“重置键”将“时间”重置为30。第三个全局变量是int变量“t”,它记录响应计时被0中断的次数。根据初始化定义,定时器0工作在1模式,每1 ms发出一个中断请求..控制程序只打开定时器0中断,所以不会有比定时器0中断更高级的中断,所以每一个请求都会被立即应答。响应后,在中断服务程序中的全局变量“T”上加1,记录响应中断次数。1000次的每一次响应都是1秒。变量“t”的初始值为0,中断服务程序加上1。当“t”为2000时,它被中断服务程序清除。在键驱动器中,当按下开始键、复位键和暂停/开始键时,“t”被清除为0,以便从0 ms开始计数

2.控制流

主程序主要用于检测全局变量“时间”,当“时间”为0时发出“声光报警”。按键驱动、显示驱动和“时间”操作都在定时器0中断服务程序中进行。控制流程如图2所示。

图2控制流程图

三、软件程序设计

1,数码管驱动器

计时器的两个数码管动态显示计时时间“time”(全局变量),LED1显示十位“time”,LED2显示一位“time”。

(1)定义段代码数据端口和芯片选择信号。

根据实际电路,C51中定义的段码的数据端口为P1,两个片选信号分别为P3.0和P3.1。定义如下:

#定义段P1

sbit wei1=p3^0;

sbit wei2=p3^1;

(2)定义字体代码

LED显示数字0~9和被完全破坏的字体码表放在数组zixing[]中。字体代码是一个固定的表,在定义的时候加上关键字“code”意味着这个表存储在程序内存中。

无符号字符代码zixing[]=

{

0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff

};

(3)定义LED1和LED2的显示变量。

为了增加驱动程序的可移植性,作者为LED1和LED2定义了显示变量。显示变量是这个驱动器的外部接口,外部程序可以通过改变显示变量的值来改变数码管显示的值。定义如下:

无符号字符led_str[2]={10,10 };

Led_str[0]直接对应LED 1,LED _ STR [1]直接对应LED2。在这个项目中,全局变量time的计算被一个特殊的子程序分为led_str[0]和led_str[1]两部分。

void js()

{

led _ str[1]= time/10% 10;

led _ str[0]= time % 10;

}

(4)数码管驱动器

数码管驱动程序“void处士(char i)”在定时中断服务程序中被调用和执行。根据初始化程序的定义,定时中断服务程序每1 ms执行一次,在定时中断服务程序中,用全局变量“t”记录进入服务程序的次数,当达到2000次时“t”被定时中断服务程序清零。

数码管驱动器的参数“char i”用于确定LED1或LED2当前是否点亮。当参数为“0”时,LED1亮,当参数为“1”时,LED2亮。如果我们想偶数次进入定时中断服务程序时点亮LED1,奇数次进入定时中断服务程序时点亮LED2,可以使用程序调用语句“处士(t % 2);”容易实现。

进入数码管驱动后,先调用子函数js()计算当前led_str[0]和led_str[1]。接下来把两个数码管都灭了,防止余辉。最后点亮需要点亮的数码管,发出字体代码。驱动程序代码如下:

无效处士(char i)

{

js();//计算显示变量

段= 0xff//去余晖

Wei 1 = I;wei2=!我;//确认电影选择

段= Zixing[led _ str[I]];//发送字体代码

}

2、关键驱动因素

按键驱动分为两部分:按键识别和按键功能执行。按键功能可以在按键时执行,也可以在按键抬起后执行,按键功能设计为在按键抬起后执行。

(1)定义关键I/O地址。

根据实际电路,三个按键(开始键、复位键、暂停/开始键)分别连接到P3端口的P3、P3.3和P3.4引脚。为了方便的获取键值,P3端口也被定义为“iokey”,可以在程序中定义如下:

#定义约基·P3

sbit key1=p3^2;

sbit key2=p3^3;

sbit key3=p3^4;

(2)关键驱动过程

按键识别的一般流程如下:I/O口写“1”→判断某个按键是否被按下→延时摇动→确定键值→等待按键被抬起→执行按键功能。按键驱动中定义了两个静态变量“ts”和“kv”,分别用于延迟去抖和存储键值。

(3)延迟去抖

静态变量“ts”用于延迟去抖。在定时器中断服务程序中,每1毫秒执行一次按键驱动程序。当按下一个键“ts”并添加1时,如果没有按下一个键,它将被清除。如果键被连续按下20毫秒,当键驱动器被连续执行20次时,检测到键被按下。此时静态变量“ts”累计到20,可以确认按键被有效按下。

为了防止按键保持按下时“ts”累积溢出,可以将“ts”的值保持在20或者大于20的某个值,比如21。

(4)取键值

确认某个键被按下后,可以通过读取该键的I/O端口状态来获取键值。为了读取P3.2、P3.3、P3.4的管脚状态,屏蔽P3口其他管脚的影响,读取值可以逐位或高达11000111b(0x E3)后发送给静态变量“kv”。

静态变量“kv”存储该键的键值,在没有按下任何键或抬起键后,kv的值为0。按下启动键时Kv = 111110111b(0x FB),按下复位键时Kv = 1165448。当按下暂停/开始键key3时,KV = 11011111b(0x ef)。

(5)执行键功能

当按键被抬起后第一次执行按键驱动时,静态变量“kv”保存按键被按下时最终得到的键值,键值作为参数调用按键执行器“act key(kV);”可以执行按键功能。通话结束后,kv值立即清零,以确保按键功能执行一次。驱动程序代码如下:

void键()

{

静态无符号字符kv = 0;

静态无符号字符ts = 0;

key 1 = 1;key 2 = 1;key 3 = 1;

如果(!(key 1 & amp;key2 & amp按键3))

{

ts++;

if(ts & gt;= 20)ts = 20;//有一个键被按下。

如果(ts==20)

kv = iokey | 0xe3//获取键值

}

其他

{//没有按下或抬起任何键。

act key(kv);

ts = 0;

kv = 0;

}

}

函数actkey(kv)用于根据键值“kv”执行相应的操作。当“kv”等于0xFB时,表示启动键key1被按下,函数actkey(kv)将全局变量act赋值为“1”。当“kv”等于0xF7时,表示复位键key2被按下,函数actkey(kv)将全局变量“time”复位为“30”。当“kv”等于0xEF时,表示暂停/开始键被按下,函数actkey(kv)反转全局变量act。每按一次按钮,全局变量“t”就会被清零,这样每当定时器复位或启动时,进入计时中断的次数就会从0开始计数,否则第1秒计时不准。程序代码如下:

void actkey(无符号字符k)

{

开关(k)

{

case 0x FB:act = 1;t = 0;打破;

案例0xf7:时间= 30;t = 0;打破;

case 0x ef:act = ~ act;t = 0;打破;

}

}

四。结束语

本文在编程过程中用面向对象的编程思想封装了两个LED数码管和三个独立的按钮。在定时中断服务程序中调用它的驱动程序时,程序员只需要操作它的接口:数组“led_str[2]”和函数“actkey(unsigned char k)”,就可以改变函数,不需要直接对硬件编程,增强了软件的通用性和可移植性。