【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)

0. 结论

先放结论把,目前2020.07.20,cubeIDE版本v1.3.0。
使用cubeIDE,配置流程和一些协议栈移植会简便很多很多,迅速推进开发流程
但是目前的cubeIDE还有一些bug和不完善的地方在里面,比如freeRTOS下的malloc没有做线程保护,printf浮点无法实现等,这些ST的官方已知且已经改了好几版依然不见好转,导致使用人不得不去第三方找补丁打,软件自身的便捷性又打了个折扣。
总结:
比较看好,潜力很大,但仍需打磨。

1. 引言

说是起来cubeIDE应该已经推出来不少几年了,只是一直没用。
之前这么久做stm32都是用Keil MDK来做的,潜意识里都快把keil当做st的官方工具了。
ST目前的开发方式有这么几种:

寄存器开发
标准库开发
hal库/LL库开发+cubeMX辅助
图形化cubeIDE开发

cubeIDE对应的是st的HAL库和LL库,感觉HAL比3.5的标准库冗余了很多,估计也是为了兼容多个平台而做的妥协,没办法,这年头芯片的性能越来越强,肯定还是以开发效率为优先,就像很多人不会再用汇编来写代码一样。
st的这个cubeIDE和之前NXP出的S32DS很像,都是从Eclipse改出来的带图形化界面的IDE,支持一键生成代码。不过感觉ST的图形化还是比NXP的直观好用一些,毕竟之前cubeMX也打了这么久的底子,也是更符合大家的用法。
图形化IDE应该是以后的一个趋势,记得11年的时候第一次接触了图形化编程——Cypress的Psoc Creator,就已经是图形化的了,很多器件就是连线连线,像现在xilinx的vivado也是这样。当时就记得一句话,“图形化编程是新一代的编程语言“,当时觉得不理解,现在看看各大厂家都在走这条路,集成度和封装度越来越高,降低了运行效率,但是也降低了开发难度,代码一键生成,最是方便。为什么呢,还不是为了降低使用门槛,把和IC相关的库都封装起来,大家直接上手写应用更快。基本上就是只要会写C的都能做这个开发。
可见,MCU这一块的门槛真的越来越低,上手越来越快,可替代性越来越强。
但是呢,并不是说以往的经验就不重要了,就我使用这些新工具的经历来看,没有时间是浪费的,在遇到问题的时候,过去的很多经验可以帮助自己触类旁通,而且上手新的平台和环境也很快。
我发现我每篇引言一发散就收不回来,也是人到中年,职业焦虑了,打住打住,还是进入今天的正题罢。
网上找了一些cubeIDE的例子,基本没有介绍界面配置的参数选择的,都是直接生成代码,然后调试。因此本来想写的详细一点,写一个系列,后来看到了别人写的系列(结尾参考链接第2条),看了一遍,感觉不用重复造轮子。
我这边只记录一些我的流程,尝尝鲜,用cubeIDE简单做一个stm32f1的串口小实验。简单用下来的感觉:开发确实是十分简便轻松,搭框架非常快。
没有花太多时间深究,如有不足,请指出。

2. cubeIDE

之前做stm32一共有3种主流开发方式:

  1. Keil MDK
  2. IAR
  3. gcc + makefile

这几种里,Keil 和 IAR国内一般都是盗版使用的,gcc自己用交叉工具链搭建编译环境又稍微有些麻烦(但是很建议一试)
后来ST官方可能是为了维护自己的生态,推出了cubeMX,算是图形化配置的先行尝试。不过就我个人习惯只是当成一个辅助工具,当自己项目功能不正常的时候,会在cubeMX中简单点选一下功能,生成代码,然后和自己的配置代码进行一下比对,看看有没有什么问题。
再之后,官方推出了主打的STM32Cube IDE,把配置,编译等步骤都放在了一起,算是一个完整意义上的IDE了,而且内嵌了一些协议栈,功能比较完善。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第1张图片
除了有点吃性能,其他感受还行。
在这里插入图片描述

2.1 下载安装

cubeIDE是ST免费放出来,所以我们直接去官网下载即可。当前(2020.7.15)的最新版本是1.3.0。
下载地址
直接拉到页面中部,点击 DOWNLOAD 即可。
可能有时候会需要输入邮箱之类的,需要填写自己的邮箱,会发下载链接过去。
也可以注册账号,直接登陆了下载。
在这里插入图片描述
整体下载速度挺快的,估计国内有镜像?比国内下东西还快。

下载后会得到一个en.st-stm32cubeide_1.3.0_5720_20200220_1053_x86_64.exe.zip压缩包,解压然后默认下一步安装即可,途中没有什么要输入激活码的地方。

注意,安装路径(还有工程路径)不能有中文,eclipse的通病
否则:
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第2张图片

2.2 建立工程

打开新安装的cubeIDE。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第3张图片
会弹出一个窗口让选择workspace路径,这个workspace就是我们的工程文件(不是代码)所在的位置,这个步骤好像eclipse改的IDE都是这样的流程,比如xilinx的vivado SDK等等,随便设置一个就好,我这里就用默认的。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第4张图片
可以改成自己想用的路径,也可以不改,直接launch。

