(分享)在Cube的Hal库做IO口的GPIO组处理方法!一次操作读写多IO端口方法
首先stm32CUbe的Hal库没有对IO口的组处理了......
那么有时候用到需要对一组IO口,怎么进行操作呢?
最简单最傻瓜的办法是类似下面的:
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_0,GPIO_PIN_SET );
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_1,GPIO_PIN_SET );
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_2,GPIO_PIN_RESET );
.
.
.
等等,
效率低先不说,看着都蛋疼,
还有弊端,就是必须知道我要把那个口驱动的电平知道...
加入模拟并口操作传输数据怎么办?
对IO口进行一组写入数据可以这样:
但是这样也是很傻逼的方法,直接操作寄存器一次写完,省了多少时间啊。。。
所以改成下面函数方法:
但是上面的是针对连续的操作,要是不连续的操作呢?
上面的办法是利用Hal库提供的办法,
楼下继续,读入IO口一组数据状态怎么弄?
那么有时候用到需要对一组IO口,怎么进行操作呢?
最简单最傻瓜的办法是类似下面的:
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_0,GPIO_PIN_SET );
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_1,GPIO_PIN_SET );
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_2,GPIO_PIN_RESET );
.
.
.
等等,
效率低先不说,看着都蛋疼,
还有弊端,就是必须知道我要把那个口驱动的电平知道...
加入模拟并口操作传输数据怎么办?
对IO口进行一组写入数据可以这样:
void GPIO_WRCMD(uint8_t cmd)}
{
uint8_t pin_cmd;
for(uint8_t i=0;i<8;i++)
{
pin_cmd = (cmd&(1<<i))? 1:0;
HAL_GPIO_WritePin(GPIOC,1<<i,pin_cmd);
}
但是这样也是很傻逼的方法,直接操作寄存器一次写完,省了多少时间啊。。。
所以改成下面函数方法:
void GPIO_WRCMD(GPIO_TypeDef* GPIOx,uint16_t cmd)
{
GPIOx->ODR = cmd;
}
但是上面的是针对连续的操作,要是不连续的操作呢?
上面的办法是利用Hal库提供的办法,
楼下继续,读入IO口一组数据状态怎么弄?
18 个回复
admin
赞同来自: 整个夏天 、a317848058 、xazzh 、kepuple 、(ㅎ‸ㅎ) 、jesse_qiao 、cjqcjq 、ZJT1028更多 »
有时候会用到连续读出一组IO口的状态,例如模拟并口的时候.
但是stm32cubemx提供的Hal库是没有这个功能的,怎么办?
可以利用以下代码:
//只获取8位数据
uint8_t Gpio_read_pins(GPIO_TypeDef* GPIOx)
{
uint8_t data;
data = GPIOx->IDR & 0xFF;
return data;
}
以上直接读取IO口状态寄存器.
日日夜夜 - 万年工科狗
赞同来自:
admin
赞同来自: 正南其北哩
都是直接操作寄存器的。呵呵
恩,这个办法不错!
要是这个能用的话,一楼的程序就可以改为:
这个可真简单了。
就是没测试,有兴趣的同学去测试下呗。。。
admin
赞同来自: 网络孤客
当需要一次操作全部某端口的io状态使用
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_All,GPIO_PIN_RESET )
但是这个有局限,只能置高或低,不能任意书写
BlackHei - 单身入门IT男
赞同来自:
ggrarea
赞同来自: 1001ddgy 、BG4RFF 、mindoff 、jin1419c3 、bf1942 、STLINK 、南风1938 、an308286811更多 »
这样不就行了嘛?
iwxyz
赞同来自:
唉!HAL库操作又退回到寄存器操作了。HAL库还需要完善。
BG4RFF
赞同来自:
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3........,PIN_RESET );
用这个写肯定没问题的,读我也不知道咋搞,高手指教
BG4RFF
赞同来自:
http://bbs.mydigit.cn/read.php?tid=1880806
这个朋友的方法对写不错
admvip73 - 业余中的业余
赞同来自: any012
HAL库函数没有WriteByte函数了,所以需要操作寄存器了。原来标准库函数中是操作ODR寄存器,但是ODR寄存器会影响除数据脚以外的其他引脚,所以更好的方法是操作BSRR寄存器。操作BSRR寄存器可以在不影响其他引脚的情况下改变某一引脚的电平状态。这是写数据的函数:
void lcd_send(uint8_t data)//以pa0-7为数据输出口
{
uint32_t dat,uc1;
data = reverse8(data);
uc1 = 0;
dat = (~(uc1|data)<<16) | (uc1|data);
GPIOA->BSRR = dat;
}
按楼上帖子,将有关代码贴到这里备查。
pkokoc
赞同来自:
正在做类似的,可以参考,非常感谢
落笔一哥
赞同来自:
HAL太不完善了
jesse_qiao
赞同来自:
各位朋友提供的参考都很好,留印备查
凯凯
赞同来自:
有启发,当处理较多的输入输出信号时,可以整体赋值
网络孤客 - 独自一人宅男
赞同来自:
连续16位:
#define GPIO_Write(GPIOx,value) GPIOx->ODR=value;
#define READ_DATA(GPIOx) GPIOx->IDR;
非连续的,我用低8位进行举例
#define GPIO_WriteLow8Bits(GPIOx,value) GPIOx->ODR = ((GPIOx->ODR & 0xFF00) | value);
#define READ_Low8Bits(GPIOx) (uint8_t)(GPIOx->IDR & 0x00FF);
FrankSun
赞同来自:
位带操作 bitband
eetau
赞同来自:
写用BSSR寄存器啊
无量寿经
赞同来自:
楼上都写得好