入门配置 | 实例1-闪烁LED | 实例2-UART发送 | 实例3-外部GPIO中断 | 实例4-UART接收和外部文件 | 实例5-定时器,PWM和看门狗 | 实例6-SPI和I2C通讯 | 实例7-实时操作系统(RTOS)
简单闪烁的LED是嵌入式系统的“世界”。 这可能是您的第一个Arduino程序,而我们将使用STM32重新进行一次。 该过程涉及在STM32CubeMX中配置芯片,生成初始化代码,编写您自己的代码,然后进行编译然后上传。 此过程与任何STM32芯片相同。
STM32CubeMX中的芯片配置
选择目标芯片
打开STM32CubeMX并单击“新建项目”:
它可能开始检查更新,最终您将在这里结束:
如您所见,它是一个非常全面的列表,您可以按系列,包,功能,成本等进行浏览。
我们需要找到正在使用的芯片,并且由于我们已经知道部件号STM32f030F4,因此我们只需要在搜索框中输入以下内容即可:
双击列表以选择该芯片:
现在我们处于一个不错的芯片配置视图中! 左侧是可用外围设备的列表,右侧是芯片本身的图示。 您可以使用鼠标滚轮放大/缩小,单击鼠标左键来移动它,并使用上面的工具栏上的按钮旋转它以适合您的需要。
启用SWD
首先,我们需要启用SWD以便将固件上传到芯片中。展开SYS节点,然后选中Debug Serial Wire框:
PA14和PA13引脚在右侧自动突出显示,表明它们正在使用中。
启用外部时钟源
开发板上有一个外部晶体振荡器,我们将使用它来运行芯片。
展开“ RCC(重置和时钟控制)”节点,为“ HSE”选择“ Crystal / Ceramic Resonator”。
启用GPIO输出
最后,我们需要将GPIO引脚设置为输出。我们将使用开发板上连接到PA4的LED。
左键单击PA4,然后选择GPIO_Output:
这会将PA4的功能设置为GPIO输出,然后再次右键单击PA4并选择Enter User Label为其命名,我将其命名为USER_LED。
外围设备就这些了!现在,我们有了一些令人兴奋的东西。
STM32时钟信号简介
内部时钟
这些时钟源位于芯片本身内,它们始终可用,但通常精度较低。结构是:
结构
Clock Frequency Description
LSI ~40KHz Low Speed Internal. Highly unstable, avoid.
HSI 8MHz High Speed Internal. Can be used for system clock.
HSI14 14MHz Used for ADC.
HSI48 48MHz Only on USB capable chips. Can be used for system clock.
LSI未经校准且不准确,请千方百计避免。
如果不需要精确的计时,则HSI和HSI48可以很好地工作,否则建议使用外部晶振。
外部时钟
您还可以从外部提供2个时钟信号以提高准确性:
时钟信号
Clock Frequency Description
LSE Usually 32.768KHz Low Speed External. Used for RTC timekeeping.
HSE 4 - 32MHz High Speed External. Used for system clock
晶体振荡器通常用于外部时钟,就像我们使用的开发板一样。
配置时钟树
我们准备好了时钟树!单击时钟配置选项卡:
现在,这是一些适当的令人兴奋的东西。不过请放心,我在下面提供了完整的设置。遵循黄色的路径,我将一路解释:
STM32F0的最大时钟速率为48MHz,因此我们的目标是运行48MHz的系统时钟。 但是,我们板上的晶体只有8MHz,因此我们需要一种将其倍频至48MHz的方法。 我们使用内置的PLL(锁相环)来精确地做到这一点,然后将相乘的时钟用作系统时钟。
我们从黄色道路的起点开始。我们可以看到HSE可用,因为我们早先启用了它。输入频率设置为8MHz,如果使用其他晶体,则可以更改输入频率。
接下来,我们遇到一个时钟分频器。 8MHz已经相当慢了,因此我们将其保留为1。
接下来,我们进入PLL源Mux,后者选择将哪个时钟输入PLL(在本例中为HSE)。
在PLL内部,我们选择将输入时钟倍增的次数。我们有8MHz,想要48MHz,所以是6MHz。
现在,我们到达系统时钟多路复用器,它确定了用于为整个系统提供时钟的工具。在这种情况下,我们选择48MHz PLL输出。
现在,系统时钟为48MHz,并已分配给许多系统总线和外围设备。无需担心这里的细节,只需将所有内容保持在最大频率下就可以了。
差不多了!我希望这是有道理的。在高端STM32芯片上,时钟树可能更复杂,但是基本原理仍然存在。
作为练习,尝试弄清楚如何在48MHz系统时钟上使用HSI。结果如下:
外围配置
我们快到了!单击“配置”选项卡,进入配置视图。在这里,您可以调整在首页上启用的所有外围设备的设置。由于我们仅启用了GPIO,因此请单击GPIO按钮。
在新窗口中,选择一个引脚以更改其设置。
在这种情况下,实际上没有太多更改,但是有助于您熟悉以下选项:
GPIO输出电平:高或低。引脚的初始输出电平。
GPIO模式:推挽或漏极开路。简而言之,推挽可以将信号驱动为高电平和低电平,而漏极开路只能将信号拉低。
上拉/下拉:我们根本不使用任何拉式。
最大输出速度:设置输出信号的摆率。将其保留为默认设置。
单击“确定”返回,所有配置都已完成,现在我们终于可以生成我们的代码了!
生成代码
现在,我们将使STM32CubeMX生成所有初始化代码,因此我们无需编写任何代码。
要开始,请单击项目菜单,然后单击设置:
输入项目名称并选择其位置,选择MDK-ARM V5作为我们的IDE,不要碰其他任何东西:
转到“代码生成器”选项卡,然后选择“仅复制必要的库文件”。并非绝对必要,但我喜欢保持清洁。
单击确定。如果是第一次运行,它将要求您下载固件包,确认并等待其完成。
毕竟,我们终于可以生成代码了!单击“项目”菜单下的“生成代码”:
您可以在所选文件夹中找到生成的代码。 .ioc文件是您正在使用的STM32CubeMX项目,而MDK项目位于MDK-ARM文件夹中。
无论如何,单击“打开项目”以启动Keil IDE。
第一个STM32程序
如果这是Keil MDK第一次运行,请仔细阅读本指南。
一切设置完成后,通过展开文件夹并双击文件来查找并打开main.c:
浏览代码后,您会发现代码生成器留下了很多注释块。通常:
始终在/* USER CODE BEGIN /和/ USER CODE END */之间输入您的代码
这样,当您在STM32CubeMX中进行更改后重新生成代码时,将保留您自己的代码,而所有外部内容将被覆盖。让我们看一下main()函数。
它看起来很长,但大部分只是注释。 生成的代码首先进行一些初始化,然后进入不执行任何操作的循环,这与Arduino中的setup()和loop()函数相当。 无论如何,这取决于我们来编写实际的程序,在这种情况下,闪烁PA4上的LED。
马上我们有一个问题:Arduino有digitalWrite(),我们在这里使用什么?要回答这个问题,我们首先需要了解我们正在使用的库。
STM32 HAL库
STM32 HAL(硬件抽象层)库是由ST编写的开放源码库,推荐用于所有新项目,并且是STM32CubeMX生成的库。 它提供了一整套在STM32系列产品中保持一致的API。 这简化了编码并提高了可移植性。
所有驱动程序文件都位于project_folder / Drivers / STM32F0xx_HAL_Driver中。每个外围设备都有自己的.c和.h文件。然后,这里的技巧很简单:
要查看外围设备可以做什么,只需查看相应的HAL驱动程序文件中提供了哪些功能即可。
通常.h文件就足够了,尽管.c文件中也有详细的文档,所以请不要错过。
您也可以右键单击任何函数名称,然后选择“转到定义”以查看其详细信息。
详情参阅 - 亚图跨际