找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6071|回复: 0
打印 上一主题 下一主题
收起左侧

基于51单片机的投票表决器制作~~

[复制链接]
跳转到指定楼层
楼主
ID:167955 发表于 2017-3-4 19:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;
    }
}




































分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表