前言
STM32可以实现初始化配置,但逻辑代码还是需要我们自己去写,就要使用大量hal库的函数,这里列举了hal开发常用的函数,中断回调函数,必要的结构体,中断标志,以及经常使用的代码块。
void Delay_us(uint32_t us)
{
uint32_t sysTickReload = (HAL_RCC_GetHCLKFreq()/ 1000000) * us;
SysTick->LOAD = sysTickReload - 1; // 设置重载值
SysTick->VAL = 0; // 清空当前计数值
SysTick->CTRL = 0x00000007; // 启动定时器,选择时钟源为处理器时钟
// 等待计数到0
while((SysTick->CTRL & 0x00010000) == 0);
SysTick->CTRL = 0x00000000; // 关闭定时器
SysTick->VAL = 0; // 清空当前计数值
}
一、GPIO and EXTI
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_15,GPIO_PIN_RESET); //写高低电平
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); //电平翻转
HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4); //读取电平,有返回值
中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1);
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
二、USART
普通函数
HAL_UART_Transmit();串口发送数据,使用超时管理机制
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收
//重定向 c 库函数 printf 到串口 USARTx,重定向后可使用 printf 函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}
//重定向 c 库函数 scanf 到串口 USARTx,重写向后可使用 scanf、getchar 等函数
int fgetc(FILE *f)
{
int ch;
/* 等待串口输入数据 */
while (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) == RESET);
HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);
return (ch);
}
HAL_UART_GetState(&huart1);
中断回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送完成回调函数
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);//发送完成过半
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收完成回调函数
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//接收完成过半
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); //错误处理回调函数
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能中断
__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //过去中断标志位
__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE); //中断标志位清零
中断标志位
接收缓冲区非空标志位 (USART_FLAG_RXNE)
发送缓冲区空标志位 (USART_FLAG_TXE)
发送完毕标志位 (USART_FLAG_TC)
奇偶校验错误标志位 (USART_FLAG_PE)
帧错误标志位 (USART_FLAG_FE)
噪声错误标志位 (USART_FLAG_NE)
串口空闲标志位 (USART_FLAG_IDLE)
LIN 帧标志位 (USART_FLAG_LBD)
三、TIM and PWM
普通函数
HAL_TIM_Base_Start(&htim2);
HAL_TIM_Base_Start_IT(&htim2);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_Base_Stop(&htim2);
HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_3);
中断
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); //更新中断 ,用的最多
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); //输出比较
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); //输入捕获
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); //触发中断
__HAL_TIM_DISABLE_IT(&htim2,TIM_IT_CC1); //失能中断
__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_CC1); //使能中断
__HAL_TIM_SET_COUNTER(&htim2,0); //设置计数值
__HAL_TIM_GET_COUNTER(&htim2); //获取计数值
HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
//更改触发方式:
//上升沿:TIM_INPUTCHANNELPOLARITY_RISING
//下降沿TIM_INPUTCHANNELPOLARITY_FALLING
//兼具上升下降:TIM_INPUTCHANNELPOLARITY_BOTHEDGE
四、ADC
HAL_ADC_Start(&hadc1);
HAL_ADC_GetValue(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 50);
HAL_ADCEx_Calibration_Start(&hadc1);
中断回调函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
五、IIC and SPI
HAL_I2C_Master_Transmit(&hi2c, 0x12, "hello word", sizeof("hello world"), HAL_MAX_DELAY);
HAL_SPI_Transmit(&hspi1, cmd, 1, 1000);
HAL_SPI_Receive(&hspi1, ID, 3, 1000);
六、SDIO
HAL_SD_ReadBlocks(&hsd, rBuff, 0x0,1, 0xFFFF); //读取一个块大小,初始地址0x0
HAL_SD_WriteBlocks(&hsd, wBuff, 0x0,1, 0xFFFF); //写入一个块大小,初始地址0x0
HAL_SD_ReadBlocks_DMA(&hsd, rBuff, 0x0,1); //读取一个块大小,初始地址0x0
HAL_SD_WriteBlocks_DMA(&hsd, wBuff, 0x0,1); //写入一个块大小,初始地址0x0
HAL_SD_GetCardstate(&hsd); //返回值为hsd工作状态
七、flash
结构体
typedef struct
{
uint32_t TypeErase;
//擦除类型
// FLASH_TYPEERASE_SECTORS 擦除某一个块,
//FLASH_TYPEERASE_MASSERASE 全部擦除
uint32_t Banks; //块名称
uint32_t Sector; //扇区号
uint32_t NbSectors; //要擦除的扇区数量
uint32_t VoltageRange; //指定擦除操作的电压范围
} FLASH_EraseInitTypeDef;
FLASH_EraseInitTypeDef flash_def;
HAL_FLASH_Unlock(); //解锁
HAL_FLASH_Lock(); //上锁
HAL_FLASHEx_Erase(&flash_def, NULL); //擦除
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data); //编程
八、CAN
结构体
typedef struct
{
uint32_t StdId; //标准ID
uint32_t ExtId; //扩展ID
uint32_t IDE; //用来决定报文是使用标准ID还是扩准ID
uint32_t RTR; //用来决定报文是数据帧要是遥控帧
uint32_t DLC; //数据长度,取值为0-8
FunctionalState TransmitGlobalTime;
//最后这个是时间触发模式用的,开启后会自动把时间戳添加到最后两字节的数据中。目前没有用到,选择 DISABLE
} CAN_TxHeaderTypeDef;
typedef struct
{
uint32_t FilterIdHigh; //CAN_FiR1寄存器的高16位
uint32_t FilterIdLow; //CAN_FiR1寄存器的低16位
uint32_t FilterMaskIdHigh; //CAN_FiR2寄存器的高16位
uint32_t FilterMaskIdLow; //CAN_FiR2寄存器的低16位
uint32_t FilterFIFOAssignment; //通过筛选器的报文存在FIFO0还是FIFO1中
uint32_t FilterBank; //此次配置用的是哪个筛选器。用单CAN的取值为0-13
uint32_t FilterMode; //掩码模式或列表模式
uint32_t FilterScale; //32位或16位
uint32_t FilterActivation; //使能或失能
uint32_t SlaveStartFilterBank; //CAN1和CAN2一起用的时候,为CAN2分配筛选器的个数
} CAN_FilterTypeDef;
函数
HAL_CAN_Start(&hcan1);
HAL_CAN_AddTxMessage(&hcan1, &can_Tx, sendBuf, &box);
HAL_CAN_ConfigFilter(&hcan1, &can_Filter);
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &can_Rx, recvBuf);
中断
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)