zoukankan      html  css  js  c++  java
  • MDK5新建工程/MDK5 使用技巧/STM32F4 在线调试

    建立相关文件夹如图所示

     FWLIB放官方固件库文件,HARDWARE放自己编写的.C,.H文件,USER放主函数文件,工程,启动文件等。

     1,首先,打开 MDK(以下将 MDK5 简称为 MDK)软件。然后点击 Project---New uVision Project ,然后保存在USER文件夹下,工程名自取。

    2,选择 STMicroelectronics--STM32F4 Series--STM32F407--STM32F407ZGT6(如果使用的是其他系列的芯片,选择相应的型号就可以了,特别注意: 一定要安装对应的器件 pack
    才会显示这些内容哦!!)。

    3,点击 OKMDK 会弹出 Manage Run-Time Environment 对话框 。这是 MDK5 新增的一个功能,在这个界面,我们可以添加自己需要的组件,从而方便构建开发环境,不过这里我们

    不做介绍。所以在图 3.2.4 所示界面,我们直接点击 Cancel,即可。得到如图所示界面:

     
    4,到这里,我们还只是建了一个框架,还需要添加启动代码,以及.c 文件等。这里我们先介绍一下启动代码: 启动代码是一段和硬件相关的汇编代码。 是必不可少的! 这代码主要作用如
    下:

    1、堆栈(SP)的初始化;

    2、初始化程序计数器(PC);

    3、设置向量表异常事件的入口地址;

    4、调用 main 函数。感兴趣的朋友可以自己去分析这部分代码。
    ST 公司为 STM32F40x STM32F41x 系列的 STM32F4 提供了一个共同的启动文件,名字为: startup_stm32f40_41xxx.s。 我们开发板使用的是 STM32F407ZGT6, 属于 STM32F40x 系列
    里面的,所以直接使 startup_stm32f40_41xxx.s 这个启动文件即可。 不过这个启动文件,我们做了一点点修改,具体是 Reset_Handler 函数,该函数修改后代码如下:

    Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]
    ;IMPORT SystemInit ;寄存器代码,不需要在这里调用 SystemInit 函数,
    ;故屏蔽掉,库函数版本代码,可以留下
    ;不过需要在外部实现 SystemInit 函数,否则会报错.
    IMPORT __main
    LDR R0, =0xE000ED88 ;使能浮点运算 CP10,CP11
    LDR R1,[R0]
    ORR R1,R1,#(0xF << 20)
    STR R1,[R0]
    ;LDR R0, =SystemInit ;寄存器代码,未用到,屏蔽
    ;BLX R0 ;寄存器代码,未用到,屏蔽
    LDR R0, =__main
    BX R0
    ENDP

    这段代码,我们主要加入了开启 STM32F4 硬件 FPU 的代码,以使能 STM32F4 的浮点运算单元。其中, 0xE000ED88 就是协处理器控制寄存器(CPACR)的地址,该寄存器的第 20~23

     位用来控制是否支持浮点运算,这里我们全设置为 1,以支持浮点运算。关于 CPACR 寄存器的详细描述,见《STM32F3 F4 系列 Cortex M4 内核编程手册.pdf》第 4.6.1 节。另外,寄存器
    版本,我们还屏蔽了 SystemInit 函数的调用,如果是库函数版本,可以取消这个函数的注释,并在外部实现 SystemInit 函数。

    特别注意:我们在汇编代码里面使能了 FPU,所以在 MDK 里面,我们也要设置使用 FPU,否则可能代码会无法运行,设置方法如下:选择 Options for Target Target1’ ,打开 Target
    项卡,在 Code Generation 里面,选择 Use FPU,如图 所示:

     这样, MDK 编译生成的代码,就可以直接使用硬件 FPU 了,其实就 2 个步骤: 1,设置CPACR 寄存器 20~23 位全为 1,使能硬件 FPU2,设置 MDK 选型,选择 Use FPU。另外,
    中, MDK 默认 STM32F4 外部晶振为 12M,我们板子用的 8M,所以这里设置为 8Mhz。修改后的这个启动文件 startup_stm32f40_41xxx.s 拷贝到刚刚新建的USER文件夹里面。

    5,在图中,我们找到 Target1--Source Group1--双击--设置打开文件类型为 Asm Source file--选择 startup_stm32f40_41xxx.s--点击 Add,如图所示:

     添加完后,我们得到如图所示的界面:

     至此,我们就可以开始编写自己的代码了。

    由于上面我们还没有任何代码在工程里面,这里我们把系统代码 COPY 过来(即 SYSTEM文件夹的代码,该文件夹由 ALIENTEK 提供,可以在光盘任何一个实例的工程目录下找到,不过不要
    拷贝错了! 不要把库函数代码的系统文件夹拷贝到寄存器代码里面用,反之亦然! 这些代码在任何 STM32F40x/STM32F41x 的芯片上都是通用的,可以用于快速构建自己的工程)。

    SYSTEM 文件夹下包含了 delaysysusart 等三个文件夹。分别包含了 delay.csys.cusart.c及其头文件。通过这 3 c 文件,可以快速的给任何一款 STM32F4 构建最基本的框架。使用
    起来是很方便的。 具体可以百度学习一下。

    6,然后在 Target 目录树上点击右键--Manage Project Items, 弹出如图 所示对话框:

     在上面对话框的中间栏,点新建(用红圈标出) 按钮(也可以通过双击下面的空白处实现),新建 USER SYSTEM 两个组。 然后点击 Add Files 按钮,把 SYSTEM 文件夹三个子文件夹里
    面的: sys.cusart.cdelay.c 加入到 SYSTEM 组中。注意: 此时 USER 组下还是没有任何文件,
    得到如图所示的界面:

     点击 OK,退出该界面返回 IDE。 这时,我们在 Target1 树下发现多了 2 个组名,就是我们刚刚新建的 2 个组。如图  所示:

     7,接着,我们新建一个 test.c 文件,并保存在 USER 文件夹下。 然后双击 USER 组,会弹出加载文件的对话框,此时我们在 USER 目录下选择 test.c 文件,加入到 USER 组下。 得到如图
    所示的界面:

     至此,我们就可以开始编写我们自己的代码了。 我们在 test.c 文件里面输入如下代码:

    #include "sys.h"
    #include "usart.h"
    #include "delay.h"
    int main(void)
    {
    u8 t=0;
    Stm32_Clock_Init(336,8,2,7);//初始化时钟为 168Mhz
    delay_init(168); //初始化延时函数
    uart_init(84,115200); //串口初始化为 115200
    while(1)
    {
    printf("t:%d
    ",t);
    delay_ms(500);
    t++;
    }
    }

    如果我们此时编译的话, 生成的过程文件,还是会存放在 USER 文件夹下,所以,我们先设置输出路径,再编译。 点击 (Options for Target 按钮),弹出 Options for TargetTarget 1
    对话框,选择 Output 选项卡--选中 Create Hex File(用于生成 Hex 文件,后面会用到)--点击Select Folder for Objects--找到 OBJ 文件夹--点击 OK

    接着,再设置 Listings 文件路径,在上文的基础上,打开 Listing 选项卡--点击 Select Folder for Listings--找到 OBJ 文件夹--点击 OK

    8,现在我们再次点击 (Options for Target 按钮),弹出 Options for TargetTarget 1’ 对话框,选择 C/C++选项卡,如图 所示:

     这里特别提醒大家: 图中 1 处设置的 STM32F40_41xxx 宏,是为了兼容低版本的 MDK(比如 MDK4/MDK3 等)才添加的, MDK5 在你选择器件的时候,就会内部定义这个宏,因此在
    MDK5 下面,这里不设置也是可以的。但是为了兼容低版本的 MDK,我们还是将这个宏添加进来。
    图中 2 处是编译器优化选项,有-O0~-O3 四种选择(default 则是-O2),值越大,优化效果越强,但是仿真调试效果越差。这里我们选择-O0 优化,以得到最好的调试效果,方便开发代
    码,在代码调试结束后,大家可以选择-O2 之类的优化,得到更好的性能和更少的代码占用量。
    图中 3 处, One ELF Section per Function 主要是用来对冗余函数的优化。通过这个选项,可以在最后生成的二进制文件中将冗余函数排除掉,以便最大程度地优化最后生成的二进制代
    码,所以,我们一般勾选上这个,这样可以减少整个程序的代码量。

    然后在 Include Paths 处(4 处),点击 5 处的按钮。在弹出的对话框中加入 SYSTEM 文件夹下的 3 个文件夹名字,把这几个路径都加进去(此操作即加入编译器的头文件包含路径, 后
    面会经常用到)。如图 所示:

     点击 OK 确认,回到 IDE,此时再点击 按钮,(bulid)编译一次,发现没错误了,得到如图 所示的界面:

     因为我们之前选择了生成 Hex 文件,所以在编译的时候, MDK 会自动生成 Hex 文件(图中圈出部分),这个文件在 OBJ 文件夹里面,串口下载的时候,我们就是下载这个文件到
    STM32F4 里面的,这个在后面的程序下载一节会介绍。

    这里有的朋友编译后,可能会出现一个警告: warning#1-D last line of file ends without anewline。这个警告是在告诉我们,在某个 C 文件的最后,没有输入新行,我们只需要双击这个
    警告,跳转到警告处,然后在后面输入多一个空行就好了。
    至此,一个完整的 STM32F4 开发工程在 MDK5 下建立了。 接下来我们就可以进行代码下载和仿真调试了。

    关于代码,其实就是配置系统时钟,开启外设时钟,配置外设,功能代码,一般就是这样的流程

    **************************************************************************************************

    文本美化,主要是设置一些关键字、注释、数字等的颜色和字体。 前面我们在介绍 MDK5新建工程的时候看到界面如图 3.2.23 所示,这是 MDK 默认的设置, 可以看到其中的关键字和
    注释等字体的颜色不是很漂亮,而 MDK 提供了我们自定义字体颜色的功能。我们可以在工具条上点击扳手图样 (配置对话框)弹出如图 所示界面:

     在该对话框中,先设置 Encoding :Chinese GB2312(Simplified),然后设置 Tab size 为: 4。以更好的支持简体中文(否则,拷贝到其他地方的时候,中文可能是一堆的问号),同时 TAB
    间隔设置为 4 个单位。然后,选择: Colors&Fonts 选项卡,在该选项卡内,我们就可以设置自己的代码的子体和颜色了。由于我们使用的是 C 语言,故在 Window 下面选择: C/C++ Editor Files
    在右边就可以看到相应的元素了。如图  示:

     然后点击各个元素修改为你喜欢的颜色(注意双击,且有时候可能需要设置多次才生效,MDK bug),当然也可以在 Font 栏设置你字体的类型,以及字体的大小等。设置成之后,点
    OK, 就可以在主界面看到你所修改后的结果 。

    这就比开始的效果好看一些了。 字体大小,则可以直接按住: ctrl+鼠标滚轮,进行放大或者缩小,或者也可以在刚刚的配置界面设置字体大小。

    细心的读者可能会发现,上面的代码里面有一个 u8,还是黑色的,这是一个用户自定义的关键字,为什么不显示蓝色(假定刚刚已经设置了用户自定义关键字颜色为蓝色)呢?这就又
    要回到我们刚刚的配置对话框了,单这次我们要选择 User Keywords 选项卡,同样选择: C/C++Editor Files,在右边的 User Keywords 对话框下面输入你自己定义的关键字

     3.3.5 中我定义了 u8u16u32 3 个关键字,这样在以后的代码编辑里面只要出现这三个关键字,肯定就会变成蓝色。点击 OK,再回到主界面,可以看到 u8 变成了蓝色了

    快速定位函数/变量被定义的地方 :右键

     快速注释与快速消注释

     **************************************************************************

    串口只能下载代码,并不能实时跟踪调试,而利用调试工具,比如 JLINKULINKSTLINK等就可以实时跟踪程序, 从而找到你程序中的 bug, 使你的开发事半功倍。这里我们以 JLINK
    V8 为例,说说如何在线调试 STM32F4

    JLINK V8 支持 JTAG SWD, 同时 STM32F4 也支持 JTAG SWD。所以,我们有 2 种方式可以用来调试, JTAG 调试的时候,占用的 IO 线比较多,而 SWD 调试的时候占用的 IO 线
    很少,只需要两根即可。
    JLINK V8 的驱动安装比较简单, 我们在这里就不说了。在安装了 JLINK V8 的驱动之后,我们接上 JLINK V8,并把 JTAG 口插到 ALIENTEK 探索者 STM32F4 开发板上,打开之前

    新建的工程, 点击 ,打开 Options for Target 选项卡,在 Debug 栏选择仿真工具为 J-LINK/J-TRACE Cortex,如图 所示:

     上图中我们还勾选了 Run to main(),该选项选中后, 只要点击仿真就会直接运行到 main 函数, 如果没选择这个选项,则会先执行 startup_stm32f40_41xxx.s 文件的 Reset_Handler,再跳到
    main 函数。
    然后我们点击 Settings,设置 J-LINK 的一些参数,如图 4.2.2 所示:

     图  中,我们使用 J-LINK V8 SW 模式调试,因为我们 JTAG 需要占用比 SW 模式多很多的 IO 口,而在 ALIENTEK 探索者 STM32F4 开发板上这些 IO 口可能被其他外设用到,可
    能造成部分外设无法使用。所以,我们建议大家在调试的时候,一定要选择 SW 模式Max Clock,可以点击 Auto Clk 来自动设置, 图 中我们设置 SWD 的调试速度为 10Mhz,这里,如果你
    USB 数据线比较差,那么可能会出问题,此时, 你可以通过降低这里的速率来试试。
    单击 OK,完成此部分设置,接下来我们还需要在 Utilities 选项卡里面设置下载时的目标编程器,如图  所示:

     中, 我们直接勾选 Use Debug Driver,即和调试一样,选择 JLINK 来给目标器件的FLASH 编程, 然后点击 Settings,设置如图所示:

     这里 MDK5 会根据我们新建工程时选择的目标器件,自动设置 flash 算法。我们使用的是STM32F407ZGT6FLASH 容量为 1M 字节, 所以 Programming Algorithm 里面默认会有 1M
    号的 STM32F4xx FLASH 算法。 特别提醒: 这里的 1M flash 算法,不仅仅针对 1M 容量的STM32F4,对于小于 1M FLASH 的型号,也是采用这个 flash 算法的。 最后, 选中 Reset and Run
    选项,以实现在编程后自动运行, 其他默认设置即可。设置完成之后,如上图 所示。

    在设置完之后,点击 OK,然后再点击 OK,回到 IDE 界面,编译一下工程。 然后点击:
    (开始/停止仿真按钮),开始仿真(如果开发板的代码没被更新过,则会先更新代码(即下载
    代码),再仿真, 你也可以通过按 load按钮,只下载代码,而不进入仿真。 特别注意:开发板上的 BOOT0BOOT1 都要设置到 GND,否则代码下载后不会自动运行的!), 如图所示:

     因为我们之前勾选了 Run to main()选项,所以,程序直接就运行到了 main 函数的入口处。另外,此时 MDK 多出了一个工具条, 这就是 Debug 工具条,这个工具条在我们仿真的时候是
    非常有用的,下面简单介绍一下 Debug 工具条相关按钮的功能。 Debug 工具条部分按钮的功能如图  所示:

     复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。 按下该按钮之后, 代码会重新从头开始执行。
    执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查
    看的地方设置了断点。
    停止运行:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。
    执行进去: 该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。
    执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。
    执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩 余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位
    置。
    执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。
    汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。
    堆栈局部变量窗口:通过该按钮, 显示 Call Stack+Locals 窗口,显示当前函数的局部变量及其值,方便查看。
    观察窗口: MDK5 提供 2 个观察窗口(下拉选择),该按钮按下,会弹出一个显示变量的窗口, 输入你所想要观察的变量/表达式,即可查看其值, 是很常用的一个调试窗口。
    内存查看窗口: MDK5 提供 4 个内存查看窗口(下拉选择), 该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况。是很常
    用的一个调试窗口

    这里stlink与jlink其实用法是一样的,选着对应的选项即可。

  • 相关阅读:
    Backbone的 listenTo 和 on
    前端工作流程
    Zepto源码笔记(三)
    Zepto源码笔记(二)
    Zepto源码笔记(一)
    Canvas基础学习(一)——实现简单时钟显示
    常用排序算法之JavaScript实现
    NodeJS学习笔记(一)——搭建开发框架Express,实现Web网站登录验证
    浏览器基础知识
    学习Vim 全图解释
  • 原文地址:https://www.cnblogs.com/caiya/p/15076775.html
Copyright © 2011-2022 走看看