嵌入式程序基于源代码仿真调试

描述

前面一课设计了51单片机最小系统电路,使用51单片机的I/O口控制发光二极管的状态,并装载运行了使用keil编写的嵌入式程序。本次实验应用proteus结合keil对嵌入式C程序进行源代码级调试。

关于上次实验遗留的问题

在上次实验中,我们遗留了一个问题没有解决。观察上次实验结果,单片机P0口的所有位颜色为灰色方块,表示该端口的电压为不确定状态。

为什么P0口所有位的电压为不确定状态呢?因为P0同P1、P2、P3的I/O口电路不同,P1、P2、P3属于带上拉电阻(将I/O不确定的电位钳位在高电平,同时起限流作用)型的I/O口,当单片机加电后I/O被钳位在高电平,P0不带上拉电阻,因此I/O的电位不确定。

若需要把P0口钳位在高电平,只需要将P0口外接一个上拉电阻即可,上拉电阻的阻值一般设置为4.7K,也可以根据负载大小选择合适的阻值。

源代码

实验目的

在开发嵌入式程序过程中,源代码级的仿真调试可以帮助开发者快速定位问题代码,纠正程序错误,极大提高开发效率。本次实验在前面实验成果的基础上,将proteus和keil结合在一起,在proteus仿真调试嵌入式程序的过程中,能够将执行点定位到程序源代码行,在源代码级别跟踪执行程序。

实验步骤

实验步骤如下:①输出可以进行源代码调试的OMF文件;②配置基于源代码仿真调试环境;③执行调试,单步跟踪代码,查看和验证程序执行结果。

输出可以进行源代码调试的OMF文件

启动keil开发工具,打开前面课程建立的项目文件,修改项目内的C源文件代码。

#include
sbit led1 = P1^0;
void main()
{
       led1 = 0;
       led1 = 1;
       led1 = 0;
       led1 = 1;
}

main()函数修改为四条语句,对P1端口的第0位led1进行赋0或赋1操作。第1条语句将led1端口赋值为低电平,此时发光二极管被点亮,第2条语句将led1端口赋值为高电平,此时发光二极管不再处于被点亮状态。第3条和第4条语句分别重复了第1条和第2条语句。

代码跟踪调试时,从第1条语句开始跟踪,单步执行到第4条语句,观察发光二极管的状态和led1端口的状态。

proteus源代码仿真调试需要Keil编译后输出omf文件,在Keil工作窗口,展开【Project】菜单,选择“Options for Targets”命令,在弹出的对话框中,选择“Output”标签页,确定在“Name of Executable”输入域输入了omf文件名称。

源代码

完成配置后重新编译,keil会把omf文件输出到项目的Objects目录下。

源代码

配置基于源代码仿真调试环境

要进行源代码级仿真调试,还需要配置调试环境,不然proteus会找不到程序的源代码。配置方法是将C源代码文件、OMF文件、电路模型文件放置在同一个目录。可以将扩展名为“DSN”电路模型文件复制到OMF文件所在的目录,同时将C源代码文件也复制到OMF文件所在目录。也可以将C源代码文件、OMF文件、电路模型文件放置到一个专门用于调试的目录。

源代码

调试环境配置完成后,使用proteus打开电路模型文件,设置单片机的装载程序为omf文件。

源代码

执行调试

启动proteus,打开待调试的电路模型文件,展开【Debug】菜单,选择“Start/Restart Debugging”命令或按下Ctrl+F12快捷键启动调试。

proteus会初始化单片机,并执行单片机内的嵌入式程序,程序在main()函数的第1条语句之前停止执行,等待开发者的下一步调试操作。默认情况下,proteus会同时打开源代码窗口,显示嵌入式程序的源代码和执行状态。

源代码

“8051 CPU Source Code-U1”为源代码调试窗口,在源代码调试窗口可以执行“Step Over Source line(单步跳过)”、“Step Into Source line(单步执行)”、“Step Out From Source line(单步跳出)”,其调试过程和Keil单步调试完全相同。

若源代码调试窗口没有弹出,可展开【Debug】菜单,在【Debug】菜单下面选择弹出源代码调试窗口的命令。

源代码

从图中列出的菜单命令可以看出,proteus还提供了查看单片机寄存器状态、SFR内存数据等窗口,开发者通过这些窗口可以随时查看单片机的内部状态。
例如选择“8051 CPU Registers-U1”命令,proteus会弹出单片机寄存器状态窗口(见下图)。

源代码

通过寄存器窗口可以查看单片机内每个寄存器当前存储的值。其中“PC”寄存器为程序计数器,该寄存器存储了当前准备要执行的指令地址,指令地址为十六进制000F,指令内容为“CLR P1.0”(对P1口的第0位清零)。再仔细观察窗口内容,名称为“P0”、“P1”、“P2”、“P3”寄存器实际上分别对应了单片机P0、P1、P2、P3四个I/O口每位的状态,当程序修改I/O口的状态后,这些寄存器的值也会发生相应变化。

调试步骤:

单步跳过第1条语句,P1口第0位被赋值为低电平,发光二级管点亮。观察寄存器窗口,PC寄存器指向了下一条指令的地址,指令为“SETB P1.0”(对P1口的第0位设置为1),P1寄存器的值由原来的FF变换为FE。

源代码

单步跳过第2条语句,P1口第0位被赋值为高电平,发光二级管熄灭。观察寄存器窗口,PC寄存器指向了下一条指令的地址,指令为“CLR P1.0”(对P1口的第0位清零),P1寄存器的值由原来的FE变换为FF。

源代码

请同学们自行完成第3、4条语句的调试,并观察发光二极管和寄存器的状态。

实验小结

通过这次实验,掌握了嵌入式程序源代码级的调试过程,由keil编写嵌入式程序,使用proteus执行嵌入式程序的源代码级调试。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分