使用仿真器进行在线调试
硬件环境:STM32F407VET6核心板 软件环境:Keil 5.0 分类:此类为【技巧型】知识,需要多加练习才能掌握 你可以学到:如何通过MDK的自带的调试功能进行调试与检查可能出现的问题
?基础调试方法
调试环境的配置
- 配置好debug:点击魔术棒
 在Debug-setting选项中进行如下配置:
 左侧和仿真器型号相关,右侧和单片机型号相关。 如果出现: 左边检测不到,是因为没有链接电脑 右边检测不到,是因为没有连接开发板 如果: 两侧都有显示,说明可以进行下载和调试,进入下一步调试阶段。
- 点击放大镜即可进入

调试界面介绍
执行操纵栏
 分别是复位/程序运行/停止 复位:程序重头开始执行,(可以和断点进行配合使用) Run:使程序正常进行 挂起:停止正在运行的程序
进入函数/执行过此函数/跳出函数/执行到光标处 这些按钮可以控制函数的执行流程,用以动态的查看函数的工作和运行
断点
 只有在灰色区域可以设置断点 上图中,【黄色箭头】是程序执行到的地方/【绿色箭头】是光标所在地方 可以设置断点状态:  插入断点、使能/失能断点、失能所有断点、清楚所有断点。 这些选项可以对断点进行管理,方便使用断点。 【注意】点击 run 是执行到断点处,(此时断点所在的行【没有】被执行),断点是:即将执行某一行代码。
除了设置断点之外,还可以设置挂起:
挂起
挂起:程序执行到某个地方突然被中断 与断点的区别:挂起并不知道在哪里停下,知识知道在发生什么事件后停下,这个事件可以通过外部的标志进行判断
调试窗口介绍
 先介绍比较常用的几个窗口
call stack windows
显示正在执行的程序中,函数的调用情况 点开后,是下列界面:  第一列是函数名称/第二列是函数地址或者函数值(返回值)第三列是函数类型 同时可以查看函数内部的局部变脸。
使用的时候,不需要将函数拖进去,就可以查看函数内部局部变量的值。
这里思考一个问题:为什么函数中的局部变量的值要在堆栈里查看?
猜测:因为C语言中调用函数内部的局部变量,是在调用时生成,调用结束后销毁的,
用堆栈存放这些变量,可能是考虑到了函数的嵌套调用的情况,
在函数调用完毕后,最后一个被存储的局部变量第一个被销毁。刚好符合堆栈后进先出的原则。
watch windows
 直接将某个函数或者变量拖进来,就可以显示该函数或者变量的值。 如下图所示:  这样可以很方便的在调试过程中查看寄存器或者变量的情况。(函数对应的是函数入口地址)
需要特别注意MDK的优化问题 一定要使用level-0优化方式,否则优化登记太高,将不会显示某些变量的值,导致一些变量一直处于< not in scope>的状态 优化的选项在魔术棒中,如下图 
peripheral工具栏
 在这个工具栏下,几乎可以选择所有的片内外设,点开后,会显示外设的寄存器的所有状态 我们依照这些寄存器状态,去和数据手册进行比对,从而可以找出问题或者进行底层的修改 
外设寄存器栏可以查看几乎所有外设的寄存器的数值? 可以对比数据手册,查看某个值是什么含义,从而了解某个数值是不是预期的数 也可以查看内核级别的寄存器 也可以查看对应中断向量的值
?进阶调试方法
区段函数执行时间
 可以查看区段函数的执行时间 执行时间,将显示在debug模式下的窗口右下角(注意窗口需要全屏显示才能看到,否则会自动隐藏)
比如查看延时函数是否准确
Memory查看寄存器地址
 需要输入带待查看数组或者函数的地址,可以结合watch窗口或者stack窗口进行查找地址 这里我们选择一个数组进行查看  把它的地址移到memory窗口中,可以查看对应内存的数据了。  例如,当一个数组很大(上千个)时,watch窗口无法显示,就需要用memory查看所有数值。
查看中断执行的时间和次数
 可以查看所有中断的执行时间/次数 
全局变量读写时暂停
 【注意】与设置断点是不同,他会停留在读/写操作的下一行代码处。
|