进入后有3个选择,直接新建一个工程,导入一个cubeMX的工程,或者 导入一个trueSTUDIO的工程。
这里我们选择直接新建,毕竟手头也没有其他工程。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第5张图片

然后是选型,这里我们直接选一个我们比较常用的stm32f103c8,然后next,输入工程名,其他默认不改了。
第一个是选择编程语言是C还是Cpp。
第二个是选择编译成可执行文件(hex、bin…)还是静态库(用于封装打包,给别人链接用)。
第三个是选择工程类型。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第6张图片
然后finish,这个工程就建立完成了。

2.3 图形化工程

工程建立之后,会先生成一个.ioc的文件,这个格式是和之前cubeMX一致的,配置方法也很类似。
界面配置主要分4个部分,下面一一来介绍。

2.3.1 PinOut & Configuration

基本的外设配置都在这个标签页了。
从左侧我们可以看出主要配置的部分分为以下6个部分:
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第7张图片
我们可以根据原理图和我们需要的功能选择引脚功能。
本次我们的功能:

  • LED灯(PB14/PB15)交替闪烁
  • 串口1输出

2.3.1.1 System Core

让我们回到左边,进入第一部分 System Core。
这部分算是系统必备的配置项了。

里面包含:

  • WWDG 窗口看门狗
  • SYS 系统
  • RCC 时钟
  • NVIC 中断
  • IWDG 独立看门狗
  • DMA
  • GPIO
    【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第8张图片
2.3.1.1.1 GPIO 引脚

这里我们要做LED灯功能,LED是PB14、PB15两个引脚,我们就点击PB14和PB15进行功能选择。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第9张图片
选完就发现这两个脚功能已经固定下来了。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第10张图片
如果需要做一些引脚的配置,比如:输出模式(推挽开漏……)、时钟、上下拉、初始电平等,都可以在界面中进行配置。
这里我们配置两个灯初始时一亮一灭(PB14、PB15都是推挽输出,label为led1/2,初始电平分别为低和高)。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第11张图片

2.3.1.1.2 IWDG

独立看门狗,个人习惯,我一般都会加一个在系统里,没啥说的,直接勾选使能就好。
看门狗用的是内部的 40kHz 低速RC时钟,所以我们设置分频64,就是40000/64=625Hz,假设我们希望6秒钟不喂狗就重启,重载值设置为625*6 = 3750。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第12张图片
这样我们1s喂一次就比较稳了。

2.3.1.1.3 RCC

时钟有三个选项

  • 是否使能外部高速时钟
  • 是否使能外部低速时钟
  • 是否使能时钟输出。
    一般都是用了外部晶振,所以开启外部高速时钟输入(外部8M晶振)HSE,关闭外部低速时钟输入,不勾选时钟输出。这些在一会的时钟树上都能看到。
    【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第13张图片
2.3.1.1.4 SYS

系统配置,这里要注意,一定要把debug模式配上!
这是st-link调试的接口。
一定要配上,不然之后再下载会比较麻烦。
这里我用的是st-link的sw模块,就配置成serial wire。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第14张图片

2.3.1.2 Connectivity

【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第15张图片
因为我们用到了串口1 PA9 PA10,所以这里要配置串口1的控制器。勾选为异步功能就好。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第16张图片

2.3.1.4 Middleware

这里都是ST帮忙集成好的一些协议栈和固件库,比如fatfs文件系统,做tf读写会用,比如freeRTOS,目前最火的免费操作系统,还有USB协议,GUI……
这里我们使用FreeRTOS系统,所以勾选上freeRTOS即可,系统会帮自动集成进去。具体的freeRTOS参数就用默认的就行。比如周期1ms(1000Hz),堆3kb……
基本上都是freeRTOSconfig.h里的裁剪项。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第17张图片
我们也可以看到,freeRTOS勾选后,一些我们没有配置的项就自动配置了。
比如NVIC,之前我们没有配置,但是使用FreeRTOS后,默认就选择4分组,并且其他可选项都没了。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第18张图片
这里我们新建一个task,用来驱动LED闪烁和串口发送。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第19张图片

2.3.2 时钟配置

在这里插入图片描述
这一面配置的是stm32的时钟树,需要对时钟树有一些简单的了解。
一般来说,stm32f1都是倍频到72M。
基础知识:
STM32 有4个独立时钟源: HSI、HSE、LSI、LSE
这里简单介绍一下,stm32 的外部输入时钟有两个,

  • 外部高速时钟HSE,4M~16M,f1一般是个8M晶振
  • 外部低速时钟LSE,一般是个32k的时钟晶振
    内部时钟也有两个:
  • 内部高速时钟HSI,内部的RC振荡器,8M
  • 内部低速时钟LSI,内部的RC振荡器,40k,是作为IWDGCLK(独立看门狗)时钟源和RTC时钟源而独立使用
    这些就是图中最左侧的输入部分,配置在2.3.1.2.3中介绍了。
    【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第20张图片
    然后将HSE通过PLL倍频到72M时钟作为系统的主时钟即可,后面的高速外设就是72M,低速外设就是36M。
    【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第21张图片

