参考:MDK入门指导
STM32入门教程(基于HAL库+CubeMX+MDK-ARM)
软件:Keil μVision4,JLINK
硬件:STM32F107VC( Cortex-M3)
一、开发流程
使用µVision 4作为嵌入式开发工具,其开发的流程与其他软件开发工具基本一样,一般分为以下几步:
1. 新建一个工程,从设备库中选择目标芯片,配置工程编译器环境;
2. 用C或汇编编写源文件;
3. 编译目标应用程序;
4. 修改源程序中的错误;
5. 测试链接应用程序。
二、安装软件
1. 安装RealViwe MDK(Keil μVision4)
去下载MDK软件(按需要可下载最新版本)。
双击执行,出现安装界面。按照提示,完成安装。
2. 安装JLINK仿真器驱动程序
(1)去下载JLINK软件(按需要可下载最新版本)
双击执行,出现安装界面。按照提示,完成安装。
桌面出现2个图标
(2)设置JLINK仿真器软件
运行J-FLASH ARM
菜单栏选择options/Project settings
选择CPU选项,Devices 选择 STM32F107VC,选择完成后按确定退出设置。
设置完成后左边显示烧写信息
连接目标板,开启目标板电源,选择Target/Connect,连接成功后会有提示信息
(3)使用J-Link command 设置和查看相关调试信息 J-Link command包含了所有设置和查看相关调试信息的命令,J-Link command基于命令行输入方式。
打开J-Link command 界面,显示JLINK的相关版本信息,如果连接了目标板,将显示目标板的状态和目标CPU内核信息等。
三、新建一个MDK工程
1. 创建一个Demo文件夹
(1) 新建子文件夹User,用于存放用户源程序
将GPIO例子(STM32F10x_StdPeriph_Examples\GPIO\IOToggle)中的文件复制到Demo\User文件夹
(2) 新建子文件夹Project,用于存放用户KEIL工程文件
在Project下依次创建Obj和List子文件夹,存放编译过程中产生的中间文件。
(3) 新建子文件夹Libraries,用于存放ST标准库文件。
可以从ST官方网站免费下载stm32f10x_stdperiph_lib.zip 。本教程使用的标准库版本为 3.1.2
2. 新建一个Keil MDK工程
(1) 启动Keil MDK,点击菜单 New uVision Project
新建一个工程,命名为new_project,保存到Demo/project目录下
(2) 选择CPU类型为 STM32F107VC (这是MDV-STM32-107开发板采用的CPU类型)
(3) 当提示是否复制启动代码时,请选择否。(我们用最新的库中的启动代码,不用Keil软件自带的旧版本启动文件)
(4)根据自己的需要修改Target名字,并在这个Project下创建几个Group
User : 存放用户自己写的源代码
RVMDK : 存放启动文件(汇编文件)
StdPeriph_Driver : 存放ST标准库文件
CMSIS : 存放CMSIS接口文件(这也是库的一部分)
(5)给各个Group开始依次添加文件
1) 给User文件夹添加文件main.c和stm32f10x_it.c,文件存放在Demo下的User文件夹中
- 给RVMDK文件夹添加文件startup_stm32f10x_cl.s
启动文件路径:Demo\Libraries\CMSIS\Core\CM3\startup\arm
- 给stdPeriph_Driver文件夹添加文件misc.c、stm32f10x_gpio.c、stm32f10x_rcc.c
设备驱动文件路径:Demo\Libraries\STM32F10x_StdPeriph_Driver\src
- 给CMSIS文件夹添加文件core_cm3.c、system_stm32f10x.c
CMSIS接口文件路径:Demo\Libraries\CMSIS\Core\CM3
3. 修改源代码
#include "stm32f10x.h"
/* 为了使用编程书写方便,我们定义几个控制LED开关的宏 */
#define LED1_OFF() {GPIO_ResetBits(GPIOD, GPIO_Pin_7);} /* PD7 = 0 熄灭LED1 */
#define LED1_ON() {GPIO_SetBits(GPIOD, GPIO_Pin_7);} /* PD7 = 1 点亮LED1 */
#define LED2_OFF() {GPIO_ResetBits(GPIOD, GPIO_Pin_13);} /* PD13 = 0 熄灭LED2 */
#define LED2_ON() {GPIO_SetBits(GPIOD, GPIO_Pin_13);} /* PD13 = 1 点亮LED2 */
#define LED3_OFF() {GPIO_ResetBits(GPIOD, GPIO_Pin_3);} /* PD3 = 0 熄灭LED3 */
#define LED3_ON() {GPIO_SetBits(GPIOD, GPIO_Pin_3);} /* PD3 = 1 点亮LED3 */
#define LED4_OFF() {GPIO_ResetBits(GPIOD, GPIO_Pin_4);} /* PD4 = 0 熄灭LED4 */
#define LED4_ON() {GPIO_SetBits(GPIOD, GPIO_Pin_4);} /* PD4 = 1 点亮LED4 */
/*这是一个延迟函数*/
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/* 主函数*/
int main(void)
{
/* 这个函数是ST库中的函数,配置内部Flash接口,初始化PLL,配置系统时钟的频率系统时钟缺省配置为72MHz/
SystemInit();
/* 配置GPIO */
{
GPIO_InitTypeDef GPIO_InitStructure; /* 定义1个结构体变量 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);/* 打开GPIOF 时钟 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_13| GPIO_Pin_3 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*推挽输出模式 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure); /* 调用库函数初始化GPIO */
}
/*下面这个 while循环实现简单的跑马灯功能 */
while (1)
{
LED1_ON(); /* 点亮LED1 */
Delay(0xAFFFF); /* 插入延时 */
LED2_ON(); /* 点亮LED2 */
Delay(0xAFFFF); /* 插入延时 */
LED3_ON(); /* 点亮LED3 */
Delay(0xAFFFF); /* 插入延时 */
LED4_ON(); /* 点亮LED4 */
Delay(0xAFFFF); /* 插入延时 */
LED4_OFF(); /* 熄灭LED4 */
Delay(0xAFFFF); /* 插入延时 */
LED3_OFF(); /* 熄灭LED3 */
Delay(0xAFFFF); /* 插入延时 */
LED2_OFF(); /* 熄灭LED2 */
Delay(0xAFFFF); /* 插入延时 */
LED1_OFF(); /* 熄灭LED1 */
Delay(0xAFFFF); /* 插入延时 */
}
}
4. 配置工程,点击“Options”按钮
(1)Device(芯片型号的选择),新建工程时已设置
(2)Target(硬件设置),一般默认设置。
(3)output(输出文件类型设置)
修改:
1)选择Object文件夹
2)在Create Hex File 前打钩。
(4)List(列表文件设置)
修改:选择List文件夹。
(5)User(用户功能设置),一般默认设置。
(6)C/C++(与C语言编译相关设置)
修改:
1)添加两个预编译宏 STM32F10X_CL, USE_STDPERIPH_DRIVER(这是ST库用到了这两个宏)
2)修改Includes路径,添加3个路径
(7)asm(与汇编语言编译相关设置),默认设置
(8)Linker(连接器功能设置),默认设置
(9)Debug(仿真功能设置)
修改:
1) 选择硬件调试器(缺省是软件仿真),选择Cortex-M/R J-LINK/J-Trace调试器
2) 在 Run to main前打钩
(10)Utilities(下载功能设置)
修改:
1) 选额调试器类型,选择Cortex-M/R J-LINK/J-Trace
2) 点settings按钮,添加Flash编程算法,选择STM32连接型器件,Flash容量256K字节
总结:MDK工程新建工程,修改:output、Listing、C/C++、Debug、Utilities
5. 编译工程
点击“Build”按钮,下方Build Output看Error和Warning
6. 调试工程
MDK支持强大的调试功能,能够仿真芯片内部所有的外设,提供了软件仿真(验证算法和程序的流程)和硬件仿真(实际工程运用)两种,常用硬件仿真来进行程序的调试和错误的排查。
当程序编译成功,目标板通过仿真器和电脑连接后,在工具栏中点击debug按钮,进入硬件仿真的调试界面,想要退出调试界面,就再次点击debug按钮。
点击一下,进入调试界面,可分为7个部分。
菜单栏提供调试模式下的全部功能。
工具栏提供调试模式下的常用功能,包括全速执行、单步执行、断点等调试方法
寄存器窗口显示MCU的片内寄存器、系统堆栈、处理器的工作模式以及程序运行时间等信息
反汇编窗口主要显示由C语言反汇编后的汇编语言窗口,一般不使用,可以关闭
代码调试窗口用于显示代码执行的顺序,单黄色箭头表示下一行将执行的代码。
命令窗口用于显示调试工程中的系统信息,比如仿真器的状态。
调用栈和局部变量窗口,在程序暂停时,会显示调用栈和当前执行函数的全部局部变量
MDK提供了强大的调试功能,主要集中在工具栏
常用可分为4大类,第一类是常规调试方法,提供8个图标。
第1个是复位功能,点击后,程序将从头开始执行,
第2个是全速运行功能,点击后,程序将全速运行,便于用户了解程序的实际运行情况
当用户设置断点以后,程序将在断点处停止执行。
第3个是停止运行功能,点击后,程序将在当前执行的代码行暂停运行,
第4-5个是跟踪调试和单步调试,
第6个是跳出函数,可以跳出当前执行的函数返回到上层函数,
第二类调试方法是断点调试(常用调试手段)
第三类方法是观察窗口,用于查看变量的值。
Value默认格式16进制,想要10进制,就步骤2-3
第四类是外设的查看功能,便于用户查看当前的配置是否正确。