打印

浅谈单片机调试方法(希望对初学者有帮助)

[复制链接]
5273|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fushaobing|  楼主 | 2011-2-1 11:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 fushaobing 于 2011-2-1 11:14 编辑

浅谈单片机调试方法(希望对初学者有帮助)

傅绍兵 2011-01-31

1.     利用I/O
1.1   利用LED进行可视化管理
    这种方法需要有多余的I/O。(如果可能,也可以将实现次要功能的I/O暂时借来一用。)
其电路很简单,一个LED通过限流电阻接到VCC电源。I/O设置为输出方式。
       我们可以用下面的宏来定义LED的操作。
#define LED_YELLOW_ON()         PA6D=0
#define LED_YELLOW_OFF()        PA6D=1
#define LED_YELLOW_FLASH()    PA6D^=1
       举个例子说明它的用法。在低功耗的产品设计中,我们一般采用“睡眠à醒来工作à睡眠à醒来工作”的工作模式,其程序结构如下:
while(1)
{
    HLT = 1; //
进入睡眠

    nop();

    clear_WDT(); //
清看门狗


    //
醒来,处理各种事务

}
       如果我们在程序醒来时点亮LED,事务处理完毕时熄灭LED,那么我们就能“看见”程序的工作状态,LED将周期性地闪烁。这就是我们称之为可视化管理的原因。(不记得在哪本书上看到“可视化管理”这个概念,我借用一下)
       其软件结构是这样:
while(1)
{
    HLT = 1; //进入睡眠
    nop();

    clear_WDT(); //
清看门狗

      

    LED_YELLOW_ON(); // debug

    //
醒来,处理各种事务

    LED_YELLOW_OFF(); // debug

}
       其实有些仿真器已经提供了这种监视程序睡眠状态的方法。如果没有提供,就可以用以上方法自行实现。
       它的使用很灵活。比如可以用来在双时钟系统中监视快时钟的打开和关闭情况(慢时钟一般总是打开,因为要用作实时时钟的时钟源,而且慢时钟耗电很小)。你可以在打开快时钟时点亮LED,关闭快时钟时熄灭LED,这样一来快时钟的打开和关闭就一目了然了。
       你也可以在某个中断中将LED的状态取反(使用LED_YELLOW_FLASH()),用来监视此中断的产生是否正常。虽然设置断点也可以知道中断是否产生,但会中断程序的执行,造成不便。
       如果你想知道程序有没有执行到某个地方,你也可以将LED_YELLOW_FLASH()放到该位置。
    依次类推,你可以用这个方法观察任何你想观察的事件。
    当然你必须互斥地观察不同的事件。就是说,对于一个LED,在一次调试中,一般只能观察一个事件,否则你自己也弄不清LED的变化到底是代表发生哪一事件。
       另外,你还可以同时使用两个或者更多不同颜色的LED来监视不同的事件,前提你有多余的I/O
    不中断程序的执行,又能看到程序的执行情况,应该说是一种很有效的调试程序的方法。相比开发工具所提供的单步、断点、观察变量等调试手段,这可以算是一种有效的补充。
1.2 利用示波器测试时间
    利用上面的方法,再加一个示波器,就可以测量程序执行的时间了。(你可以自己决定接不接LED)。
       比如,在初始化程序中,在打开总中断之前,写如下代码:
LED_YELLOW_ON()
nop();
LED_YELLOW_OFF();
       使用示波器,在捕获模式下,你应该能捕获到一个脉冲,测试它的宽度,假如为30.5us。以OKI ML610Q431为例,一条nop指令包括1 cycles1 cycles包括1 system clock。这里system clock等于振荡周期。(注意,不同的单片机对cycles, system clock的定义是不同的,需要参考各自的用户手册)。
       那么我们可以这样计算振荡器的频率:1*1*(1/f)=30.5/1000000.
      f=32786Hz

       当然,如果示波器测量精度不够,可以多放几个nop指令,计算时再求平均。如果嫌示波器的捕获模式太麻烦,还可以采用循环结构,输出一串方波。比如:
while(1)
{
    LED_YELLOW_ON()
    nop();
    LED_YELLOW_OFF();
    nop();
    clear_WDT(); //清看门狗
}
       这种方法的使用也很灵活。你可以用来测试主循环的执行时间,调用某个函数所花的时间,以及某个中断处理的时间(不包括响应中断和退出中断的时间)等等。
       当你发现某些时候主循环的执行时间特别长时,可以采用逐步缩小范围的方法来找出到底是哪个函数花费时间长,有没有可能将其优化。
       下面是测试主循环执行时间的程序结构。
