新建MDK工程

713 阅读7分钟

参考: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文件夹中

  1. 给RVMDK文件夹添加文件startup_stm32f10x_cl.s

启动文件路径:Demo\Libraries\CMSIS\Core\CM3\startup\arm

  1. 给stdPeriph_Driver文件夹添加文件misc.c、stm32f10x_gpio.c、stm32f10x_rcc.c

设备驱动文件路径:Demo\Libraries\STM32F10x_StdPeriph_Driver\src

  1. 给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

第四类是外设的查看功能,便于用户查看当前的配置是否正确。