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; } }
|