while(1)
{
    HLT = 1; //
进入睡眠

    nop();

    clear_WDT(); //
清看门狗
      

    LED_YELLOW_ON(); // debug

    Fun1();

    Fun2();

    Fun3();
    Fun4();
    LED_YELLOW_OFF(); // debug

}
       如果发现上面的执行时间异常(比如太长),你可以调整测试的位置,如下所示:
while(1)
{
    HLT = 1; //
进入睡眠

    nop();

    clear_WDT(); //
清看门狗

      

    Fun1();

    LED_YELLOW_ON(); // debug
    Fun2();

    Fun3();
    Fun4();
    LED_YELLOW_OFF(); // debug
}
       这样,你就可以确定执行时间过长是不是因为Fun1()引起。如果不是,则继续调整测试位置,逐个排除,直到找到真正费时的函数,对其进行分析,看看有没有可能优化。
       当然,我们还可以用两个或更多I/O对多个事件进行逻辑分析,观察他们的先后顺序以及测试其时间间隔。这种方法也很有用,很灵活。在此不详述。
2.     利用LCD进行可视化管理
    如果你的产品带LCD显示,又没有多余的IO可供调试,或者你只是想临时的调试某个功能,那么你可以临时使用LCD上的某个图标来指示某个事件。当某个事情发生时,显示该图标,否则清除该图标。
       如果想在程序运行中获得更复杂、更丰富的信息,可以对不同的事件显示不同的数值。
3.     小结
    不中断程序的执行,又能观察程序的执行情况,应该说是一种很有效的调试程序的方法。相比开发工具所提供的单步、断点、观察变量等调试手段,这可以算是一种有效的补充。
    实际上,这些调试方法很像PC应用开发的printf调试手段。它可以在不打断程序运行
的情况下,借助于I/OLED,示波器,数码管或LCD显示,给出各种各样的提示信息,帮助我们调试程序。

相关帖子

沙发
norman33| | 2011-2-1 15:22 | 只看该作者
如果没有显示部分的电路的话还可以用uart将关键数据发送到pc上调试。

使用特权

评论回复
板凳
NE5532| | 2011-2-1 16:32 | 只看该作者
个人意见这个不是叫可视化管理,而是叫盲调,另外如果是正式产品这些空余端口还是空在那里为妙,多了东西花钱不说,还要出问题。当然如果产品有显示屏和键盘之类就可以利用起来调试了。比如我调无线模块,啥都没,就一串口,一样调了。

使用特权

评论回复
地板
fushaobing|  楼主 | 2011-2-1 17:04 | 只看该作者
如果没有显示部分的电路的话还可以用uart将关键数据发送到pc上调试。
norman33 发表于 2011-2-1 15:22


谢谢补充!也是很不错的调试手段。

使用特权

评论回复
5
fushaobing|  楼主 | 2011-2-1 17:11 | 只看该作者
个人意见这个不是叫可视化管理,而是叫盲调,另外如果是正式产品这些空余端口还是空在那里为妙,多了东西花钱不说,还要出问题。当然如果产品有显示屏和键盘之类就可以利用起来调试了。比如我调无线模块,啥都没,就 ...
NE5532 发表于 2011-2-1 16:32


LED只是接在目标板上,不用于正式产品。
在程序中可以使用条件编译,调试代码仅在调试版本有效。

使用特权

评论回复
6
bd7qwmcu| | 2011-2-3 16:35 | 只看该作者
不玩没有JTAG仿真器不用的芯片了

使用特权

评论回复
7
触觉的爱| | 2011-2-4 19:06 | 只看该作者
真复杂,一般偶都是乱折腾的

使用特权

评论回复
8
numLiu| | 2011-4-2 21:54 | 只看该作者
呵呵,俺和LZ一样处在高手所谓的初级阶段。

使用特权

评论回复
9
numLiu| | 2011-4-2 21:56 | 只看该作者
这种调试方法往往只限于简单运用。

使用特权

评论回复
10
程序匠人| | 2011-4-2 22:59 | 只看该作者
关于这个问题,我曾经专门写过一些文字


程序调试(除错)过程中的一些雕虫小技(更新:2010-04-09)
https://bbs.21ic.com/icview-128517-1-1.html

使用特权

评论回复
11
xlsbz| | 2011-4-3 01:15 | 只看该作者
楼主写的看样子都是自己的心得体会

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

106

帖子

1

粉丝