单击计数器以使用 C 代码点亮 LED
click counter to light up LEDs using C code
我正在为微控制器设计点击计数器,我正在使用 C 来开发代码。
这里发生的是当我点击第一个按钮时它会计算按钮按下的次数。然后我必须按下第二个按钮以二进制显示点亮 LED 的计数。例如,如果我按第一个按钮 10 次,它将点亮第二个 LED 和第四个 LED。
因为有 8 个 LED,我使用了 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循环或任何其他方法来开发这段代码?
我不知道这是否减少了二进制大小,并且没有测试过。您仍然可以这样做:
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;
}
}
为了处理输出,我会做类似的事情:
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 */
一点一点地做,我看不出有什么理由。
这可以通过分别为 PORTB 和 PORTD 分配值来完成,因为您将点击次数存储在 variable-clickCounter。
PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);
我正在为微控制器设计点击计数器,我正在使用 C 来开发代码。
这里发生的是当我点击第一个按钮时它会计算按钮按下的次数。然后我必须按下第二个按钮以二进制显示点亮 LED 的计数。例如,如果我按第一个按钮 10 次,它将点亮第二个 LED 和第四个 LED。
因为有 8 个 LED,我使用了 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循环或任何其他方法来开发这段代码?
我不知道这是否减少了二进制大小,并且没有测试过。您仍然可以这样做:
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;
}
}
为了处理输出,我会做类似的事情:
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 */
一点一点地做,我看不出有什么理由。
这可以通过分别为 PORTB 和 PORTD 分配值来完成,因为您将点击次数存储在 variable-clickCounter。
PORTB = PORTB | (clickCount & 0b00111111);
PORTD = PORTD | (clickCount & 0b11000000);