修改控制寄存器GPBCON

来源:互联网 发布:salk institute知乎 编辑:程序博客网 时间:2024/06/06 04:16

修改控制寄存器GPBCON

C++的程序看着有些晕,恶补之,哪里不明白查哪里,学了不少知识,抄到下面。

1<<2代表1左移2位
1>>2代表1右移2位
这两个都是用二进制来算的

s2440IOP->rGPBCON = (s2440IOP->rGPBCON &~(3 << 10)) | (1<< 10);
以上这句话的意思是,把GPBCON寄存器第10和11位清零,其他位不变,再把第10位置1,这样就把GPB5的状态改成输出了。
具体运算这样进行,3<<10是0000 1100 0000 0000,~之后就变成1111 0011 1111 1111,这样再与GPBCON的值相与后,GPBCON中的10和11位变0,其他位的值不变,然后再|(1<<10),也就是第10位置1,看是看明白了,不过不明白的是为什么要搞得这么复杂,有什么意义?可能这样做不会改变GPBCON中其他位的值,这是好处。还有个不明白的地方,为什么要用指针呢?这个有什么好处?

 

以上摘自网络,作者不详。

 

我想看了leddriver里的代码就知道为什么这么写了。

/*GPBCON Init*/

s2440IOP->rGPBCON  = (s2440IOP->rGPBCON  &~(3 << 10)) | (1<< 10); // GPB5 == OUTPUT.
 s2440IOP->rGPBCON  = (s2440IOP->rGPBCON  &~(3 << 12)) | (1<< 12); // GPB6 == OUTPUT.
 s2440IOP->rGPBCON  = (s2440IOP->rGPBCON  &~(3 << 14)) | (1<< 14); // GPB7 == OUTPUT.
 s2440IOP->rGPBCON  = (s2440IOP->rGPBCON  &~(3 << 16)) | (1<< 16); // GPB8 == OUTPUT.

 

/*GPBDAT*/

s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<5);
  break;
 case IO_CTL_LED_2_ON:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<6);
  break;
 case IO_CTL_LED_3_ON:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<7);
  break;
 case IO_CTL_LED_4_ON:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0x1<<8);
  break;
 case IO_CTL_LED_ALL_ON:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT&~(0xF<<5);
  break;
 case IO_CTL_LED_1_OFF:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<5);
  break;
 case IO_CTL_LED_2_OFF:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<6);
  break;
 case IO_CTL_LED_3_OFF:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<7);
  break;
 case IO_CTL_LED_4_OFF:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0x1<<8);
  break;
 case IO_CTL_LED_ALL_OFF:
  s2440IOP->rGPBDAT=s2440IOP->rGPBDAT|(0xF<<5);