打印

STM32GPIO位操作取反问题(关于~操作符)

[复制链接]
23119|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fengxt27|  楼主 | 2013-3-29 09:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,小弟最近在学习STM32,遇到一个问题,向各位大虾请教。
对GPIO某位取反,小弟是这么写的
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction) ~GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0));
但是PA0口一直是高电平,不能取反。
但是如果写成这样
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction) !GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0));或
GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction) (1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0)));
就可以实现,而且如果写成这样
GPIO_Write(GPIOA, ~GPIO_ReadOutputData(GPIOA))
也是可以实现的。
那么我就想问了,既然“~”是按位取反操作符,而且对整个PortA口操作就可以实现,为什么第一种写法对某一位就不能实现呢?

相关帖子

沙发
huangxz| | 2013-3-29 10:59 | 只看该作者
楼主仔细看下这几个操作函数(宏),尤其是这些返回值和传递参数的类型,你就可以明白了,反正我觉的stm32的库写的n恐怖,我自己一般都是直接操作寄存器,不要用他的那个库。

使用特权

评论回复
板凳
fengxt27|  楼主 | 2013-3-31 16:13 | 只看该作者
huangxz 发表于 2013-3-29 10:59
楼主仔细看下这几个操作函数(宏),尤其是这些返回值和传递参数的类型,你就可以明白了,反正我觉的stm32的库 ...

谢谢这位大虾,经指点小弟想了想,现在把我的想法写下来,大虾看看我想的是否正确,同时也分享下我的想法
我认为主要是在BitAction定义的原因。BitAction定义如下
typedef enum
{ Bit_RESET = 0,
  Bit_SET
}BitAction;
当定义了某个数据为BitAction类型时(如BitAction Value),当进行强制数据转换时,所有非0的数据均转换为Bit_SET
而“~”操作符是按位取反,GPIO_ReadOutputDataBit()的返回类型时U8,即当端口输出为1时返回值为0x01,为0时返回值为0x00。取反之后高低电平分别为0xfe和0xff,在进行转换数据类型之后就全都为Bit_SET类型。
而GPIO_WriteBit()定义当输入为非Bit_RESET时输出为低电平,否则为高电平,所以就全部都输出高电平了。IO口也就不能翻转了。
而剩下的方法,按上述的观点看也是可以行得通的。

使用特权

评论回复
地板
csq463276932| | 2013-6-14 16:30 | 只看该作者
                GPIO_WriteBit(GPIOE,GPIO_Pin_0,(BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_0))));

使用特权

评论回复
5
aiohu| | 2015-10-30 21:12 | 只看该作者
可以这样理解  ReadOutputDataBit(GPIOE,GPIO_Pin_0)是读GPIOE口的0位值,返回值是8位 的  0x00或0x01.该函数的前面 BitAction是枚举变量,是要把非0、1的量变为1、0.他的前面函数是GPIO_Write(GPIOE,GPIO_Pin_0),就是把BitAction的返回值付给GPIOE的0口

使用特权

评论回复
6
西街耳呦| | 2016-7-21 14:57 | 只看该作者
可以用异或操作么

使用特权

评论回复
7
jianeee| | 2016-11-3 10:28 | 只看该作者
GPIOB->ODR ^= GPIO_Pin_14;//led D3,PB14上的LED反转

使用特权

评论回复
8
刘纯胜| | 2017-4-18 17:14 | 只看该作者
#define LED0_Read  HAL_GPIO_ReadPin(LED0_GPIO_Port,LED0_Pin)  //读LED0状态
#define LED0_ON    HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin, GPIO_PIN_RESET)  //开LED0
#define LED0_OFF   HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin, GPIO_PIN_SET)  //关LED0

if(LED0_Read == 1)
                        {
                                LED0_ON;
                        }
                        else
                                LED0_OFF;

使用特权

评论回复
9
changwan1| | 2017-4-27 11:45 | 只看该作者
受教了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

17

帖子

2

粉丝