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?
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;
}
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With