click counter to light up LEDs using C code
Asked Answered
R

3

5

I'm designing a click counter for a microcontroller and I'm using C for developing the code.

What happens here is when I click first button it will count the number of button presses. Then I have to press the second button to display the count in binary lighting up the LEDs. For example, if I press first button 10 times, it will light up second LED and fourth LED.

Since there are 8 LEDs I'm using 2 different ports.( 6 bits from PORTB and 2 bits from PORTD). For that I have developed a code using if/else.But I want to implement this operation without multiple if/else operations because this method doesn't seem like much efficient.

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

And I want to make this code in less number of bytes. So is there any way to develop this code segment using a for loop or any other method?

Rudy answered 3/11, 2018 at 4:34 Comment(2)
You should update your question, to point out that you actually use 2 ports - last 2 bits are from portD.Basting
Already updated it.Rudy
R
3

This could be done by just assigning values to PORTB and PORTD seperately since you have the number of clicks stored in a variable-clickCounter.

PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);
Rudy answered 24/5, 2019 at 10:10 Comment(0)
I
3

I don't know if this reduces the binary size, and not tested. You can still do something like this:

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

Or you can use a single loop:

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;
    }
}
Ivar answered 3/11, 2018 at 4:52 Comment(2)
Since I am using interrupts to handle the button clicks I will have to change your code.Rudy
Actually you don't need to use if/else or any other loops to implement this.I have mentioned it in my answer below.Rudy
R
3

This could be done by just assigning values to PORTB and PORTD seperately since you have the number of clicks stored in a variable-clickCounter.

PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);
Rudy answered 24/5, 2019 at 10:10 Comment(0)
B
1

To handle the output, I would do something like:

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

To make the output exactly 1 instruction long:

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

I see no reason for doing it bit by bit.

Basting answered 24/5, 2019 at 9:51 Comment(6)
yes, you can seperately assign the values to the ports as you have mentioned here.Rudy
Then you can implement it in 2 simple operations, instead of countless operations. Of course, you need to handle the increment of the conter and the second button additionally.Basting
Here you can only use 1 port.But in my answer we can use different ports as we need.Rudy
When doing embedded work, it is always best to optimize everything which can be optimized. Of course you can even use 8 ports, but it is not worth. It is more worth to alter the hardware design (early enough in the project), rather than finding flexible solutions in software.Basting
Yes sure.But I had used other pins for several other purposes.Rudy
It is in your best interest to change the usage of the pins, in order to have a full port for the output. Otherwise, your answer is the next best answer.Basting

© 2022 - 2024 — McMap. All rights reserved.