快速做一个工程 开始
while (1)
{
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
HAL_Delay(200);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);
}
可以看到按键旁边的卢瑟 红色 2个LED在闪烁 【红外发射的那个灯PC9没有亮起 算了】
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, 0);
while (1)
{
HAL_Delay(200);
}
看到LED都安安静静亮起
第三个参数在改改呢?突然感觉不好 这样没意义 0都亮起 1都熄灭 如何一个亮一个灭?
这个函数不行
需要位带 或者 自己写底层开始自己写吧
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
if (PinState != GPIO_PIN_RESET)
{
GPIOx->BSRR = GPIO_Pin;
}
else
{
GPIOx->BSRR = 0;
}
}
这个函数其实是反向操作的 导致第三个参数只能是0 1其他没有啥意义
我们反过来。
朴树理解:
GPIOB->BSRR = 0x01就是把GPIOB port 0升为高电平
GPIOB->BRR = 0x01就是把GPIOB port 0降为低电平
GPIOB->BSRR = 0x02就是把GPIOB port 1升为高电平
GPIOB->BRR = 0x02就是把GPIOB port 1降为低电平
GPIOB->BSRR = 0x04就是把GPIOB port 2升为高电平
GPIOB->BRR = 0x04就是把GPIOB port 2降为低电平
GPIOB->BSRR = 0x08就是把GPIOB port 3升为高电平
GPIOB->BRR = 0x08就是把GPIOB port 3降为低电平
uint32_t value;
value = GPIOC->BSRR;
value &= ~(0X0180); //清除bit7-8
value |= 0X0100; //维持bit80 而bit7为0
GPIOC->BSRR =value;
while (1)
{
HAL_Delay(200);
}
成功!可以看到一个灯亮起 一个灯熄灭!!
我的思路就是LCD里面那个旧旧的库函数
先读出来-保证别人不干扰清掉我要控制的2个 --给我要控制的2个写0或者1--在写到GPIO中即可
抽一下吧:
while (1)
{
LEDPC78TESTE();
}
uint32_t GReadGPIOOutput(GPIO_TypeDef* GPIOx)
{return GPIOx->BSRR;}
void GWriteGPIOOutput(GPIO_TypeDef* GPIOx,uint32_t value)
{GPIOx->BSRR = value;}
void LEDPC78TESTE(void)
{
uint32_t value ;
value = GReadGPIOOutput(GPIOC);
value &=~0X0180;
GWriteGPIOOutput(GPIOC,value);
HAL_Delay(1000);
value = GReadGPIOOutput(GPIOC);
value |=0X0180;
GWriteGPIOOutput(GPIOC,value);
HAL_Delay(1000);
}
测试效果不好 没有一闪一闪 !!!----------------上面代码完成错误!!!BSRR不可以写0 的 不对!!!!
继续研究:https://zhidao.baidu.com/question/1367120329858878139.html
一般情况下控制控制IO口高低电平就直接控制GPIOx->ODR寄存器即可。
而控制GPIOx->BSRR和GPIOx->BRR就等于间接控制GPIOx->ODR寄存器,
而且手册也说了,BSRR、BRR是只写寄存器,写1有效写0无影响,这是什么意思呢;
就是对BSRR和BRR寄存器写1就是对相应的IO口电平操作,写0的话IO口电平不变,
这样就达到了上面所说的:允许对任何GPIOx进行读、更改的独立访问。
比如我要让GPA0变为高电平,可以有两种做法:
1、GPIOA->ODR|=GPIO_Pin_0;
2、GPIOA->BSRR=GPIO_Pin_0;
比如我要让GPA0变为低电平,可以有两种做法:
1、GPIOA->ODR&=~GPIO_Pin_0;
2、GPIOA->BRR=GPIO_Pin_0;
可以看到都是只改变一个IO口电平的时候,明显第2中方法要更加简单一些。
现在果然成功了!!可以一闪一闪
uint32_t GReadGPIOOutput(GPIO_TypeDef* GPIOx)
{return GPIOx->ODR;}
void GWriteGPIOOutput(GPIO_TypeDef* GPIOx,uint32_t value)
{GPIOx->ODR = value;}
void LEDPC78TESTE(void)
{
uint32_t value ;
value = GReadGPIOOutput(GPIOC);
value &=~0X0180;
GWriteGPIOOutput(GPIOC,value);
HAL_Delay(1000);
value = GReadGPIOOutput(GPIOC);
value |=0X0180;
GWriteGPIOOutput(GPIOC,value);
HAL_Delay(1000);
}
也可以:
void LEDPC78TESTE(void)
{
uint32_t value ;
value = GReadGPIOOutput(GPIOC);
value ^=0X0180;
GWriteGPIOOutput(GPIOC,value);
HAL_Delay(1000);
}
这样直接翻转!
++++++++++++++++mcube补充理解+++++++++++
突然不知道自己写的是什么 在说一次
比如 你看到这样的代码
你的怀疑是
我直接是暴力的=
这样的话我执行后面的语言的时候 会不会干扰前面的语句呢
比如
LCD1602_RS0 GPIOB->BRR = GPIO_Pin_10//0x00000004 //低电平 PB.15
LCD1602_RW0 GPIOB->BRR = GPIO_Pin_9
依次执行上面2句话 不会干扰的
BSRR、BRR是只写寄存器,写1有效写0无影响
就是这样意思