软件one pin错误是啥意思_软件菜鸟扫盲01 之 GPIO Register移位运算

研究了一整晚,终于搞明白了一点东西。谨以此文献给像我一样彻头彻尾的软件门外汉。。。们

如果我文中描述有错误,欢迎各路神仙指正

*******************************************************

范例 MCU: Atmega328p

关于GPIO的设置,我们经常看见这样的语法

DDRB |= (1 << DDB4);

PORTB |= (1 << PORTB4);

PORTB &= ~(1 << PORTB4);

啥意思?

首先是要看datasheet (Atmega328p)

93f4b1d11071686af97c57ae9ca79d48.png

DDRB,PORTB,这些看上去是一些普通的变量,实际上在avr/iom328p.h头文件里面都已经被宏定义了

#define DDRB _SFRIO(0x04)

也就是说, DDRB其实就是阿拉伯数字0x04(16进制),表示SRAM地址0x04,也就是Atmega328p芯片PortB端口(共8个)的GPIO方向设置register

DDRB |= (1<<DDB4); 这一行简单的代码,其实有多重意思

意思一:PortB这8个端口的第五个,即DDB4,无论它原来的状态如何,它都要被写入1,即为output

意思二:PortB除了DDB4的其他7个端口的方向,维持原来的状态不变(这一点非常重要)

那么这个变量赋值语法是怎么用一行完成的

  1. 在C语言里面 DDRB |= (1<<DDB4) 可以等效表达成 DDRB = DDRB | (1<<DDB4),意思是新DDRB的值 等于原来的DDRB"或" (1<<DDB4)的值
  2. DDB4是什么?DDB4 其实也是被iom328p.h 里面宏定义了#define DDB4 4,其实DDB4就是阿拉伯数字4,所以(1<<DDB4) 在这里和 (1<<4)是一个意思
  3. 那(1<<DDB4) 或者说 (1<<4) 又是什么鬼?这其实是一个移位语法,我们把这个"1"换算成8位二进制数字,1即 0000 0001,1<<4就表示0000 0001 往"左"挪4位,结果就0000 0001就变成了 0001 0000,我们现在仔细看,新的值0001 0000 里面的这个"1"处于哪个位置,是不是正好是DDRB这个8位register,从右(低位)往左(高位)数,第五个(如下图),它是不是正好就是DDB4的位置?

2777ced813c52ee8f0a6798ade422ff0.png

这也意味着,1<<4就变了 0001 0000,把这个新的值带入到上面的变量赋值

DDRB | (1<< 4) 就变成了 DDRB | 0001 0000

现在我们把DDRB 也换算成一个8bit的二进制,xxxx xxxx

"x"表示原来的状态,无论是0还是1,通过逻辑门"或"上一个0,还是x,即状态不改变,"或"上一个1,即状态一定被改变成1

那么新的DDRB的值就变成了 xxx1 xxxx

现在大家懂了吗,通过DDRB |= (1<<4),这样一个巧妙的移位,把DDRB的第5个bit(即DDB4)变成了1,而其他bit维持原状态不变,即PORTB上的第5个PIN被设置成output,其他的PIN保持原状态不变

同理,PORTB |= (1 << PORTB4); 表示,PORTB上的PORTB4号pin被强制输出HIGH,其他pin维持原状态不变

最后,PORTB &= ~(1 << PORTB4); 这个语法和上边的"或"门正好相反

利用"与门" 符号 &,还有"非门"符号 ~,利用相同的移位原理,把PORTB上的第5个pin,即PORTB4强制变成LOW,而其他的pin维持原状不变

简单来说,如果不用汇编,刚才那样的移位应该来说是效率最高的语法了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值