2.3.3 工程配置

在这里插入图片描述
这一面都是一些工程相关的配置了,会改动的可能这么几个地方:

  1. 堆栈大小
    【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第22张图片
  2. 库代码是否复制入工程

【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第23张图片
3. 每个外设生成独立的一对.c 和 .h文件
这个默认是不勾选的,这里我们勾选上。这样模块化的感觉比较好。

【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第24张图片
别的项比如初始化不用引脚都为模拟脚(省电)等功能,都不强求,看大家自己需求。

2.3.4 工具Tools

在这里插入图片描述
这一面没啥研究,据说是可以计算功耗,没关注过这一块,没用过。
直接略过。

2.4 代码编写

2.4.1 应用层

图形化配置完成后,我们点击Project-Generate Code,右侧生成代码。
点击main看一下,其实很多代码结构都已经做固定在里面了。

无freeRTOS的版本:
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第25张图片
用户代码只允许卸载 USER CODE BEGIN 和 USER CODE END之间,不然其他位置的代码在再次Generate code之后会被覆盖掉。

带freeRTOS的版本:
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第26张图片
可以看出,基本上所有的初始化都做完了,系统main的流程也写完了,用户只要加自己的功能就行了。
这里我们在启动的StartDefaultTask任务中随便加几句,把串口1和两个灯驱动起来。

void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
	  HAL_UART_Transmit(&huart1,'t',1,1000);
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
	  HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_15);
	  HAL_IWDG_Refresh(&hiwdg);
	  osDelay(1000);
  }
  /* USER CODE END StartDefaultTask */
}

2.4.2 printf实现

补充:
如果串口需要printf功能,可以在底部参考链接中找到做法。
即重定向putchar函数,再使能浮点输出即可。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第27张图片
然后在设置中使能浮点输出。
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第28张图片

2.4.3 添加自定义的文件夹

如果我们有一些.c和.h需要添加到项目中,可以按照如下步骤.
本工程里暂时没有做这一步。只是mark一下,万一有人需要。

2.5 下载运行

点击
在这里插入图片描述
编译下载可执行文件。
初次使用需要配置
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第29张图片

ST-link方面,我用的就是淘宝十几块的便宜货,第一次下载时候会提示需要固件升级。

【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第30张图片
确定后弹出升级框,点击 Open in update mode.
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第31张图片
左下角出现 Upgrade successful之后则为成功。

然后重新下载运行即可。

2.6 遇到的问题

7月19补记
之前记录这个问题只是临时记一下,以为是个小问题,没想到纠结了一周还没找到原因,而且感觉现象很诡异,认真的探究了与喜爱,感觉干脆单独再开一文做记录把。

添加printf驱动之后,在task中一运行printff就进入HardFault_Handler。很奇怪。
HardFault_Handler一般就是堆栈溢出,数组越界等等,
查了一下,网上给的解释就是task的堆栈分小了,128改成512即可。
为什么printf要这么大的栈?
查了一下,cubeIDE里的用了newlib,里面的printf居然还要malloc空间,有点无语。
对于我20k的stm32f103c8真的不友好啊。
反正改一把试下,
【stm32】 stm32cube IDE v1.3.0 使用步骤(freeRTOS + GPIO + 串口 printf)_第32张图片
跑了一下,还是不行。
主要体现在:
在task里printf 浮点数异常。

又测试了几组,发现还是任务堆栈大小设置的问题,太大太小都不行。还有freeRTOS的总堆栈大小也要设置合适。

  • 任务堆栈太小,printf跑不起来,要进HardFault_Handler
  • 任务堆栈大了(注意分配的是word),接近freeRTOS的总heap大小,也会容易进

还有奇怪的一些bug还遗留在里面:

  1. 在main中先跑一下printf,task里跑printf就正常,main中不跑,直接task跑printf就进HardFault_Handler,这个还没搞清楚为什么。
  2. 每个周期printf的字符很多之后,最后的部分就打不出来了。

居然官方的IDE有问题,看来还得打磨。

解决方案和文件下载我记录在 下一篇博客 里了。
有需要的可以自取。

总结

使用cubeIDE来开发真的是十分简单十分方便,也不用自己再收集整理一些常用接口模块了,常用的协议栈也不用自己移植了。
可以说是非常强大了。
就是出来没多久,还是有一些需要打磨的地方,比如freeRTOS、USB库等的malloc接口等等,都有问题。这部分可能还是得先用老的(诶,本来就冲着不用自己移植来用的cubeIDE)
基本上要注意的部分我都在本文加粗加黄了。

参考资料

  • UM1718_STM32CubeMX的配置和C代码的生成 - 官方中文文档
  • cubeIDE入坑指南
  • stm32f1时钟树配置
  • STM32CubeIDE串口实验操作
  • CubeIDE实现printf
  • 官方视频教程
  • stm32CubeIDE 在自己工程中添加.c 和.h文件
  • STM32Cube IDE使用lib、a库文件方法
  • CubeIDE freeRTOS中无法printf浮点数的坑

你可能感兴趣的:(stm32,单片机,嵌入式)