跳转至

HAL库学习

GPIO相关

常用功能

  • 点亮LED

    根据电路确定引脚->初始化系统时钟与GPIOx的时钟->初始化GPIOx->设置对应引脚的高低电平

    设置GPIO的mode为GPIO_Mode_Out_PP

  • 按键

    根据电路确定引脚->初始化系统时钟与GPIOx的时钟->初始化GPIOx->读取电平

    设置引脚为GPIO的输入模式,既不上拉也不下拉(其实是否上拉下拉并无影响)

GPIO类

  • GPIO_InitTypeDef

    HAL库中GPOI的初始化类型

    包括Pin,Mode,Pull,Speed

    工作模式mode定义

    注意,这里的定义的具体名字可能在不同的文档中不一样,需要查询,可能和HAL版本有关

    在stm32f1xx_hal_gpio.h中有详细定义,如下:

    #define  GPIO_MODE_INPUT 0x00000000u /*!< Input Floating Mode */

    #define  GPIO_MODE_OUTPUT_PP 0x00000001u /*!< Output Push Pull Mode */

    #define  GPIO_MODE_OUTPUT_OD 0x00000011u /*!< Output Open Drain Mode */

    #define  GPIO_MODE_AF_PP 0x00000002u /!< Alternate Function Push Pull Mode/

    #define  GPIO_MODE_AF_OD 0x00000012u /!< Alternate Function Open Drain Mode/

    #define  GPIO_MODE_AF_INPUT  GPIO_MODE_INPUT/!< Alternate Function Input Mode/

    #define  GPIO_MODE_ANALOG 0x00000003u   /!< Analog Mode/

    #define  GPIO_MODE_IT_RISING 0x10110000u   /!< External Interrupt Mode with Rising edge trigger detection/

    #define  GPIO_MODE_IT_FALLING 0x10210000u   /!< External Interrupt Mode with Falling edge trigger detection/

    #define  GPIO_MODE_IT_RISING_FALLING  0x10310000u   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */

    #define  GPIO_MODE_EVT_RISING  0x10120000u   /!< External Event Mode with Rising edge trigger detection/

    #define  GPIO_MODE_EVT_FALLING 0x10220000u   /!< External Event Mode with Falling edge trigger detection/

    #define  GPIO_MODE_EVT_RISING_FALLING  0x10320000u   /!< External Event Mode with Rising/Falling edge trigger detection/

GPIO函数

  • __HAL_RCC_GPIOx_CLK_ENABLE()

    GPIOx的时钟使能信号,在使用该GPIO前一定要使能时钟

  • HAL_GPIO_Init(GPIOx, &GPIO_InitTypeDef);

    初始化GPIOx

  • HAL_GPIO_WritePin(GPIOx,GPIO_Pin,a)

    a可以为GPIO_PIN_RESET或GPIO_PIN_SET,表示把GPIOx的GPIO_Pin脚设置为0或1

  • TeHAL_GPIO_ReadPin(GPIOx,GPIO_Pin)st

    读取GPIOx的GPIO_Pin脚的电平

    1是高电平,0是低电平

时钟相关

RCC(复位和时钟控制器)的时钟部分

  • 需要设置的内容有: 1.系统时钟SYSCLK

    2.设置AHB分频因子(决定HCLK等于多少)

    3.设置APB2分频因子(决定PCLK2等于多少)

    4.设置APB1分频因子(决定PCLK1等于多少)

    5.设置各个外设的分频因子

    然后控制AHB、APB2和APB1这三条总线时钟的开启、控制每个外设的时钟的开启。

    常用的设置为:PCLK2 = HCLK = SYSCLK=PLLCLK = 72M,PCLK1=HCLK/2 = 36M

  • MCO输出

    可以将PA8(stm32f103中)引脚设置为MOC输出,然后可通过示波器查看其出书情况 函数

  • 函数 HAL_Delay() 延时一段时间

中断相关

中断都定义在IRQn_Type结构体中

