关于STM32的一些开发技巧
2017-03-10 00:00
1016 查看
流行IDE
Keil老牌编译器,结合SourceInsight用应该是大众所常用的开发方式吧!
IAR
老牌编译器,这个还是以前在学校用MSP430时接触的。一样功能比较强大,特别一点,编译出来的hex比其它编译器要小。
sw4stm32
基于Eclipse开发的一个STM32专用IDE,似乎是官网推荐。好处是免费,结合STM32Cube的插件使用,开发STM32程序即为方便。
缺点是资料较少,使用的人群没有Keil、IAR多。
Atollic TrueSTUDIO(仅仅测过一下)
仅了解一下,这也是基于Eclipse开发的嵌入式IDE,支持很多MCU,不止STM32一种。分为免费版本和Pro版。有兴趣的童鞋可以详细了解一下。
STM32开发方式
官网提供了两套开发STM32的代码:其一为stdperiph_lib,即我们所说的标准库;
其二为STM32CubeMx,这是一个基于HAL库的工具,如下图所示;
这种方式极为简化了STM32的开发,可以通过一些简单的配置,快速的生成代码。而且HAL库兼容了STM32各个系列,使得硬件改版后,软件代码的可移植性大大提高。
当然HAL也有不足之处,那便是过于复杂,看过其代码就知道其复杂性远非其它库所比。
它的复杂性带来的便是系统级的兼容。如你在用到嵌入式系统时,并不需要额外的参数及代码来保证各线程的冲突。HAL内部自带互斥、硬件读写锁。
比较建议的开发组合为:HAL+自己参考标准库写的一些硬件操作函数。下面简略介绍一下HAL库的常用开发方式。
基于HAL库开发
使用STM32CubeMx(或Eclipse的插件)生成工程后,其包含了所有的初始化代码及时钟配置代码。你只需要在工程中添加自己的逻辑代码即可。如果包含系统(STM32Cube默认使用FreeRTOS),则可以删除src中的freertos.c文件,然后新建一个源码目录users,将freertos中的初始化函数“void MX_FREERTOS_Init()”,在自己的c文件中,重新定义一个即可。
这样做的好处是:以后再调整STM32Cube工程后,只需要删除freertos.c,不用更改一处代码即可正常编译执行。
下面说一说“HAL库的正确使用方式”(这部分基于FreeRTOS,无系统的代码大同小异),这主要包含两部分:
外设初始化
生成的初始化代码有三个函数: void MX_I2C1_Init(void); void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle); void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle); 通过这三个函数调用,可以初始化外设以及功耗控制。
读写操作
HAL库提供三种读写方式:一是超时读写;二是中断读写;三是DMA读写。详见“stm32fxxx_hal_i2c.h”。超时读写
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); 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); 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); HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
中断读写
HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
DMA读写
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
如何得到返回的读写数据长度呢?这个可以根据I2C_HandleTypeDef结构中的RxXferCount/RxXferSize、TxXferCount/TxXferSize做差得到。每发送或者接收一个数据,Count值会减1,而Size则是你传入的一个长度,Size减去Count即可得到返回的读写数据长度。
中断回调
HAL库不止提供了读写操作函数,还提供了一系列的中断回调。比如发送、接收、错误中断。void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
注意:这些函数均在stm32fxxx_hal_i2c.c中有实现。如果需要某个中断回调,则需要查看这个文件中的函数是否有__weak修饰。有__weak修饰的函数表示这是一个虚拟函数,你可以在外部重新定义其实现。如果没有__weak修饰,如HAL_I2C_EV_IRQHandler,则表示这个函数被HAL库实现。
总结
总得来说,STM32开发建议使用如下方式:sw4stm32IDE+STM32Cube的Eclipse插件进行开发。如果不能满足需求,则读写、中断可以从标准库中拷贝过来,自己实现。简单说就是:
使用STM32Cube的函数进行时钟和外设的初始化及其使能控制。
使用从标准库移植的代码实现外设的读写、中断操作。
由于HAL库和标准库有部分冲突,所以两个库并不能直接在一个工程中使用。除非修改库的代码。
相关文章推荐
- 关于实际开发中优化web的一些小技巧汇总(持续更新中)
- 最近整理IOS开发关于scrollView的一些细节和技巧
- 网上看到的一些关于asp.net开发的经验
- 关于软件开发团队的一些思考
- 【蛙蛙王子】我今天上午整理了一些关于.NET企业开发的文章(2005年9月13日12:44:28 )
- 开发购物网站的第一步--关于制作前的一些思考
- 一些关于网页制作的特效和技巧
- 关于外挂开发的一些感悟:(
- DELPHI的一些开发技巧和方法(二)
- DELPHI的一些开发技巧和方法(一)
- 写给新手的,关于投稿的一些技巧- -
- 对DHTML性能提高的一些开发技巧
- 蛙蛙推荐:关于开发规范的一些讨论.doc
- 网上看到的一些关于asp.net开发的经验
- 实际开发中的一些技巧(更新中)
- 关于软件开发团队的一些思考
- 关于使用Java开发工具的一些心得
- [转]一些struts开发技巧
- 关于这两天的学到的一些java编界面时的一些技巧或方法。
- 关于软件开发团队的一些思考