我需要将PORTC设置为通过一堆if语句修改的临时变量,但是分配给PORTC的位序列在最后都为零,因此我假设if语句中的所有表达式均未求值为true时,我测试位序列是否小于或等于十六进制。
#include <avr/io.h>
unsigned char GetBit(unsigned char x, unsigned char k) {
return ((x & (0x01 << k)) != 0);
}
unsigned char SetBit(unsigned char x, unsigned char k, unsigned char b) {
return (b ? x | (0x01 << k) : x & ~(0x01 << k));
}
int main(void)
{
/* Replace with your application code */
DDRA = 0x00; PORTA = 0x0F;
DDRC = 0xFF; PORTC = 0x00;
unsigned char tmpa = 0x00;
unsigned char tmpc = 0x00;
tmpa = tmpa | PORTA;
tmpc = tmpc | PORTC;
while (1)
{
if (tmpa <= 0x02) //less than or equal to 2
{
SetBit(tmpc, 5, 1);
SetBit(tmpc, 6, 1);
}
if (tmpa <= 0x04) //less than or equal to 4
{
SetBit(tmpc, 4, 1);
SetBit(tmpc, 6, 1);
}
if (tmpa <= 0x06) //less than or equal to 6
SetBit(tmpc, 3, 1);
if (tmpa <= 0x09) //less than or equal to 9
SetBit(tmpc,2,1);
if (tmpa <= 0x0C)
SetBit(tmpc,1,1); //less than or equal to 12
if (tmpa <= 0x0F)
SetBit(tmpc,0,1); //less than or equal to 15
PORTC = PORTC | tmpc; ////////PORTC ends up being all zeros
asm("break");
}
}
答案 0 :(得分:3)
问题是SetBit
的返回值被丢弃了。
尝试按以下方式更改对此函数的调用:
SetBit(tmpc,0,1); //less than or equal to 15
到
tmpc = SetBit(tmpc,0,1); //less than or equal to 15
答案 1 :(得分:2)
您可以对十六进制值完全使用逻辑运算符。表示形式是二进制,十六进制还是十进制都没有区别。对于您的编译器,它是8位值。
关于您的示例:
tmpa为0x0F,因此只有在条件经过验证的情况下才最后执行。在此行,tmpc等于0x00(初始化后)。通过SetBit(tmpc,0,1))
时,条件的值为真(b = 1),函数将返回x | (0x01 << k
,在这种情况下,该值等于0x01。
tmpc最后等于0x00(其初始值),因为您没有将其分配给SetBit函数的返回值!
试试这个:
if (tmpa <= 0x0F)
tmpc = SetBit(tmpc,0,1); //less than or equal to 15
答案 2 :(得分:2)
是的,您可以使用逻辑运算符,但是此代码不必要地缓慢且复杂。您不需要分支或比较,只需要一个具有16个值的查找表即可。
const uint8_t VAL [0x10] =
{
[0x00] = 1u<<5 | 1u<<6,
[0x01] = 1u<<5 | 1u<<6,
[0x02] = 1u<<5 | 1u<<6,
[0x03] = 1u<<4 | 1u<<6,
[0x04] = 1u<<4 | 1u<<6,
// ... up to 0x0F
};
tmpc = VAL[tmpa & 0xF];