标题: 基于51单片机的投票表决器制作~~ [打印本页]
作者: lvzhibi 时间: 2017-3-4 19:58
标题: 基于51单片机的投票表决器制作~~
1、前言
在社会高速发展的当下,各方各面效率的提升得到了人们的重视,投票表决环节也不例外。按照传统的用纸条投票,会耽误大量的时间,其中就包括制作纸条的时间,分发和回收纸条的时间。也许大家说手机网络投票,网络手机投票往往要要打开网页,但前提是网速要好。在这种情况下,如果在座位旁安装一个投票按钮,随手可按,轻松、随意。这样子既可以节省大量的时间和精力,同时也可以排除网络不稳定而导致无法网络投票的问题。这样的一个投票系统,具有巨大的意义,充分节省时间和精力,有很大的便捷性,同时发挥了公平的原则,让人人都可以表达出自己的意愿,有效调动了大家的积极性,提高大家对投票结果的认可度,减少了冲突的发生,并且实时传递出投票讯息,在一些比赛娱乐节目中具有很高的实用价值。
2、使用及应用说明
2.1、投票表决器的使用
根据使用方便原则,本投票表决器采用充电宝供电。将充电宝输出端接于本投票表决器的USB接口上(由于买的USB接口比较廉价,需要按紧外皮后再插入到充电宝中),此时显示屏亮起,显示屏左边数字表示反对票数目,对应于五对按键中的左方按键(×),显示屏右边数字表示赞成票数目,对应于五对按键中的右方按键(√)。通电以后,依次输入赞成或者反对(即按下每一对按键左边或者右边的按键),然后按下蓝色的确定按键,此时芯片判断输入的赞成反对票数,当赞成票数大于反对票数时,流水灯开始亮起显示效果,赞成与反对票数相同时,黄灯亮起,反对票数大于赞成票数时,红灯亮起,整个投票过程中显示屏都实时显示赞成和反对的票数。
若要进行下一次判断或者需要重置票数,则按下左下方黄色按钮,重置票数,此时显示屏显示0.0 ,以后即可进行下一次投票。
2.2、应用
当需要进行投票时,接通充电宝电源,
即可按照以上方法依次进行投票。
3、原理
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image002.jpg
本投票表决器是基于两块51单片机来制作的,右边一块的下方引脚用来读取十二个独立按键的电平值并进行分析,当单片机统计到赞成票数和反对票数的总数时,实时地给上端p口分配相应电平值以点亮数码管相应段位(其中数码管与单片机p口中间用了三极管扩流)。
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image004.jpg
三极管扩流
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image006.jpg
独立按键
同时,单片机程序会对赞成票数和反对票数进行分析,若反对票数大于赞成票数时给予红色LED管以高电平,若持平给予黄色LED管以高电平,若赞成票大于反对票将投票通过的结果通过串口(右边单片机上端的一个p口)传送到左边单片机,左边单片机执行点亮绿色LED爱心阵列的程序。
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image008.jpg
爱心阵列
本投票表决器通过usb口用充电宝作为5V电源供电,为解决工作电流太小而导致充电宝自动关闭的情况,我们在电源线两端并联了一个68欧姆的电阻,如下图所示。
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image010.jpg
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image012.jpg
USB线
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image014.jpg
背面焊接图
另外,我们在设计电路的过程中,给两块单片机芯片都分别预留了两个p口,可以随时对程序进行修改并烧录进芯片。
心形灯接线原理图:
file:///C:/WINDOWS/TEMP/msohtmlclip1/01/clip_image016.jpg
附:
右边单片机芯片源代码为:
#include<reg51.h>
#include<intrins.h>
#defineAGREE_P P1
#defineDISAGREE_P P2
typedef unsigned char uchar;
sbit RESET_P = P3^3;
sbit RE_AGREE_P = P3^4;
sbit RE_EQUAL_P = P3^5;
sbit RE_DISAGREE_P = P3^6;
sbit SHOW_RESULT_P = P3^2;
bit TR0_5ms_FLAG = 0;
voidTimer0Init(void) //5毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0xEE; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
ucharpops(uchar n){
char cnt = 0;
while(n){
if(n&0x01)
++cnt;
n >>= 1;
}
return cnt;
}
voidshow_result(uchar agree,uchar disagree,uchar init){
if(init){
RE_AGREE_P = 1;
RE_EQUAL_P = 1;
RE_DISAGREE_P = 1;
return ;
}
if(agree > disagree){
RE_AGREE_P = 0;
RE_EQUAL_P = 1;
RE_DISAGREE_P = 1;
}
else if(agree < disagree){
RE_AGREE_P = 1;
RE_EQUAL_P = 1;
RE_DISAGREE_P = 0;
}
else {
RE_AGREE_P = 1;
RE_EQUAL_P = 0;
RE_DISAGREE_P = 1;
}
}
void main()
{
uchar reset_p_last = 0;
uchar agree_p_last = 0x00;
uchar disagree_p_last = 0x00;
uchar agree_last = 0x00,disagree_last =0x00;
uchar agree,disagree;
uchar show_result_last = 0;
uchar show_on = 0;
uchar t;
show_result(0,0,1);
Timer0Init();
ET0 = 1;
EA = 1;
while(1){
if(TR0_5ms_FLAG){
TR0_5ms_FLAG = 0;
agree = RESET_P;
t = reset_p_last;
reset_p_last = agree;
if(!agree && t){
agree_p_last = 0x00;
disagree_p_last = 0x00;
agree_last = 0x00;
disagree_last = 0x00;
show_result_last = 0;
show_on = 0;
show_result(0,0,1);
continue;
}
agree = SHOW_RESULT_P;
t = show_result_last;
show_result_last = agree;
if(!agree && t){
show_on = 1;
}
agree = AGREE_P;
disagree = DISAGREE_P;
t = agree_p_last;
agree_p_last = agree;
agree = t & (~agree);
t = disagree_p_last;
disagree_p_last = disagree;
disagree = t & (~disagree);
agree_last |= agree;
disagree_last |= disagree;
if(show_on)
show_result(pops(agree_last),pops(disagree_last),0);
}
}
}
void tr0() interrupt1{
TL0 = 0x00; //设置定时初值
TH0 = 0xEE; //设置定时初值
TR0_5ms_FLAG = 1;
}
左边单片机芯片源代码为:
#include<reg51.h>
voiduart_init(void);
bitG_UART_RECVED;
bitG_TR0_FLAG;
unsignedchar g_uart_char = 0;
intg_tr0_cnt = 0;
void led_set(unsignedchar led_index,char on);
voidled_off(void);
sbit LED_13= P2^7;
sbit LED_14= P0^7;
#define BLINK_IM_MAX (4)
codeunsigned char blink_tm_by_50ms[BLINK_IM_MAX] = {2,2,4,12};
codeunsigned char blink_cnts[BLINK_IM_MAX] = {30,28,15,8};
#define LED_NUM (30)
void led_set(unsigned char led_index,char on){
unsignedchar t;
if(led_index< 7){
t =0x01<<(6-led_index);
if(on)
P2&= ~t;
else
P2|= t;
}
else if(led_index< 13){
t =0x01<<(14-led_index);
if(on)
P3&= ~t;
else
P3|= t;
}
elseif(led_index == 13){
LED_13 =on ? 0 : 1;
}
elseif(led_index == 14){
LED_14 =on ? 0 : 1;
}
elseif(led_index < 23){
t =0x01<<(22-led_index);
if(on)
P1&= ~t;
else
P1|= t;
}
elseif(led_index < 30){
t =0x01<<(led_index -23);
if(on)
P0&= ~t;
else
P0 |= t;
}
else {
;
}
}
void led_off(void){
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
P3 |= 0xFC;
}
void led_on(void){
P0 = 0x00;
P1 = 0x00;
P2 = 0x00;
P3 &=0x03;
}
void tr0_init(void){ // 50ms
TMOD &=0xF0; //设置定时器模式
TMOD |=0x01; //设置定时器模式
TL0 =0x00; //设置定时初值
TH0 =0x4C; //设置定时初值
TF0 =0; //清除TF0标志
TR0 =0; //定时器0开始计时
ET0 = 1;
G_TR0_FLAG =0;
g_tr0_cnt =0;
}
void uart_init(void){
SCON = 0x50; //UART为模式1,8位数据,不允许接收
TMOD |= 0x20; //定时器1为模式2,8位自动重装
PCON |= 0x80; //SMOD=1;
TH1 = 0xFD; //Baud:19200fosc="11".0592MHz
IE |= 0x90; //Enable Serial Interrupt
TR1 =1; // timer 1 run
TI=1;
ES = 1;
}
void led_show(unsigned char blink_im,unsigned charblink_cnt){
if(!blink_cnt)
led_off();
switch(blink_im){
case 0 :if(blink_cnt)
led_set(blink_cnt-1,0);
led_set(blink_cnt,1);break;
case 1 : if(blink_cnt){
led_set(blink_cnt-1,0);
led_set(blink_cnt+2,1);
}
else {
led_set(0,1),led_set(1,1),led_set(2,1);
}
break;
case 2 :led_set(blink_cnt,1),led_set(29-blink_cnt,1);break;
case 3 :if(blink_cnt&0x01)
led_on();
else
led_off();
break;
default: ;
}
}
void main(){
charled_blink = 0;
unsignedchar blink_im_cnt = 0;
unsignedchar blink_cnt = 0;
tr0_init();
uart_init();
//G_UART_RECVED = 1;
//g_uart_char = 'S';
EA = 1;
while(1){
if(G_UART_RECVED){
G_UART_RECVED = 0;
switch(g_uart_char){
case'E' : led_blink = 0; led_off();TR0 = 0; break;
case'S' : led_blink = 1; blink_im_cnt = 0;
blink_cnt =0;
g_tr0_cnt =0;
G_TR0_FLAG = 0;
TR0 = 1;
break;
default: ;
}
}
if(G_TR0_FLAG){
G_TR0_FLAG = 0;
if(led_blink){
led_show(blink_im_cnt,blink_cnt);
if(++g_tr0_cnt == blink_tm_by_50ms[blink_im_cnt]){
g_tr0_cnt = 0;
if(++blink_cnt == blink_cnts[blink_im_cnt]){
blink_cnt = 0;
if(++blink_im_cnt == BLINK_IM_MAX){
G_UART_RECVED = 1;
g_uart_char = 'E';
}
}
}
}
}
}
}
void tr0_int() interrupt 1 {
TL0 =0x00; //设置定时初值
TH0 =0x4C; //设置定时初值
G_TR0_FLAG =1;
}
void uart_int() interrupt 4 {
if(TI){
TI = 0;
}
else {
RI = 0;
g_uart_char = SBUF;
G_UART_RECVED = 1;
}
}
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |