(分享)在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口进行一组写入数据可以这样:

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口一组数据状态怎么弄?

已邀请:
关于GPIO口的连续读出:

有时候会用到连续读出一组IO口的状态,例如模拟并口的时候.

但是stm32cubemx提供的Hal库是没有这个功能的,怎么办?

可以利用以下代码:
//只获取8位数据
uint8_t Gpio_read_pins(GPIO_TypeDef* GPIOx)
{
uint8_t data;
data = GPIOx->IDR & 0xFF;
return data;
}
以上直接读取IO口状态寄存器.

日日夜夜 - 万年工科狗

赞同来自:

写宏 内联 封装 写C必备三神器

admin

赞同来自: 正南其北哩

刚刚有人告诉我,你读都可以用GPIOx->IDR ,那么向IO写入为何不用GPIOx->ODR ?

都是直接操作寄存器的。呵呵
恩,这个办法不错!
要是这个能用的话,一楼的程序就可以改为:

void GPIO_WRCMD(GPIO_TypeDef* GPIOx,uint16_t cmd)
{
GPIOx->ODR = cmd;
}

这个可真简单了。
就是没测试,有兴趣的同学去测试下呗。。。

admin

赞同来自:

又看了看手册,以前忽略了个变量 GPIO_PIN_All
当需要一次操作全部某端口的io状态使用
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_All,GPIO_PIN_RESET )
但是这个有局限,只能置高或低,不能任意书写

BlackHei - 单身入门IT男

赞同来自:

老弟弱弱的问一个问题:stm32标准库设置指定的数据端口位函数是GPIO_SetBits,那么用cube生成的HAL驱动库怎么表示呢?
HAL_GPIO_WritePin (GPIOC,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3........,PIN_RESET );
这样不就行了嘛?

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寄存器可以在不影响其他引脚的情况下改变某一引脚的电平状态。这是写数据的函数:

  1. void lcd_send(uint8_t data)//以pa0-7为数据输出口

  2. {

  3.         uint32_t dat,uc1;

  4.         data = reverse8(data);

  5.         uc1 = 0;

  6.         dat = (~(uc1|data)<<16) | (uc1|data);

  7.         GPIOA->BSRR = dat;

  8. }


按楼上帖子,将有关代码贴到这里备查。

pkokoc

赞同来自:

正在做类似的,可以参考,非常感谢

落笔一哥

赞同来自:

HAL太不完善了

要回复问题请先登录注册