您的位置 首页 培训

AVR单片机C言语程序设计中的位操作

在标准C语言的的教材中,对于位运算的操作是基本不涉及的,但是在单片机系统的程序中,需要经常操作各类以字节为单位的寄存器,而这些寄存…

在规范C言语的的教材中,关于位运算的操作是基本不触及的,可是在单片机体系的程序中,需求常常操作各类以字节为单位的寄存器,而这些寄存器一般都是以二进制中的位为操控单位的数据组合。往往一个8位寄存器中的每一位都有各自的操控目标,例如端口B的方向寄存器DDRB,如下图所示

它实践上操控着PB口的8个端口PB0-PB7的方向,也便是说它的每一位都操控一个端口的方向,假设咱们要把端口PB0-PB3设置为输出口,而把PB4-PB7设置为输进口,在不必位运算符的状况下,咱们能够直接运用赋值查办DDRB=0x0f来完成,这样是完全能够完成的。
可是假设呈现下面的状况:在程序中PB口的8位端口的状况原本是1、3、5、7为输入。0、2、4、6为输出(即DDRB=0x55),接下来要将PB口的第1位设置为输出,其它端口的状况不变,然后又要将第2位设置为输入,其它端口的状况不变。该怎样完成?惹祸咱们依然能够运用赋值查办来完成,比方DDRB=0x55;接下来设置DDRB=0x57;然后再设置DDRB=0x53;首要要必定的是,这种做法是肯定正确的。可是咱们或许有没有注意到,在改动其间一位的值的时分,咱们一起还要考虑其它7位的状况,而且要小心谨慎的防止不小心改动了其它位的值。
那么有没有一种方法,能够简略的完成修正某一位的状况,一起不会改动其它位的状况呢?
这就牵出了单片机C言语程序设计中的位运算的概念。
咱们来看这个查办:DDRE |= (1 << PE5); 这个查办完成的功用是将PE口的第5位设置为输出口,其他口的状况不变。它是怎样完成的?首要咱们来看1 << PE5这个表达式,咱们前面现已介绍了,AVR各寄存器的宏界说是在头文件io.h中界说好的,咱们能够直接调用,现在

咱们就来看看在io.h中PE5是怎么界说的(在WINAVR的装置目录下查找iom64.h),咱们能够看到PE口的8位别离界说如下:
/* Port E Data Register – PORTE */
#define PE7 7
#define PE6 6
#define PE5 5
#define PE4 4
#define PE3 3
#define PE2 2
#define PE1 1
#define PE0 0
能够看出,实践上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= DDRE | (1 << PE5);这句话完成的功用,这句话实践上是将寄存器DDRE中的内容(数据)跟二进制数0b00100000进行或操作,咱们知道两个数的或操作的成果是:只需有一个是1,成果便是1.那么假设DDRE中原本的值是0b10001010(0x8a),它和0b00100000进行“或”操作今后的成果变成了0b10101010(0xaa)。咱们能够看出,相或今后DDRE中的第5位以外的各位的值都没有改动,而第5位变成了1,咱们的意图便是要将第5位设为输出口(行将第5位设置为1)。
现在咱们来看一下从言语中有几种位运算符:
移位运算符:左移<<,右移>>
与运算符:&
或运算符:|
取反运算符:~
异或运算符:^
就这些了,一共只要6种位运算符。现在咱们来看一下这些运算符都起什么效果;
左移运算符:表达形式为x< 例如,x是一个unsigned char类型的数据(即x是一个单字节数据,共有8位),设x的初值为0x00000001,碑文x<n=0时,x<n=1时,x<n=2时,x<
n=7时,x<n=8时,x< 从成果来看,当n在1-7之间取值时,运算的成果总是1顺次向左移动一位,可是当n>=8今后,x的值就一直是0了,这是由于x是一个只要8位的整形变量,它的最大二进制长度是8位,当n超越8今后,移位操作的成果现已超出8位的范围了,产生了溢呈现象。
右移的原理跟左移类似,仅仅它的运算成果跟左移刚好相反。
在单片机C言语编程中,常常运用移位操作来完成将数据乘以(左移)或除以(右移)2的n次方的乘除运算,使用移位操作完成乘除运算能够明显进步单片机的运算速度和功率。其详细原理咱们能够翻阅相关的C言语书本来进行更深了解。
“取反”、“与”、“或”、“非”运算常常用于对寄存器的某一位进行操作,
例如,使端口B的第二位输出高电平,一起不改动其他端口的状况,咱们能够选用如下方法:
PORTB |= (1<实践上,想将一个8位寄存器的某一位设置为1,能够选用这样的查办:寄存器名(如PORTB) |= (1 << X),式中X一共第X位。
相反的,假设想将一个8位寄存器的某一位设置为0,能够选用这样的查办:寄存器名(如PORTB) &= ~(1 << X),式中X一共第X位。

写着的时分,总感觉心里清楚,可是表达不出来,原本是想结合单片机来解说怎么用C言语来开发单片机程序的,但总是没有方法将两者的结合很直观的表达出来。有些困惑!
这或许便是现在市面上相当多的解说单片机C言语开发的书为什么总是将C言语的解说和详细的程序设计分隔来讲的原因吧。我们都没有更好的方法在解说详细的单片机开发的一起把C言语的常识逐渐融合到实例中

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/peixun/263980.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部