当前位置:首页 > 单片机 > 单片机
[导读]浅谈单片机调试方法

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 cycles,1 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/O,LED,示波器,数码管或LCD显示,给出各种各样的提示信息,帮助我们调试程序。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