[应用相关] 论STM32标准库程序修改为HAL库

[复制链接]
1095|18
 楼主| sensitivity 发表于 2020-5-17 10:07 | 显示全部楼层 |阅读模式
标准库占绝大多数,自己买的板子跟的资料也一般是标准库,HAL库很少,不过要是使用STM32CubeMx配置,那么就是使用的HAL库了,而参考资料是标准库的,就没有办法用。
 楼主| sensitivity 发表于 2020-5-17 10:08 | 显示全部楼层
注意:

      1. 标准库与HAL库不兼容,不要想着直接拿来用了,比如标准库使用#include "stm32f10x.h",HAL库使用#include "stm32f1xx_hal.h"
 楼主| sensitivity 发表于 2020-5-17 10:08 | 显示全部楼层
要让标准库程序使用HAL库时也可以正常运行得到想要的结果,有以下几种方法:

      一、 将标准库程序中的每个函数内的代码修改为使用HAL库且同样效果的代码,

              比如标准库中配置GPIO的代码直接就可以用STM32CubeMx配置为相同效果

      二、根据标准库程序整个程序运行的原理使用HAL库中提供的函数实现,

              比如使用IIC写入内存的代码可以使用HAL库中提供的函数HAL_I2C_Mem_Write
实现
 楼主| sensitivity 发表于 2020-5-17 10:09 | 显示全部楼层
先举例介绍第一种方法:

      1. 外部中断

            标准库:中断入口函数在stm32f10x_it.c中,修改void EXTI&_IRQHandler()

                          使用if(EXTI_GetITStatus(EXTI_Line2)==SET)判断是否产生中断

                          处理中断时,要清除中断线路挂起位(EXTI_ClearITPendingBit),以便下次使用

 楼主| sensitivity 发表于 2020-5-17 10:09 | 显示全部楼层
            HAL库:在stm32f1xx_it.c中依然有中断入口函数void EXTI2_IRQHandler(void)

                        该函数调用了HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);,当该引脚产生中断事件时会调用该函数

                        最后会由HAL_GPIO_EXTI_Callback(GPIO_Pin);回调函数执行中断,该函数是可以被重定义的,复制该函数添加到main.c中就可以进行特定引脚的中断事件处理

            在HAL库的回调函数和标准库的中断入口函数中的中断事件执行是差不多的
 楼主| sensitivity 发表于 2020-5-17 10:10 | 显示全部楼层
      2. 引脚操作

          51、STM32的标准库和HAL库对引脚都有基本的读取引脚状态和设置引脚的操作

          51:P0  = 0x00; //置P0口为低电平,P08个IO口全为低电平

                  P0  = 0xff; //置P0口为高电平

                  注意P0有8个IO口,即从P0.0到P0.7,而0x00二进制就是0000 0000,效果就是P0.0到P0.7都是0,即低电平。

                P0 = 0xC8;

                 51可以实现直接将八位二进制直接传递给8个IO口,只需一次传值;也可以单独对某个IO口设置,但HAL库只能一次对一个引脚操作
 楼主| sensitivity 发表于 2020-5-17 10:11 | 显示全部楼层
          标准库:GPIO_SetBits(GPIOC,GPIO_Pin_All);将引脚置1,可以将多个引脚一起设置使用GPIOx->BSRR = GPIO_Pin;

                        GPIO_ResetBits(GPIOC,GPIO_Pin_All);将引脚置0,使用GPIOx->BRR = GPIO_Pin;

                        GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)读取引脚状态
 楼主| sensitivity 发表于 2020-5-17 10:11 | 显示全部楼层
          HAL库:所有GPIO的操作函数在stm32f1xx_hal_gpio.h中,也定义了一些GPIO设置用到的参数

                      具体函数见stm32f1xx_hal_gpio.h,功能和标准库大致相同,有一个引脚反转函数HAL_GPIO_TogglePin
 楼主| sensitivity 发表于 2020-5-17 10:12 | 显示全部楼层
      问题:如何使用HAL库实现向多个引脚写入八位十六进制数据?

       51:cmd = 0xc8;

               PC = cmd;
 楼主| sensitivity 发表于 2020-5-17 10:13 | 显示全部楼层
       HAL库:cmd = 0xc8;

              if(cmd&0x01)

             {

                   HAL_GPIO_WritePin(GPIOC,D0_Pin,GPIO_PIN_SET);

             }

             else

             {

                  HAL_GPIO_WritePin(GPIOC,D0_Pin,GPIO_PIN_RESET);

             }

             if(cmd&0x02)

            {

                  HAL_GPIO_WritePin(GPIOC,D1_Pin,GPIO_PIN_SET);

           }

           else

          {

                   HAL_GPIO_WritePin(GPIOC,D1_Pin,GPIO_PIN_RESET);

          }

         if(cmd&0x04)

        {

             HAL_GPIO_WritePin(GPIOC,D2_Pin,GPIO_PIN_SET);

        }

         else

           {

                 HAL_GPIO_WritePin(GPIOC,D2_Pin,GPIO_PIN_RESET);

           }

           if(cmd&0x08)

          {

                HAL_GPIO_WritePin(GPIOC,D3_Pin,GPIO_PIN_SET);

           }

          else

         {

           HAL_GPIO_WritePin(GPIOC,D3_Pin,GPIO_PIN_RESET);

          }

         if(cmd&0x10)

          {

                  HAL_GPIO_WritePin(GPIOC,D4_Pin,GPIO_PIN_SET);

            }

          else

          {

                HAL_GPIO_WritePin(GPIOC,D4_Pin,GPIO_PIN_RESET);

             }

           if(cmd&0x20)

            {

                      HAL_GPIO_WritePin(GPIOC,D5_Pin,GPIO_PIN_SET);

           }

           else

              {

                 HAL_GPIO_WritePin(GPIOC,D5_Pin,GPIO_PIN_RESET);

                }

           if(cmd&0x40)

          {

               HAL_GPIO_WritePin(GPIOC,D6_Pin,GPIO_PIN_SET);

           }

          else

          {

               HAL_GPIO_WritePin(GPIOC,D6_Pin,GPIO_PIN_RESET);

            }

            if(cmd&0x80)

           {

                 HAL_GPIO_WritePin(GPIOC,D7_Pin,GPIO_PIN_SET);

          }

        else

         {

                HAL_GPIO_WritePin(GPIOC,D7_Pin,GPIO_PIN_RESET);

           }

