资源描述
.. -
基于单片机的班级投票器
【摘要】班级投票器是针对班级而设计的现场投票计数器系统,该系统可用于班级人数小于99人,职位候选人不超过10人的投票选举。投票器是由键盘接口专用芯片74C922来完成按键编码,再通过单片机采集信息,进展票数的累计,最后有四联数码管来显示选举结果。投票期间用一个按键来控制投票有效性,并通过发光二极管来完成指示工作。选举投票期间可暂停投票,查看投票结果,后可继续投票,直至到达预设的最大班级人数关闭投票系统。
引言……………………………………………………………………………………3
1 系统总体设计………………………………………………………………………4
1.1设计要求…………………………………………………………………………………..........4
1.2 系统组成方框图……………………………………………………………………………......4
1.3 方案设计……………………………………………………………………………………......4
2 系统硬件设计………………………………………………………………………4
2.1 相关芯片介绍………………………………………………………………………………......4
2.1.1 AT89C51芯片介绍…………………………………………………………………………...4
2.1.274C922芯片介绍……………………………………………………………………….........5
2.1.3 74LS04芯片介绍……………………………………………………………………….........6
2.2 各单元电路设计与分析……………………………………………………………………......7
2.2.2 由74C922够成的键盘电路………………………………………………………………....7
2.2.2 复位电路…………………………………………………………………………………......8
2.2.3 时钟电路…………………………………………………………………………………......8
2.2.4 显示模块……………………………………………………………………………………..9
2.2.5 控制投票有效局部…………………………………………………………………………10
2.3 总原理图和元器件清单……………………………………………………………………….11
2.3.1 总原理图…………………………………………………………………………………….11
2.3.2 元件清单…………………………………………………………………………………….11
3 系统软件设计………………………………………………………………………12
3.1 主程序设计……………………………………………………………………………………12
3.2 中断程序设计…………………………………………………………………………………13
3.3 定时程序设计…………………………………………………………………………………14
4 调试…………………………………………………………………………………16
5 总结…………………………………………………………………………………16
6 致语………………………………………………………………………………17
参考文献………………………………………………………………………………17
附录一 PCB图 ………………………………………………………………………19
附录二 源程序 ………………………………………………………………………19
引言
在大学生活中,时常发生选举投票事件。目前班级职位选举采用纸条的方式进展投票。具体过程如下:首先,在黑板上列出要选举的职位及职位候选人的名字;接着班级成员在纸条上写上候选人的名字,折叠好放在指定的位置〔如讲台桌上〕;再来全部投票完毕后,进展唱票,判断票的有效性〔写上多于一个候选人的名字,或不写都视为废票〕,同时并统计票数。最后,票数统计完成后先判断本次选举是否有效〔假设发生选票多于选民数,视为无效〕。确定本次选举有效后,宣布最高得票者为该职位的的中选者。这样的选举的缺点是比拟费时,效率不高,同时也由于可能发生的选举无效问题,造成时间的延长,同时降低班级成员的积极性等。其优点就是选举十分的直观,可以在唱票时期直接观察到每个候选人的得票情况,并较直接判断出中选人。
针对纸条选举费时,效率不高的问题,采用设计投票器来改善这一情况。本设计是基于单片机设计的适用于班级选举的投票器,由键盘专用芯片74C922完成投票,再经由单片机采集信息,统计票数。最后由四联数码管显示投票结果。并且利用发光二极管和一个按键来控制投票的有效性。选举投票期间可暂停投票,查看当前投票结果,后可继续投票,直至到达预设的最大班级人数就会自动关闭投票系统。
本次设计的班级投票器可以有效地控制投票及选举的有效性,就节省了去判断选票及选举的有效性及选举无效延长的时间。同时投票器本身有统计票数的功能,就又节省了统计票数的时间。整体上提高了班级选举的效率,同时也使得选举更加地,公平。
1、系统总体设计
1.1 设计要求
假定班级成员45人,职位候选人10人〔不超过10人〕。选民〔班级成员〕分别编号为01,02,……44,45;候选人分别编号为01,02,……,09,10(由10个按键构成)。
(1) 一上电不允许投票,按下允许投票键,利用10个按键进展投票,有效投票后显示选民编号和所选候选人的编号。将投票结果储存起来并且再按其他按键无效。
(2) 按下允许投票键进展下一个选民的投票。
(3) 投票期间,可暂停投票来查看票数统计结果,后按下允许投票键又可继续投票。
(4) 全部成员投票完成后,最后显示候选人的编号及其得票数。
(5) 按下复位键,进展新一轮的职位选举。
1.2 系统组成方框图
单片机
〔AT89C51〕
时钟电路
复位电路
由74C922构成的键盘投票
允许投票键开启选民投票
LED灯灭提示选民可以进展投票;当LED灯亮,无法进展投票。
数码管显示
图1-2 系统模块组成方框图
1.3 方案设计
设计时班级成员不超过99,职位候选人10人。由键盘接口专用芯片74C922及12个按键〔10个按键用于投票工作,2个按键用于查看投票结果〕构成的电路来完成键盘扫描,编码,再通过AT89C51芯片来采集信息,进展票数的统计。由四联数码管完成显示工作,投票期间显示选民编号和所选候选人的编号,查看结果时显示候选人的编号及其得票数。设置一按键来控制有效投票,并让发光二极管配合指示。选举投票期间可暂停投票,查看投票结果,后可继续投票,直至到达预设的最大班级人数关闭投票系统。
2、系统硬件设计
2.1 相关芯片介绍
2.1.1 AT89C51芯片简介
AT89C51是一种低电压,高性能CMOS8位单片机,采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片置通用8位中央处理器(CPU)和FLASH存储单元,功能强大AT89C51单片机可为您提供许多高性能比的应用场合,可灵活应用在各种控制领域。[1]
它具有以下特点:4K字节FLASH闪速存储器,128字节部RAM,32个I/O口线,两个16位定时/计数器,一个5向量级中断接口,一个全双工串行通信口,片振荡器及时钟电路。同时,AT89C51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。空闲方式停顿CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。掉电方式保存RAM中的容,但振荡器停顿工作并制止其它所有部件工作直到出现下一个硬件复位。
图2-1-1 AT89C51引脚图
2.1.2 74C922芯片简介
74C922芯片有16键IC和20键IC,本设计采用的是16键的IC。图2-1-2〔1〕所示为4×4(16键)扫描式编码键盘原理图。这种键盘的按键排成矩阵形式,以减少按键联线。如图中有16个键,排列成4行4列,仅需8根引线。时钟发生器的输出送给4位计数器进展计数,计数器的低2位经译码后作为行扫描,高2位经译码后作为列扫描。假设没有检出有键闭合,那么计数器周而复始反复计数,即反复进展扫描,一旦检出有键闭合,就发出一个脉冲使时钟振荡器停振,计数器随即停顿计数。单片机通过读取计数器的计数值来获取闭合键所在的行列位置,然后从真值表得到按键读数。如果有两个键同时按下,那么扫描到第一个闭合键时就停顿扫描,把该键当作有效按键进展处理。[2]
4
位计数器
时钟发生器
2—4译码器
4×4
键盘
2
︳
4
译码器
去抖动
停振
选通
3
2
1
0
图2-1-2〔1〕扫描式编码键盘
74C922芯片(16键IC)的引脚排列如图2-1-2〔2〕所示:
图2-1-2〔2〕74C922引脚图
X1~X4:列线。
Y1~Y4:行线。
OSC:接振荡电容0.1μF,以便扫描矩阵键盘
KM:键盘消除抖动电路,并发出两种信号。(1)部计数器停顿计数。(2)假设有键按下,使DA脚由未按键时的低电平变为高电平,假设按键未放开那么一直保持高电平,当按键放开时,才转为低电平。此引脚外接一个电容是OSC所接电容的10倍。
DA:数据有效信号。假设无键按下,保持低电平。假设有键按下,变为高电平,直到键放开,才转为低电平。
/OE:输出使能。D~A:按键值输出,按BCD码输出,具体输出情况如表2-1-2所示。
表2-1-2真值表
数据输出
0
Y1,
X1
1
Y1,
X2
2
Y1,
X3
3
Y1,
X4
4
Y2,
X1
5
Y2,
X2
6
Y2,
X3
7
Y2,
X4
8
Y3,
X1
9
Y3,
X2
10
Y3,
X3
11
Y3,
X4
12
Y4,
X1
13
Y4,
X2
14
Y4,
X3
15
Y4,
X4
A
0
1
0
1
0
1
0
1
0
1
0
1
0
1
0
1
B
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1
C
0
0
0
0
1
1
1
1
0
0
0
0
1
1
1
1
D
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
2.1.3 74LS04芯片简介
74ls04是一六反向器,其功能表如表2-1-3,其引脚分布如图2-1-3。
表2-1-3功能表
Y=
输入
输出
A
Y
L
H
H
L
H为高电平
L为低电平
图2-1-3 74LS04引脚图
2.2 各单元电路设计与分析
2.2.1由74C922够成的键盘电路
图2-2-1 74C922构成的键盘电路
在键盘局部采用74C922来完成工作。键盘电路图如图2-2-1所示。74922芯片是专用编码键盘接口芯片,当按下某一按键时,该芯片能自动给出相应的编码信息,并可自动消除抖动,从而可免除关于削抖的软件编程,提高了CPU的利用率。[2]因为按键扫描要对按键进展削抖处理,而削抖分为软件削抖和硬件削抖,一般情况下多采用软件削抖。
74C922为CMOS工艺技术制造,工作电压为3—15V,“二键锁定〞功能,编码输出为三态输出,可直接与微处理器数据线相连,部振荡器完成4×4矩形键盘扫描,当有按键按下时,DA变高,通过非门接到AT89C51的外部中断0,并且设外部中断0为边沿触发方式,当DA变高时,经过非门变为低电平跳变产生外部中断,通知AT89C51从数据总线读键值,判断键值从而完成相应的散转程序功能。[3]根据图2-2-1及74C922芯片真值表2-1-2,按键S1—S10对应DCBA输出〔0000—1001〕,上下翻查键S11,S12对应输出是〔1010〕和〔1011〕。同时ABCD输出连接到AT89C51的P2口的P2.0—P2.3。
2.2.2复位电路
图2-2-2 复位电路
单片机的复位都是靠外部电路来实现的。在时钟电路工作后,只要在单片机的复位(RST)脚上出现24个时钟振荡脉冲(也就是2个机器周期)以上的高电平,单片机便实现初始化状态复位。[4]
传统的复位方法有阻容上电复位和按键电平复位如图2-2-2。本设计采用按键手动复位电路。它们实际上利用RC充放电原理实现的复位电路,从外部给RST脚2个机器周期以上的高电平。
在实际应用系统中,为了保证复位电路可靠地工作,常常将RC电路接斯密特电路后再接入单片机的复位端和外围电路复位端。这样就特别适用于应用现场干扰大、电压波动大的工作环境,并且当系统有多个复位端时,也能够保证可靠的同步复位。
当AT89C51的RST引脚到高电平时,单片机就会复位。按下按纽S13,将高电平接到RST端,从而复位。复位后,单片机就从0000H地址开场执行程序。P0~P3四个并行接口全为高电平,其他存放器全部清零,只有SBUF存放器状态不确定。
2.2.3时钟电路
图2-2-3 时钟电路
时钟电路是计算机的心脏,它控制着计算机的工作节奏。CPU就是通过复杂的时序电路完成不同的指令功能的。MCS-51的时钟信号可以由两种方式产生:一种是部方式,利用芯片部的振荡电路,产生时钟信号;另一种为外部方式,时钟信号由外部引入。MCS-51单片机有HMOS型和CHMOS型,它们的时钟电路有一定区别。[5]
部时钟电路,利用AT89C51部一个高增益的反向放大器,把一个晶振体和两个电容器组成的自激振荡电路接于XTAL1〔19脚〕和XTAL2〔18脚〕之间。这样,振荡器发出的脉冲直接送入部时钟电路。如图2-2-3所示。图中晶振体可以是石英晶体或瓷构造,振荡频率可任选,一般频率在1.2~12MHz。对于石英晶体振荡器,电容C3,C4在30pF左右,对于瓷振荡器,C3,C4约47pF左右。
外部部时钟电路,MCS-51的部工作时钟也可以由外部振荡器提供,这时,对HMOS型芯片,外部振荡器的信号接至XTAL2,即部时钟发生器的输出端,而部反相放大器的输人端XTAL1应接地.在CHMOS电路中,因部时钟发生器的信号取自反相放大器的输入端(即与非门的一个输人端),故采用外部时钟源时,接线方式与HMOS型的有所不同:外部信号接至XTALI,XTAL2不用。外部时钟引入方式如图2-2-3(A,B,C)所示。对外部振荡器的信号没有特殊的要求,一般为0.5一12 MHz的方波,方波的波形应尽量规即上升沿、下降沿尽可能垂直。
时钟发生器把振荡频率加以二分频,给主机提供了一个双相信号,第一相信号在每一个时钟周期的前半局部有效,第二相信号那么在时钟周期的后一半有效。
图2-2-3(A)HMOS和CMMOS器件都适用的外部时钟连接图
图2-2-3(B)HMOS器件外部时钟连接图 图2-2-3(C)CHMOS器件外部时钟连接图
本次设计采用部时钟电路,石英晶体〔频率12M〕,电容C3,C4为30pF。AT89C51的机器周期为1us。
2.2.4显示模块
〔1〕显示方式的选择
7段数码管的显示方法可分为静态显示和动态显示,
所谓静态显示,就是当显示某一字符时,相应段的发光二极管恒定地导通或截止。例如,7段显示器的a、b、c、d、e、f段导通,g、dp段截止,那么显示0。这种显示方法的每一位都需要有一个8位输出口控制。对于51单片机,可以在并行口上扩展多片锁存器74LS573作为静态显示器接口。
所谓动态显示就是一位一位地轮流点亮各位显示器〔扫描〕,对于显示器的每一位而言,每隔一段时间点亮一次。虽然在同一时刻只有一位显示器在工作〔点亮〕,但利用人眼的视觉暂流效应和发光二极管熄灭时的余辉效应,看到的却是多个字符“同时〞显示。显示器亮度既与点亮是的导通电流有关,也与点亮时间和间隔时间的比例有关。调整电流和时间参数,可实现亮度较高较稳定的显示。假设显示器的位数不大于8位,那么控制显示器公共极电位只需一个8位I/O口〔称为扫描口或字位口〕,控制各位LED显示器所显示的字形也需要一个8位口〔数据口或字形口〕。
与静态驱动显示相比,动态扫描显示具有以下优点:第一,能显著降低显示器的功耗,这对于采用电池供电的便携式数字仪表尤为重要;第二,能大大减少显示器的外部引线,给印制板的设计和安装带来方便;第三,能采用BCD码多路输出的方式,不仅使译码、驱动电路大为简化,还可以与微机相连等。[6]动态扫描的缺点是CPU工作效率比静态扫描低,同时显示亮度较静态显示器要低。
本次设计选择采用动态扫描。如图2-2-4芯片AT89C51的P1.0—P1.6作为数据口,P0.0—P0.3作为扫描片选口。
图2-2-4 LED显示电路
(2)数码管的驱动
本设计采用共阴型的四联数码管,关于数码管的驱动局部把P1口〔P1.0 —P1.6〕作为驱动接口,并外接上排阻511作为其上拉电阻增强其驱动能力。这样的驱动能力就可使数码管显示适宜的亮度。
2.2.5控制投票有效局部
由一个发光二极管〔DS1〕和一个按键〔S〕构成控制投票有效局部,如图2-2-5所示。通过软件设置成发光二极管DS1灭时可允许投票,DS1亮时不可以投票。而按下按键S〔允许投票键〕,让P3.3产生一个负跳变,开启外部中断1〔外部中断选择边沿触发的方式〕,通过软件编程使发光二极管灭,一检测到有投票按键按下,使发光二极管亮。通过DS1和S的配合来控制投票有效的问题。
图2-2-5 控制投票有效局部电路
2.3总原理图和元器件清单
2.3.1总原理图
图2-3 总原理图
2.3.2元件清单
器件名称
器件型号
数量
备注
单片机
AC89C51
1
晶振
12M
1
键盘编码器
74C922
1
非门
74LS04
1
四联数码管
共阴型
1
发光二极管
1
按键
14
磁介电容
30pf
2
104
2
电解电容
22uf
1
电阻
1K
6
100欧
1
排阻511
1
导线
假设干
电源
5V
1
3、系统软件设计
开场
存放器的配置
灯和系统的初始化
进入for(;;)死循环
按下键是有效投票吗?
显示数据转换,
被选候选人选票加1,
选民编号自动加1,灯亮
选民编号等于预设的最大选民人数加1
关闭投票系统
按下键S11?
按下键S12?
上翻操作
下翻操作
Y
N
N
Y
N
N
Y
intbit=1
Y
N
3.1主程序设计
图3-1 主程序流程图
主程序流程图如图3-1所示,在存放器配置的环节中,包含了翻开外部中断1,外部中断0,选择2个外部中断的触发方式为边沿触发方式;选择定时器T1的工作方式为方式2〔自动再装入的8位定时器的工作方式〕,翻开T1的溢出中断并对其赋初值。
当intbit=1时,开场执行主程序中关于对选票的统计,上下翻等操作,而外部中断0翻开后的便会执行intbit=1。
按下键是有效投票须同时满足3个条件,第一个是发光二极管LED指示灯处于灯灭状态,第二个是选民编码未超过最大班级人数,第三个是按下的键是键S1—S10其中一个。
与74C922配合的12个按键中,S1—S10代表的是10个候选人〔01—10〕相应被投票键,S11是用于查询结果时的上翻键,S12是用于查询结果时的下翻键。
中断0的中断入口
Key键值清零
Key键值加1,
并置intbit为1
中断返回
P2.0为高电平?
Key键值加1
P2.1为高电平?
Key键值加2
P2.2为高电平?
Key键值加4
P2.3为高电平?
Key键值加8
N
N
N
N
Y
Y
3.2中断程序设计
关闭LED
中断1的中断入口
中断返回
图3-2(1) 外部中断1流程图
图3-2(2) 外部中断0流程图
外部中断1流程图如图3-2(1)所示,外部中断0流程图如图3-2(1)所示,其中2个外部中断的触发方式皆是边沿出发,通过硬件电路中P3.3〔INT1〕引脚处连接一个按键〔S,也就是允许投票键〕来控制中断1。当按键按下时便会产生一个负跳变,翻开了中断1。执行中断程序让发光二极管灭〔允许投票〕。通过按键S和LED灯来控制按键投票的有效性。
外部中断0用来完成按键采集工作,并置intbit为1,转入执行主程序中关于对选票的统计,上下翻等操作。与74C922芯片构成的12个按键的键盘电路,一有按键按下,74C922的DA端由低电平转为高电平再经74LS04非门的取反作用给P3.2(INT0)产生负跳变,便翻开中断0。
按键S1—S10〔10个候选人01—10相应被投票键〕对应DCBA输出〔0000—1001〕,上下翻查键S11,S12按键值对应输出是〔1010〕和〔1011〕。ABCD输出端连接到AT89C51的P2口的P2.0—P2.3。执行如图3-2(2)所示的操作,便使得从按键S1—S12采集给Key,分别对应Key键值为1到12。
3.3定时程序设计
定时器T1的主要功能就是用于四联数码管的片选显示,每隔10个定时中断时间〔2.39ms〕换一位数据管显示相应的数字。定时中断流程图如图3-3所示。
通过主程序中的TMOD=0x20语句选择定时器工作方式为方式二〔自动再装入的8位定时器的工作方式〕;通过TL1=0x00;TH1=0x11;两个语句对T1赋初值。T1的定时时间为t,
t=(2^8-TH0初值)*振荡周期*1 3-3
根据公式3-3可知t=(256-17)*(1/12M)*12=239us,那么10个定时时间就是2.39ms,
本设计中硬件电路中,共阴型的四联数码管的4个片选端〔1—4〕与AT89C51的P0.0—P0.3引脚相连。同时共阴型的数码管的片选端是低电平有效,cs用于片选,cs等于0—3相当于连接到数码管的片选端〔4—1〕。本设计采用的是动态扫描,而动态扫描的频率有一定的要求,频率太低,LED将出现闪烁现象。假设频率太高,由于每个LED点亮的时间太短,LED的亮度太低,肉眼无法看清,所以一般均取几个ms左右为宜。本次设计选择每隔10个定时中断时间〔2.39ms〕换一位数码管显示,利用人眼的视觉暂流效应和发光二极管熄灭时的余辉效应,就可以看到四联数码管输出四个数字。调试时,可根据实际情况再对定时时间做适当的调节。
定时器1的中断入口
到了10个定时时间了吗?
cs=0?
P0.3置0
cs=1?
P0.2置0
cs=2?
P0.1置0
cs=3?
P0.0置0
数码管显示相应位的数字
cs!=3
cs加1
cs置0
N
N
N
N
N
N
Y
Y
Y
Y
Y
Y
中断返回
N
图3-3 定时中断流程图
4调试
调试包括硬件调试和软件调试。而硬件调试的主要任务是排除硬件故障,其中包括设计错误和工艺性错误。在利用Keil和Proteus两个软件仿真调试,根本上验证了设计方案的可行性后,开场画原理图和PCB图〔PCB图见附录一〕,接着制版。对制好的电路板进展初步调试,检查电路是否符合原理图的设计,是否出现短路,断路等现象。及时对电路板做适当的修补。接着大致检查一下要用到的元器件,没问题后焊接电路。做好硬件电路后,将源程序〔源程序见附录二〕烧入AT89C51芯片,后芯片插在电路板上,接上5V的电源进展调试。
一开场发现数码管不能正常显示,同时也不够亮。同时LED灯指示灯会一直亮,按下允许投票按键〔S〕也不会灭。接着就用万用表分模块检查电路,排查故障。具体地对照仿真图检查各个芯片管脚的电压是否到达正常的工作电压。
首先检查单片机是否有起振,是否会正常。发现EA端悬空,为了单片机能稳定工作将EA端接高电平〔访问的地址空间在0—4KB围,CPU访问程序存储器;访问的地址空间超出4KB时,CPU将自动访问外部程序存储器〕。检查后发现单片机有起振,可正常工作。
其次检查由74C922芯片构成的键盘电路,发现由74C922芯片构成的键盘电路本身能正常工作〔按下相应的键连接ABCD的管脚会输出正确的数据〕;然而按下投票按键数码管确不能显示正确的数据,说明是显示的问题。而检查过共阴型的四联数码管发现它可以正常工作,调试时发现数码管的亮度不够,说明需要增强驱动能力,同时数码管的显示不正常,很有可能是因为程序中的关于数码管动态显示的方面有问题。
在设计的电路AT89C51的P1口〔P1.0—P1.6〕直接接上四联数码管的A—G脚,显然这样单靠P1口的驱动是不够的,后在P1口〔P1.0—P1.6〕加上7个510欧的上拉电阻〔利用排阻511实现〕来增强其驱动能力,修改调试后发现数码管可显示的足够的亮度。
做好以上的修改再调试时,观察到数码管刚开场会显示初始状态〔4个0〕,复位按键也有效,允许投票按键也可与LED配合正常显示,但是按下投票按键,数码管不会显示正常的数锯。再一次验证了很有可能是软件局部数码管的动态显示有问题。后将程序中关于片选扫描局部P0口(P0.0—P0.3)由原先的右移片选扫描改为直接的对P0.0—P0.3直接片选赋值后,再次烧入程序便可显示正常的数据。
此时,电路板根本上实现了设计要求。但必须全部投票完成后才可利用上下翻查键来查看投票的结果。接着对程序关于上下翻查键局部作出适当的修改后,可实现了再未到达预设的班级人数时,也可查看当时的投票结果。
5总结
本设计是基于AT89C51设计的班级投票器。它可实现最多班级人数99个,最多职位候选人10个的投票选举。由键盘接口专用芯片74C922完成按键扫描编码工作,再通过AT89C51芯片来采集信息,完成票数统计任务,并有四联数码管显示相应的数字〔投票期间显示选民编号和所选候选人的编号,查看结果时显示候选人的编号及其得票数〕。同时有LED和允许投票按键来控制投票的有效性。可以在投票期间或投票完毕时利用上下翻查键可以查看投票结果。而班级投票器主要用来满足平常班级职位等选举,它可以较提高班级职位选举的效率,同时更加突出了选举的公平,公开。
本设计需改良的地方,首先,可以增设一个弃权键和一个用于显示最后投票选举的结果的按键,使得投票系统更加的完善。其次,本次设计的投票器是基于班级设计,考虑到实际中班级投票的情况,设计时最多候选人人数为10人,以满足班级日常选举。可进一步增大候选人人数,来完善投票系统,使其更大围的选举。再有,假设显示时编号可配合人名等资料显示,会使得显示结果更加的直观;最后,可以进一步的改善,实现直接手动调节相关按键便可设置最大班级人数,而不需要通过软件修改来完成。
附录
1、PCB图
2、源程序
#include "reg51.h"
sbit LED=P2^4;
sbit P2_0 = P2^0;
sbit P2_1 = P2^1;
sbit P2_3 = P2^3;
sbit P2_2 = P2^2;
sbit P3_3 = P3^3;
unsigned char key=0;
#define max_xuanmin 45 //最多项选择民数量
unsigned char beixuan[11];//选手选票数
unsigned char xuanmin=1;//选民编号
unsigned char present=1;//目前这个被选者,用于显示整体选票
unsigned char ledout[4]; //显示数据
unsigned char code led1[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x27,0x7f,0x6f};
unsigned char cs=0;
unsigned char flash_cs=0;
bit ok=0;//投票输入OK
bit intbit=0;
void delay(unsigned int time)
{
unsigned int mm;
for(mm=0;mm<time;)
mm++;
}
void led_init(void)
{
unsigned char n;
for(n=0;n<=9;n++)
beixuan[n]=0;
LED=1;
ok=0;
}
/***********************************************************************************
****************************进展数据转换********************************************
************************************************************************************/
void change_led(unsigned char xuan,unsigned char value)
{
unsigned char x,change;
x=xuan;
change=x/100;
x=xuan;
ledout[3]=x/10-change*10;
x=xuan;
ledout[2]=(unsigned char)(x-change*100-ledout[3]*10);
x=value;
change=x/100;
x=value;
ledout[1]=x/10-change*10;
x=value;
ledout[0]=(unsigned char)(x-change*100-ledout[1]*10);
}
/***********************************************************************************
************外部中断1的入口*********************************************************
************************************************************************************/
int1_in() interrupt 2 using 3
{
LED=0;
}
/***********************************************************************************
**************************外部中断0的入口******************************************
************************************************************************************/
int0_in() interrupt 0 using 3
{
key=0;
if(P2_0==1)
{
key=key+1;
}
if(P2_1==1)
{
key= key+2;
}
if(P2_2 ==1)
{
key= key+4;
}
if(P2_3==1)
{
key= key+8;
}
key=key+1;
intbit=1;
}
/***************************************************************************************
*****************************定时1的入口**********************************************
***************************************************************************************/
Time1() interrupt 3 using 3
{
unsigned char bb;
flash_cs++;
if( flash_cs==10)//每隔10个定时中断换一个数据
{
if(cs==0)
P0=0xff-8;
if(cs==1)
P0=0xff-4;
if(cs==2)
P0=0xfd;
if(cs==3)
P0=0xfe;
flash_cs=0;
bb=ledout[cs];
P1=led1[bb];
if(cs!=3)
cs++;
else
cs = 0;
}
}
/***********************************************************************************
**********************************主函数********************************************
************************************************************************************/
void main()
{
EX0=1;
IT0=1;
EX1=1;
IT1=1;
ET1=1;
TMOD=0x20;//采用定时器1的第二种工作方式
TL1=0x00;
TH1=0x11;
TR1=1;
EA=1;
led_init();
change_led(0,0);
for(;;)//整个系统进入死循环
{
if(intbit)
{
if(key>0 && key<=10 && ok==0 && LED==0)
{
change_led(xuanmi
展开阅读全文