单片机C语言程序设计中的位操作_第1页
单片机C语言程序设计中的位操作_第2页
单片机C语言程序设计中的位操作_第3页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、动手学AVR单片机十二、AVR单片机C语言程序设计中的位操作在标准C语言的的教材中,对于位运算的操作是基本不涉及的,但是在单片机系统的程序中,需要经常操作各类以字节为单位的寄存器,而这些寄存器通常都是以二进制中的位为控制单位的数据组合。往往一个8位寄存器中的每一位都有各自的控制对象,例如端口B的方向寄存器DDRB,如下图所示   它实际上控制着PB口的8个端口PB0-PB7的方向,也就是说它的每一位都控制一个端口的方向,如果我们要把端口PB0-PB3设置为输出口,而把PB4-PB7设置为输入口,在不用位运算符的情况下,我们可以直接使用赋值语句DDRB=0x0f来实现,这样是

2、完全可以实现的。  但是如果出现下面的情况:在程序中PB口的8位端口的状态本来是1、3、5、7为输入。0、2、4、6为输出(即DDRB=0x55),接下来要将PB口的第1位设置为输出,其它端口的状态不变,然后又要将第2位设置为输入,其它端口的状态不变。该怎么实现?也许我们仍然可以使用赋值语句来实现,比如DDRB=0x55;接下来设置DDRB=0x57;然后再设置DDRB=0x53;首先要肯定的是,这种做法是绝对正确的。但是我们可能有没有注意到,在改变其中一位的值的时候,我们同时还要考虑其它7位的状态,并且要小心翼翼的避免不小心改变了其它位的值。  那么有

3、没有一种方法,可以简单的实现修改某一位的状态,同时不会改变其它位的状态呢?  这就牵出了单片机C语言程序设计中的位运算的概念。  我们来看这个语句:DDRE |= (1 << PE5);   这个语句实现的功能是将PE口的第5位设置为输出口,其余口的状态不变。它是怎么实现的?首先我们来看1 << PE5这个表达式,我们前面已经介绍了,AVR各寄存器的宏定义是在头文件io.h中定义好的,我们可以直接调用,现在我们就来看看在io.h中PE5是如何定义的(在WINAVR的安装目录下查找iom64.h),我们可以看到P

4、E口的8位分别定义如下:/* Port E Data Register - PORTE */#define    PE7       7#define    PE6       6#define    PE5       5#define    PE4    

5、   4#define    PE3       3#define    PE2       2#define    PE1       1#define    PE0       0   

6、可以看出,实际上PE5=5;那么1 << PE5,就很容易理解了,它的作用是把1左移5位,最后的结果按照二进制表示就是0b00100000,而DDRE |= (1 << PE5);实际上是DDRE= DDRE | (1 << PE5);首先“|”表示的是“或”操作DDRE是端口E的方向寄存器,在iom64.h中定义为:#define DDRE      _SFR_IO8(0x02);它实际上是定义了一个标识符,这个标识符对应数据存储区RAM中的某个地址,这个我们暂且不去深究。我们还是回过头来看DDRE= DD

7、RE | (1 << PE5);这句话实现的功能,这句话实际上是将寄存器DDRE中的内容(数据)跟二进制数0b00100000进行或操作,我们知道两个数的或操作的结果是:只要有一个是1,结果就是1.那么假如DDRE中本来的值是0b10001010(0x8a),它和0b00100000进行“或”操作以后的结果变成了0b10101010(0xaa)。我们可以看出,相或以后DDRE中的第5位以外的各位的值都没有改变,而第5位变成了1,我们的目的就是要将第5位设为输出口(即将第5位设置为1)。   现在我们来看一下从语言中有几种位运算符:移位运算符:左移<

8、;<,右移>>与运算符:&或运算符:|取反运算符:异或运算符:     就这些了,总共只有6中位运算符。现在我们来看一下这些运算符都起什么作用;左移运算符:表达形式为x<<n,意思是将数据x向左移动n位,在这里x和n都必须是无符号整形数据(所有的位运算符的操作对象都是无符号整形);     例如,x是一个unsigned char类型的数据(即x是一个单字节数据,共有8位),设x的初值为0x00000001,执行x<<n的操作:n=0时,x<<n表示x左

9、移0位,实际就是不移动,x的值不改变n=1时,x<<n表示x左移1位,运算结果为0b00000010n=2时,x<<n表示x左移2位,运算结果为0b00000100.n=7时,x<<n表示x左移7位,运算结果为0b10000000n=8时,x<<n表示x左移8位,运算结果为0b00000000      从结果来看,当n在1-7之间取值时,运算的结果总是1依次向左移动一位,但是当n>=8以后,x的值就一直是0了,这是因为x是一个只有8位的整形变量,它的最大二进制长度是8位,当n超过8以后,移

10、位操作的结果已经超出8位的范围了,产生了溢出现象。       右移的原理跟左移相似,只是它的运算结果跟左移刚好相反。      在单片机C语言编程中,经常使用移位操作来实现将数据乘以(左移)或除以(右移)2的n次方的乘除运算,利用移位操作实现乘除运算可以显著提高单片机的运算速度和效率。其详细原理我们可以翻阅相关的C语言书籍来进行更深了解。      “取反”、“与”、“或”、“非”运算经常用于对寄存器的某一位进行操作,例如,使端口B的

11、第二位输出高电平,同时不改变其余端口的状态,我们可以采用如下方法:PORTB |= (1<<PB2),         实际上,想将一个8位寄存器的某一位设置为1,可以采用这样的语句:寄存器名(如PORTB) |= (1 << X),式中X表示第X位。        相反的,如果想将一个8位寄存器的某一位设置为0,可以采用这样的语句:寄存器名(如PORTB) &= (1 << X),式中X表示第X位。        写着的时候,总感觉心里清楚,但是表达不出来,本来是相结合单片机来

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论