stm32-hal库函数
-
HAL_GPIO_Init:初始化我们需要用到的引脚的工作模式,包括具体引脚的工作速度、是否复用模式、上下拉等等参数。
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) -
HAL_GPIO_DeInit:将初始化之后的引脚恢复成默认的状态–各个寄存器复位时的值
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
例:HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); -
HAL_GPIO_ReadPin:读取我们想要知道的引脚的电平状态、函数返回值为0或1。
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
例:GPIO_PinState pinState;
pin_State = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9); -
HAL_GPIO_WritePin:给某个引脚写0或1,但是不要理解成,写1就是使能之类的意思,有些寄存器写1是擦除的意思
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
例:#define LED_G(x) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15,
(x) ? GPIO_PIN_SET : GPIO_PIN_RESET) //配置引脚的初始化电平 -
HAL_GPIO_TogglePin:翻转某个引脚的电平状态
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); -
HAL_GPIO_LockPin:如果一个管脚的当前状态是1,读管脚值使用锁定,当这个管脚电平变化时保持锁定时的值,直到重置才改变
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
例:HAL_StatusTypeDef hal_State;
hal_State = HAL_GPIO_LockPin(GPIOC, GPIO_PIN_9); -
HAL_GPIO_EXTI_IRQHandler:这个函数是外部中断服务函数,用来响应外部中断的触发,函数实体里面有两个功能,1是清除中断标记位,2是调用下面要介绍的回调函数。实际调用的是下边的中断回调函数
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); -
HAL_GPIO_EXTI_Callback:中断回调函数,可以理解为中断函数具体要响应的动作。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
例:HAL_GPIO_EXTI_Callback(GPIO_Pin); -
使能时钟
/*
使能时钟A、B、C、D
这里使能时钟的方法与标准库不一样,HAL库其实是宏定义,标准库则是函数。
*/
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE(); -
HAL_GetTick:获取系统当前运行时间,返回uint32_t类型,时间为毫秒ms。
__weak uint32_t HAL_GetTick(void)
__weak修饰符:“弱函数”
加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。
__weak 在回调函数的时候经常用到。这样的好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时,如果用户自己要定义用户回调函数,那么只需要重新定义即可,不需要考虑函数重复定义的问题,使用非常方便,在 HAL 库中__weak 关键字被广泛使用。
-
HAL_Delay:Delay延时,单位毫秒ms。
__weak void HAL_Delay(__IO uint32_t Delay)
例:HAL_Delay(500); //延时500ms -
HAL_UART_Transmit:串口发送数据
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:HAL_UART_Transmit(&huart1, MyRxData, 15, 100); //发送串口1数据 -
HAL_UART_Receive:串口接收数据
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:HAL_UART_Receive(&huart1, MyRxData1, 15, 100)//接收串口1数据 -
HAL_ADC_Start:开启ADC转换
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
例:HAL_ADC_Start(&hadc1); //hadc1为ADC_HandleTypeDef变量 -
HAL_ADC_PollForConversion:等待ADC转换完成
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
例:if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) //第二个参数表示超时时间,单位ms -
HAL_ADC_GetValue:获取ADC转换数据
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
例:KeyADCVal = (WORD)HAL_ADC_GetValue(&hadc1); -
HAL_ADC_Stop:停止ADC转换
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
例:HAL_ADC_Stop(&hadc1); -
HAL_SPI_Transmit:SPI发送
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:HAL_SPI_Transmit(&hspi1, data, 2, 100); //SPI发送data的2个字节,100ms超时 -
HAL_SPI_Receive:SPI接收
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:while(HAL_SPI_Receive(&hspi1, data, 1, 100) != HAL_OK) //接收1个字节,100ms超时 -
HAL_SPI_TransmitReceive:SPI发送和接收
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
例://SPI发送/接收数据,tx_data:发送数据;rx_data:接收数据,100ms超时
HAL_SPI_TransmitReceive(&hspi1, tx_data, rx_data, 2, 100); -
HAL_I2C_Master_Transmit:I2C主机发送数据
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:IIC根据地质发送数据到不同的设备
HAL_I2C_Master_Transmit(&hi2c1, 0x78, data0, 1, 100); //主机发送数据 -
HAL_I2C_Master_Receive:I2C主机接收数据
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:HAL_I2C_Master_Receive(&hi2c1, 0x78, data1, 1, 100); //主机接收数据 -
HAL_I2C_Slave_Transmit:I2C从机发送数据
HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:HAL_I2C_Slave_Transmit(&hi2c1, data0, 1, 100); //发送数据data0 -
HAL_I2C_Slave_Receive:I2C从机接收数据
HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例:if(HAL_I2C_Slave_Receive(&hi2c1, data1, 1, 100) == HAL_OK) //判断是否接收到数据 -
HAL_I2C_Mem_Write:I2C设备寄存器写数据
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例://*hi2c: I2C设备号指针,这里用的是I2C1: &hi2c1;
//DevAddress: 设备地址;MemAddress: 寄存器地址;MemAddSize: 寄存器长度;
//*pData: 数据指针;Size: 数据长度;Timeout: 超时时间
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0X00, 1, data0, 1, 100); //写数据 -
HAL_I2C_Mem_Read:I2C设备寄存器读数据
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
例://*hi2c: I2C设备号指针,这里用的是I2C1: &hi2c1;
//DevAddress: 设备地址;MemAddress: 寄存器地址;MemAddSize: 寄存器长度;
//*pData: 数据指针;Size: 数据长度;Timeout: 超时时间
HAL_I2C_Mem_Read(&hi2c1, 0x78, 0X00, 1, data1, 1, 100); //读数据 -
HAL_IWDG_Refresh:独立看门狗数据重装函数
独立看门狗使用,独立看门狗时钟采用与RTC公用的40KHz的时钟,与系统时钟分开,即使系统时钟挂了,看门狗还是可以工作
例:HAL_IWDG_Refresh(&hiwdg); //重装看门狗数据为4095. -
三种编程方式
HAL库对所有的函数模型也进行了统一。在HAL库中,支持三种编程模式:轮询模式、中断模式、DMA模式(如果外设支持)。其分别对应如下三种类型的函数(以ADC为例):
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
其中,带_IT的表示工作在中断模式下;带_DMA的工作在DMA模式下(注意:DMA模式下也是开中断的);什么都没带的就是轮询模式(没有开启中断的)。
- HAL_RCC_OscConfig:根据RCC_OscInitTypeDef结构体中指定的参数初始化RCC振荡器
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
例:ret=HAL_RCC_OscConfig(&RCC_OscInitStructure);//初始化,RCC_OscInitTypeDef指针
RCC_OscInitTypeDef结构体:
typedef struct
{
uint32_t OscillatorType; //①选定将被配置的振荡器
uint32_t HSEState; //②HSE状态
uint32_t LSEState; //③LSE状态
uint32_t HSIState; //④HSI状态
uint32_t HSICalibrationValue; //⑤HSI校准调整值
uint32_t LSIState; //⑥LSI状态
#if defined(RCC_HSI48_SUPPORT)
uint32_t HSI48State; //⑦HSI状态,#if defined(RCC_HSI48_SUPPORT)
#endif
uint32_t MSIState; //⑧,MSI状态
uint32_t MSICalibrationValue; //⑨,MSI校准调整值
uint32_t MSIClockRange; //⑩,MSI频率范围
RCC_PLLInitTypeDef PLL; //⑾,PLL结构体参数
} RCC_OscInitTypeDef;
- HAL_RCC_ClockConfig:根据RCC_ClkInitTypeDef结构体中指定的参数初始化CPU、AHB(系统总线)和APB(外围总线)总线时钟
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
例:ret=HAL_RCC_ClockConfig(&RCC_ClkInitStructure,FLASH_LATENCY_2); //同时设置FLASH延时周期为2WS,也就是3个CPU周期。
RCC_ClkInitTypeDef结构体:
typedef struct
{
uint32_t ClockType; //①,选定将被配置的时钟
uint32_t SYSCLKSource; //②,用作系统时钟的时钟源选择
uint32_t AHBCLKDivider; //③,AHB时钟(HCLK)分频器,该时钟由SYSCLK而来
uint32_t APB1CLKDivider; //④,APB1时钟(PCLK1)分频器,该时钟由HCLK而来
uint32_t APB2CLKDivider; //⑤,APB2时钟(PCLK2)分频器,该时钟由HCLK而来
} RCC_ClkInitTypeDef;