




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言编程开发中用好位操作符1. C语言中的位操作符因为C语言的设计目的是取代汇编语言,所以它必须支持汇编语言所具有的运算能力,所以C语言支持全部的位操作符(Bitwise Operators)。位操作是对字节或字中的位(bit)进行测试、置位或移位处理,在对微处理器的编程中,特别适合对寄存器、I/O端口进行操作。因而本节将对此作比较详细地介绍。6种位操作符的形式与含义如下:& :按位“与”(AND);| :按位“或”(OR); :按位“异或”(XOR); :“取反” (NOT); :数据右移; 将变量的各位按要求向右移动若干位。右移语句的通常形式是:variable 右移位数如:a = 1111 0000;进行 a = a 2 操作后,a = 0011 1100。6) 数据左移数据左移操作符 将变量的各位按要求向左移动若干位。左移语句的通常形式是:variable 左移位数如:a = 1111 0000;进行 a = a 2 操作后,a =1100 0000。无论是左移还是右移,当某位从一端移出时,另一端出现的空白将以从外面移入的0(某些计算机是送1,详细内容请查阅相应C编译程序用户手册)来补充。这说明,移位不同于循环,从一端移出的位并不送回到另一端去,移去的位永远丢失了,同时在另一端只能补上相应位数的0。移位操作可用于整数的快速乘除运算,左移一位等效于乘2,而右移一位等效于除以2。如:x = 7, 二进制表达为:0000 0111,x 1 0000 1110,相当于: x =2*7=14,x 3 0111 0000,相当于: x=14*2*2*2=112x 2 0011 0000, x=48x 3 0000 0110 x=48/8=6x 1 0000 0011 x=6/2=3移位操作还可以配合其它位操作夫对寄存器或者数据I/O接口的各个位进行设置、检测,具体方法见下一节。 2.位操作符的一些实用方法介绍1) 学会应用复合运算符如前面所介绍的,位操作运算符可以和赋值运算符“=”一起组成复合运算符。即如下5个:=、&=、=、|=其中,x = y,相当于x = x = y,相当于x = x y;x & = y, 相当于x = x & y;x = y, 相当于x = x y;x | = y, 相当于x = x | y;学会在C语言中使用复合运算符,可以简化源程序,优化目标程序。2) C 语言中一些常见的位操作方法由于我们此处学习C 语言的目的主要是为了开发微控制器的控制程序,为此我们特别关注一下对MPU的寄存器、I/O中某一位的操作语句。假如要对PORTA(端口A)的某些位进行赋值、置0、置1、取反、测试,可能会用到如一下一些语句: PORTA = 0x87给整个PORTA赋值,作用是将1000 0111这个数赋予PORTA,即让PORTA的第0、1、2和7位置1,其它位清0。 PORTA = (17) 给整个PORTA赋值,作用等价于PORTA = 0x80,将1000 0000这个数赋予PORTA,将指定的第7位置1,其余各位置0。只不过这里包括了两个步骤,即先是括号中的17操作,表示将0x01这个数左移7位,其值变成0x80,再将它赋予PORTA。 PORTA = (17) | (1 3) | (1 2)给整个PORTA赋值,作用与中的操作相同,但是是分别对7、3、2位置1,而将其它各位均置0。它先要分别对三个括号中给定的值进行移位操作,再将它们按位“与”,最后将值赋予PORTA。即: 1000 0000 (1 7) 0000 1000 (1 3) | 0000 0100 (1 2) PORTA = 1000 1100 PORTA & = 0x80使PORTA中的指定位清0,等价于PORTA =PORTA & (0x80)。由于0x80的二进制表达形式为1000 0000,利用其最高位为1,其它各位均为0的特性,作为一个模板将其等于1的那些位(如本例中的第7位)屏蔽起来,使之保持不变,而将其它位清0(不管原来为0还是为1)。因为PORTA与0x80按位“与”的结果如下:PORTA = 0x87 1000 0111& 0x80 1000 0000 = 1000 0000操作后,第7位的原来值1被保留,其它各个位被清0,其中最低的3位原来为1,现在均为0了。 PORTA & = (17)它也等价于PORTA & = 0x80:这里也包括了两个步骤,即先执行括号中的17操作,将0x01左移7位,其值变成0x80,再将它与PORTA做按位“与”。该操作将除指定的第7位以外的各个位清0。PORTA & = (1 7)该指令在等号后面加了取反符号 。与上一条操作的区别是,在与PORTA做按位“与”前,还将0x80先行取反,将1000 0000转换成0111 1111,再做按位“与”操作。这样的操作结果是将指定的第7位清零,其它各位保持不变。 PORTA | = (17)等价于PORTA = PORTA | (17),这里也是先执行括号中的17操作,将0x01左移7位,其值变成0x80,再将它与PORTA做按位“或”。若操作前PORTA的初始值为0x07,则: PORTA 0000 0111| 0x80 1000 0000PORTA = 1000 0111该操作将最高位置1,其它各位保持不变。要注意的是,这条指令与PORTA = (17) 相比,虽然都可以使指定的某一位置1,但它们有着不同之处。PORTA = (17) 执行后,虽然某一位被置1了,但其它的位却被修改了,即不管PORTA的初始值为什么,原来为1的位都会被0覆盖,执行的结果总是为1000 0000。而本条指令却可以将其它位屏蔽起来,在改变要设置的那一位的同时,并不改变其它位的状态。3) 巧用C语言中的位操作方法 将寄存器的指定位置1或清0在实际应用中,经常利用:PORTA | = (1 n) 这条指令将寄存器的任意位置1,而又不影响其它位的现有状态。比如说,你如果想将第4位置1,就使用:PORTA | = (1 4) 就行了。当然,也可以使用:PORTA | = (1 7) | (1 4 ) | (1 0) 这样的指令一次将设第8、5和1位置1,但又不影响到其它位的状态。在实际应用中,经常利用:PORTA & = (1 n) 这条指令将寄存器的任意位清0,而又不影响其它位的现有状态。比如说,你如果想将第4位清0,就使用:PORTA & = (1 4) 就行了。在启动nRF905芯片向空中发送数据时,采用以下函数:/* ShockBurst 发射数据 */void nrf905_TxSend(void) PORTD|=(110us PORTD &= (1TRXCE);其中让PORTD中控制TRX_CE信号的那一位先置1,再清0,输出一高一低的脉冲信号,就在一个脉冲周期内,完成了一次数据发送。因为在程序的开头已经定义TRX_CE信号为PD6位,即TRXCE = 6,因而上面两行程序等价于:PORTD|=(1 6);PORTD &= (1 6); 测试寄存器指定位的状态nRF905在接收数据过程中,要分别发出CD、AM和DR信号,而MPU也要分别对这些位进行检测,看它们是否变高,若变高,就执行下一步,否则就跳出分支,返回主程序。下面就是对这些位进行检测的一段函数:/*检查接收情况*/ void nrf905_RxRecv(void) while (PIND&(1CD)=0); /CD引脚置1,检测到载波信号 while (PIND&(1AM)=0); /一般先AM=1指示地址匹配对 while (PIND&(1DR)=0); /DR=1时表示数据接收对而且Crc正确 /nrf905已经接收到数据 nrf905_ReadData(0);/读出nrf905中的数据其中有:while (PIND&(1DR)= =0); 或者:if (PIND&(1DR)= =0); 语句,其功能就是对寄存器指定的位进行测试。括号中是一个等式,我们将其拆分开介绍它的作用:1DR:DR在程序的开始已经被定义为2,(1DR)也就是(1 2),表示将0x01左移2位,结果为0000 0100;PIND& (1DR):PIND为PORTD端口的8位引脚的值,PIND& (1DR)表示让它和(1DR) 亦即和0000 0100按位相“与”。不管PIND的其它位为何值,由于和0相与,这些位的结果都为0,我们关心的只有第2位的状态。由于该位与1相与,只要DR为高,就会有: PIND xxx x1xx& 0000 0100 结果
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论