C根据真值表按位运算

时间:2017-07-29 10:32:39

标签: c bit

我的程序有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运算符来简化事情。

3 个答案:

答案 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))