前段时间开发一个按键板驱动,该板用的STM32F103系列单片机,前任工程师用STM32CubeMX生成的工程,里面全是HAL库调用,我接手后,学习了下HAL库的用法,踩坑不少,特别是带IT后缀的函数,初学者对其的理解很容易出错,特此记录一下。

项目中的按键板通过SPI总线与主板连接,按键板是Slave设备,因此无法确定什么时候收到主板的读写请求,要么轮询,要么依赖控制器提供的中断机制。

说明一下,SPI的BPW(bits per word)=8,不是16,因此一个word就是一个字节。
先看函数签名
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
hspi是SPI控制器句柄,pData是接收buf地址,Size是接收buf长度,Timeout是接收超时时间,如果期间一直没收到数据,则返回。
根据HAL源码,梳理流程概要:
注意,RxISR表示接收中断的回调函数,因为我们是轮询模式,所以该字段填0。
先看函数签名
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
参数含义跟HAL_SPI_Receive一样,少了个超时参数,因为中断方式并不关心rx fifo深度
根据HAL源码,梳理流程概要:
注意:
printf之类的打印语句,否则会影响SPI接收时序!可以看出,带IT后缀的receive函数,只填充控制器的上下文结构体并开启中断,剩下的都交给中断回调。这种策略将接收分成前后台两部分,后台开启中断,前台响应中断并读取数据,检测数据收够了就关闭中断,因此带IT后缀并不是传言的只能在中断态下运行。