我的程序有8位注册,即PC0,PC1,PC2,PC3,PC4,PC5,PC6,PC7.
我不关心PC0,PC1,PC2,PC3.
我想根据提到的真值表设置位:
PC4 PC5 PC6 (Ports)
Row1 : 0 0 0
Row2 : 0 0 1
Row3 : 0 1 0
Row4 : 0 1 1
Row5 : 1 0 0
Row6 : 1 0 1
设置位时不应更改PC7状态,应保持不变。我可以单独设置位,但需要立即设置它们。 这就是我所做的:
void Set(unsigned char Row)
{
if(Row == 1)
{
PC_ODR &= ~(0x40) //To Set 0 to PC6
PC_ODR &= ~(0x20) //To Set 0 to PC5
PC_ODR &= ~(0x10) //To Set 0 to PC4
}
if(Row == 2)
{
PC_ODR |= 0x40 //To Set 1 the PC6
PC_ODR &= ~(0x20) //To Set 0 to PC5
PC_ODR &= ~(0x10) //To Set 0 to PC4
}
// ......So on for Row 3, 4,5,6
}
对于所有6行,代码将变得冗长,有没有什么方法可以使用移位运算符和AND / OR运算符来简化事情。
答案 0 :(得分:3)
仔细查看你的真相表并找到一些规则。
void Set(unsigned char Row){
Row --;
PC_ODR &= 0x8F;
PC_ODR |= (0x01 & Row) << 6;
PC_ODR |= (0x02 & Row) << 4;
PC_ODR |= (0x04 & Row) << 2;
}
如果您向Row
提供值7和8,这仍然有效,但如果您提供9或以上的数字,可能会出错。
感谢 0andriy 对代码进行了一些小改进!
答案 1 :(得分:0)
所以你有:
PC654 Decimal
Row1 : 000 0
Row2 : 100 4
Row3 : 010 2
Row4 : 110 6
Row5 : 001 1
Row6 : 101 5
然后使用查找表:
void setRow(int row) {
static int mask = 0x70; // binary mask for bits 456: 1110000
static int rowData[7] = { 0/*dummy entry no row 0*/, 0, 4, 2, 6, 1, 5 };
PC_ODR = (PC_ODR & ~mask) | rowData[row]<<4; // get original bits except 456 and combine with right value for 456
}
注意:不确定变量的类型,但您可以轻松适应。
答案 2 :(得分:-1)
从这里选择任何8位反转方法:http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious并将其包装到reverse()
中,然后使用:
假设基于0的行索引(第1行= 0)
PC_ODR |= (0xf | (reverse(row) >> 1))
否则需要基于1的行索引(第1行= 1)
PC_ODR |= (0xf | (reverse(row - 1) >> 1))