中断函数的定义位于stm32f1xx_it中

  • EXTI(外部中断/事件控制器)

    EXIT0~EXIT15可用于GPIO,通过编程可将任意GPIO作为EXIT的输入源 举例EXIT0对应GPIOx的PIN0引脚

    • HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)

      第一个为中断号,也即IRQn_Type结构体中的某一个,第二个为抢占优先级0~3(越低优先级越高),第三个为响应优先级

    • HAL_NVIC_EnableIRQ(IRQn_Type IRQn)

      使能IRQn中断

      在startup中可以找到对应中断函数的名称(大概?????)

      然后自己写中断函数,可以用define的方法给中断函数改个名字方便使用

      \#define EXTI0_IRQHandler MYIT_Handler
      

      详细的情况用到EXTI中断的时候再配置

  • systick系统定时器

    当其数值清0时会触发一次中断,也即每隔一段时间调用一次中断

    因此可以设定其数值,然后触发的中断为修改某一变量的值,通过该变量的值即可判断调用了多少次中断函数,也即经过了多少个周期

    D可以用于一些固定频率触发的时间

    比如电机的恒定频率的控制上

通信

  • 分类:

    1.串行通讯与并行通讯

    2.全双工、半双工及单工通讯

    • 全双工:在同一时刻,两个设备之间可以同时收发数据

    • 半双工:两个设备之间可以收发数据,但不能在同一时刻进行

    • 单工:在任何时刻都只能进行一个方向的通讯,即一个固定为发送设备,另一个固定为接收设备

    3.同步通讯与异步通讯

  • USART串口通信

    有别于USART还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在USART基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。

    本身USART接口,在stm32f103xb.h中有定义

ADC相关

  • 电压限制

    ADC的输入范围为:[VREF- , VREF+],还受VDDA,VSSA影响

    这些电压值是由硬件电路决定的

    VREF-与VSSA会接地,VREF+与VDDA会接3.3V,所以范围是0~3.3V

  • 通道

    规则通道与注入通道

    规则通道是最常用的一种,没有什么特别注意的地方

    注入通道,类似于中断,有可能插入规则通道过程中进行转换,转换完成后再回到规则通道

  • 转换顺序

    规则通道的转换顺序由SQR3~SQR1决定

  • 触发源

    可以通过寄存器ADC_CR2来控制,写1开始,写0结束

    还可以触发转换:内部定时器触发,外部IO触发

  • ADC时钟

    由PCLK2经过分频产生,最大14M

    分频因子由RCC时钟配置寄存器RCC_CFGR的位15:14 ADCPRE[1:0]设置,可以是2/4/6/8分频

  • 中断相关

    中断方式

  • 使用方法

    typedef struct
    {
        uint32_t Mode;                      // ADC 工作模式选择 一个ADC为独立模式 两个
                                            // ADC为双模式,双模式下还有具体模式
        FunctionalState ScanConvMode;       // ADC 扫描(多通道)用ENABLE或者单次(单通道)模式选择DISABLE //
        FunctionalState ContinuousConvMode; // ADC 单次转换或者连续转换选择
        uint32_t ExternalTrigConv;          // ADC 转换触发信号选择
        uint32_t DataAlign;                 // ADC 数据寄存器对齐格式
        uint8_t NbrOfChannel;               // ADC 采集通道数
    }ADC_InitTypeDef;
    

其他

  • 断言:

    #ifdef  USE_FULL_ASSERT
    /**
    * @brief  assert_param 宏用于函数的输入参数检查
    * @param  expr:若expr值为假,则调用assert_failed函数
    *             报告文件名及错误行号
    *              若expr值为真,则不执行操作
    */
    #define assert_param(expr) \((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
    /* 错误输出函数 ------------------------------------------------------- */
    void assert_failed(uint8_t* file, uint32_t line);
    #else
    #define assert_param(expr) ((void)0)
    #endif
    
    通过定义USE_FULL_ASSERT来判断是否使用断言

    若使用,可以用以下函数来输出错误:

    void assert_failed(uint8_t \* file, uint32_t line)
    {
        printf(“/r/n 输入参数错误,错误文件名=%s,行号=%s”,file,line);
    }
    
    注释:

    使用Doxygen注释规范

    防止头文件重复包含

    和C++中一样的方式使用

    #ifndef __LED_H
    #define __LED_H
    
    /*此处省略头文件的具体内容*/
    
    #endif /* end of __LED_H */