这个方法比较笨,是使用与运算直接判断八位二进制数据的各位是0还是1,然后设置相应引脚即可。
 楼主| sensitivity 发表于 2020-5-17 10:13 | 显示全部楼层
      3. 直接操作寄存器

            这个在标准库和HAL库中的使用是一样的,

            标准库:例如 #define IIC_SDA_IN()  {GPIOB->CRH &= 0XFFFF0FFF;GPIOB->CRH |= 8 << 12;GPIOB->BSRR = 1 << 11;}

                          其中GPIOB是在stm32f10x.h中定义的,其中BSRR、CRH等是GPIO结构体中的属性,结构体为:

              typedef struct

            {

               __IO uint32_t CRL;

               __IO uint32_t CRH;

               __IO uint32_t IDR;

               __IO uint32_t ODR;

               __IO uint32_t BSRR;

              __IO uint32_t BRR;

              __IO uint32_t LCKR;

            } GPIO_TypeDef;
 楼主| sensitivity 发表于 2020-5-17 10:14 | 显示全部楼层
HAL库:例如  #define        LCD_RST_CLR        GPIOC->BRR=1<<5

              其中GPIOC是在stm32f103xe.h中定义的,BSRR,BRR等GPIO结构体的属性也是在该文件中定义的,具体结构体为:

typedef struct

{

__IO uint32_t CRL;

__IO uint32_t CRH;

__IO uint32_t IDR;

__IO uint32_t ODR;

__IO uint32_t BSRR;

__IO uint32_t BRR;

__IO uint32_t LCKR;

} GPIO_TypeDef;

与标准库的GPIO结构体定义相同。

待续.........
 楼主| sensitivity 发表于 2020-5-17 10:16 | 显示全部楼层
作者:停下浮躁的心
链接:https://www.jianshu.com/p/f13b9e47a4d7
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
qjp1988113 发表于 2020-5-17 10:18 | 显示全部楼层
其实大同小异,你会标准库,HAL库用起来也一样。
xiaoqizi 发表于 2020-6-4 16:57 | 显示全部楼层
非常感谢楼主分享
木木guainv 发表于 2020-6-4 16:58 | 显示全部楼层
这个好像工作量很大
磨砂 发表于 2020-6-4 16:58 | 显示全部楼层
这样改 会牵涉到具体的代码吗
晓伍 发表于 2020-6-4 16:58 | 显示全部楼层
非常的详细
八层楼 发表于 2020-6-4 16:59 | 显示全部楼层
值得参考 收藏一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

216

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部