单击计数器以使用C代码点亮LED

时间:2018-11-03 04:34:13

标签: c arduino-uno atmelstudio

我正在为微控制器设计一个点击计数器,并且正在使用C来开发代码。

这里发生的是,当我单击第一个按钮时,它将计算按钮按下的次数。然后,我必须按第二个按钮以二进制方式点亮LED来显示计数。例如,如果我按第一个按钮10次,它将点亮第二个LED和第四个LED。

由于有8个LED,我正在使用2个不同的端口。(PORTB有6位,PORTD有2位)。 为此,我开发了使用if / else的代码。但是我想实现此操作,而不执行多个if / else操作,因为这种方法似乎效率不高。

while(PIND & 0b00100000){                   //while PD5 switch is not pressed
        if(clickCount>=128){                //if click count>=128
            PORTB = PORTB | 0b00100000;     //set PB5 HIGH
            clickCount-=128;                //deduct 128 from clickCount
        }else if(clickCount>=64){
            PORTB = PORTB | 0b00010000;
            clickCount-=64;
        }else if(clickCount>=32){
            PORTB = PORTB | 0b00001000;
            clickCount-=32;
        }else if(clickCount>=16){
            PORTB = PORTB | 0b00000100;
            clickCount-=16;
        }else if(clickCount>=8){
            PORTB = PORTB | 0b00000010;
            clickCount-=8;
        }else if(clickCount>=4){
            PORTB = PORTB | 0b00000001;
            clickCount-=4;
        }else if(clickCount>=2){
            PORTD = PORTD | 0b10000000;
            clickCount-=2;
        }else if(clickCount==1){
            PORTD = PORTD | 0b01000000;
            clickCount = 0;
        }           
    }

我想用更少的字节数来编写此代码。那么,有什么方法可以使用for循环或任何其他方法来开发此代码段?

3 个答案:

答案 0 :(得分:3)

我不知道这是否会减少二进制文件的大小,并且未经测试。您仍然可以执行以下操作:

 unsigned char mask[] = {
     0b01000000, 0b10000000, 0b00000001, 0b00000010,
     0b00000100, 0b00001000, 0b00010000, 0b00100000};
 while(PIND & 0b00100000) {
     for (int i = 7, v = 128; i > -1; --i, v /= 2) {
         if (clickCount >= v && clickCount > 0) {
             if (clickCount >= 4) {
               PORTB = PORTB | mask[i];
             } else {
               PORTD = PORTD | mask[i];
             }
             clickCount -= v;
             break;
         }
     }
 }

或者您可以使用一个循环:

int v = 128, i = 7;
while (v > 0 && (PIND & 0b00100000)) {
    if (clickCount >= v) {
         if (clickCount >= 4) {
           PORTB = PORTB | mask[i];
         } else {
           PORTD = PORTD | mask[i];
         }
        clickCount -= v;
    } else {
        --i;
        v /= 2;
    }
}

答案 1 :(得分:3)

这可以通过仅将值分别分配给PORTB和PORTD来完成,因为您将点击次数存储在变量clickCounter中。

PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);

答案 2 :(得分:1)

要处理输出,我会做类似的事情:

clickCount %= 256; /* because the output is 8-bit */
PORTB = clickCount;

要使输出恰好长1条指令:

unsigned char clickCount = 0;

... /* do things, handle increment, handle 2nd button */

PORTB = clickCount; /* modulo 256 no longer needed, ClickCount cannot be more than 8 bits anyway */

我没有理由一点一点地做。