目录
众所周知,要学好嵌入式,就必须在实物上动手做。但现实中局限于实际条件,有时候手边并没有开发版,为方便大家学习,本节课就Proteus为例,介绍采用Proteus + STM32CubeMX + MDK-ARM工具来学习STM32。
在本专栏中,仅这一篇文章是讲Proteus的,需要继续用Proteus学习ARM的,可参考本文移植其他到项目。
1. Proteus中的ARM库概要
Proteus8.15版中,可仿真的ARM芯片不少,检索记录有108条,见下图:
芯片检索的关键字换为STM32以后,检索记录有19条,见下图:
由上图可知,对于STM32,支持F103和F401两个系列的部分芯片。本文就以STM32F103R6为例,讲述如何用Proteus学习ARM。
2. Proteus仿真原理图
Proteus中的流水灯仿真原理如如下 ,只用了3种元件,元件库的名字见下图中的Device。
3. 利用STM32CubeMX创建MDK工程
选择File下的New Project后,进入下面界面:
选择芯片类型(本文为STM32F103R6TA),选择下边的item,然后Start Project:
结合前面的仿真电路图,进行GPIO设置。
在上图中,选择Pinout选项卡,选择GPIO,依次将PC0~PC7设置为GPIO_Output,按上图配置各IO口。
由于本文仅做仿真,不连接硬件电路,因此时钟等其他设置保持默认,结合电路图,选择Clock Configuration,保持如下默认配置:
项目配置:
在Project Manager下的Project中设置工程名称和工程路径,并选择编译软件。取消勾选Use lastest available version,选择其他版本:
设置代码生成选项:
在驱动库选择栏,GPIO库选择LL库,RCC库选择HAL。见下图:
最后点击Generate Code,即生成代码:
可以打开MDK工程编辑了。
点击上图中的Open Folder,可以看到STM32CubeMX自动建立了与工程名同名的文件夹,并将工程存在该文件夹下。生成的MDK工程及源文件也置于该文件夹内。
4.在MDK中编辑工程
4.1 代码编辑说明
由STM32CubeMX生成的代码,为用户预留了用户代码区,所有自己编写的代码,请放在:
/* USER CODE BEGIN XXX */
和
/* USER CODE END XXX */之间。
这样我们修改工程的时候你自己写的代码就不会被删除。
4.2 修改代码
打开Keil文件后点击Application,
在 main.c 文件里的
的 while(1) 循环内的
/* USER CODE BEGIN 1 */
和
/* USER CODE END 1 */
之间添加以下代码
在 while(1) 循环内的
/* USER CODE BEGIN 3 */
和
/* USER CODE END 3 */
之间添加以下代码:
编译代码:
上图界面的倒数第三行,可以看到编译后已经生成01Proteus_LED.hex文件。此文件在下一步中有用。
5. Proteus调试设置
为使Proteus能仿真STM32,需要设定电源正负极参数。
在Proteus主界面中的菜单栏中依次选择“Design”(设计)→“Configure Power Rails”(配置电源轨)选项:
打开电源轨配置对话框,如下图:
在电源轨配置对话框中,需要将电源正极由5V改为3.3V;将模拟电源正极VDDA添加到VCC/VDD网络中,如下图:
将模拟量电源负极VSSA添加到GND网络中,否则单片机无法仿真,设置后见下图:
为仿真电路添加单片机程序。
程序编写完成后,选择电路原理图中的STM32F03R6单片机并右击,在弹出的快捷菜单中选择“Edit Properties”命令,打开如下图所示的单片机属性编辑对话框,单击该对话框中的回按钮,选择HEX文件所在路径并保存。此步骤相当于为单片机下载程序。
运行仿真
单击Proteus界面左下角的三角形仿真按钮即可开始仿真。Proteus电路仿真效果如下图:
6. LL库概要
6.1 STM32开发方式
寄存器(STM32Snippets):直接操作寄存器。
SPL库(Standard Peripheral Libraries):标准外设库,将寄存器操作封装成函数。
HAL库(Hardware Abstraction Layer):硬件抽象层,将功能操作封装成函数。
LL库(Low Layer):底层库,直接操作寄存器。
6.2 LL库简介
LL库旨在提供快速轻巧的面向专家的层,其比 HAL 库更接近硬件。 与 HAL 相反,LL API 不是提供给优化访问不是关键功能的外围设备或需要繁重的软件配置和/或复杂的上层协议栈(例如 FSMC,USB 或 SDMMC)。
在设计上,LL 库的 API 旨在用于独立模式或与 HAL 库结合使用。不过它们不能与 HAL库同时用于相同的外设实例。如果您将 LL api 用于特定的外设实例,那么您仍然可以将 HAL api 用于其他外设实例。注意,LL api可能会覆盖一些寄存器,这些寄存器的内容被映射到 HAL 句柄中。
6.3 一点说明
实际开发中,为方便项目移植,建议不要将HAL和LL两种库混用。