нажмите счетчик, чтобы зажечь светодиоды с помощью кода C - PullRequest
0 голосов
/ 03 ноября 2018

Я разрабатываю счетчик кликов для микроконтроллера и использую C для разработки кода.

Что происходит здесь, когда я нажимаю первую кнопку, она подсчитывает количество нажатий кнопок. Затем я должен нажать вторую кнопку, чтобы отобразить счетчик в двоичном коде с подсветкой светодиодов. Например, если я нажму первую кнопку 10 раз, загорится второй светодиод и четвертый светодиод.

Поскольку имеется 8 светодиодов, я использую 2 разных порта . (6 бит из PORTB и 2 бита из PORTD). Для этого я разработал код, использующий 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 голосов
/ 24 мая 2019

Чтобы обработать вывод, я бы сделал что-то вроде:

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

Чтобы вывод выводился ровно на одну инструкцию:

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 */

Не вижу смысла делать это постепенно.

0 голосов
/ 24 мая 2019

Это можно сделать, просто присваивая значения PORTB и PORTD по отдельности, поскольку в переменной-clickCounter хранится количество щелчков.

PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);
0 голосов
/ 03 ноября 2018

Не знаю, уменьшает ли это размер бинарного файла, и не проверялось. Вы все еще можете сделать что-то вроде этого:

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