7330|21

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

LPC单片机延时异常(LPC21xx,LPC2300)--欢迎高手指点 [复制链接]

小弟在使用LPC21xx及LPC2300系列单片机遇到点棘手的问题,用C做一段延时程序时,当程序代码放置于不同的地址将导致延时不确定,就是说同样的代码放置的地址不一样可能导致延时不一样,百思不得其解,而且代码都运行于通一个类型的存储区域,以下为扑捉的C代码图片、汇编代码图片,以及抓到的引脚输出波形。
使用的是周立功的工程模板,ADS1.2编译器,AXD仿真,在进入循环前已禁止所有中断,通过示波器检测NRF_CLK2引脚的变化来查看延时时间,可以看到示波器抓到的图片有三段(3个100us)较长,紧跟的三段较短,并周期性循环。正常的100us在不正常的时候大概为66us,汇编代码也是完全一样的。
有哪位兄台碰到过类似问题吗?
C:\Documents and Settings\Administrator\桌面\C代码1
C:\Documents and Settings\Administrator\桌面\反汇编代码1
C:\Documents and Settings\Administrator\桌面\C代码2
C:\Documents and Settings\Administrator\桌面\反汇编代码2
C:\Documents and Settings\Administrator\桌面\捕获波形

最新回复

呵呵,好的,我再试下。你的意思让他从4字边界上开始就不会因为MAM加速的时候导致延时的不确定了? 因为MAM预取址是为4字的。  详情 回复 发表于 2009-12-27 11:47
点赞 关注

回复
举报

74

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
图片没有 ,马上传
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
建议使用定时器做延时.
软件延时会受以下几方面影响:
1. 编译器优化程度.
2. 主芯片频率.
3. 中断.
4. 函数调用开销.


你把程序修改下..复制多个延时代码段, 而不是通过循环调用同一个延时代码段, 如:
由形式:
for(i = 0; i < n; i++)
    DELAY();
改为:
    DELAY();
    DELAY();
    DELAY();
    DELAY();
    DELAY();
    DELAY();
形式,  DELAY最好写成宏, 再测试IO速度.
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

4
 
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

5
 



 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

6
 
请问楼上你回答前看到图片了吗?
采用软件延时是因为对延时的精确度要求不是很高
而且方便其他地方调用,并且测试延时时工作频率一样,中断已关,   函数调用开销也不会导致较大误差。
现在的情况是延时100us有时可能只有66us,而有时候又是100us,而且同样的代码,只是函数名不一样,有时候也会导致误差。
谢谢你的回答,我也是打算用定时器延时,不过这个问题的根源还得找出来。
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

7
 
根据我的分析是你示波器测量的I/O脚(也就是你用来输出延时的pin)被重复使用了,也就是这个pin可能被程序中的其他部分的代码所控制,中间的66us就是因此而产生的(66.666*3 = 200),所以应该重点看一下是否有这种情况,也许你的程序中没有复用,但要考虑系统中的其它程序(比如调试系统等)是否用了此pin.
 
 
 

回复

63

帖子

0

TA的资源

禁止发言

8
 
用如下代码测试下:
#deifne DELAY_TEST() SET_NRF24_CLK2(); \
for(j = 0; j < 800; j++); \
CLR_NRF24_CLK2();

// 注意不要用循环来调用.
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();
DELAY_TEST();

以前看到某个MCU厂商测试IO翻转速度时就是以这种形式测试的.
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

9
 
感谢楼上两位的帮助,
1.引脚为LPC2300--P0.24脚
2.程序中断已经屏蔽,快速中断,慢速中断都禁止了,而那是一个死循环,不可能存在其他调用
3.我用IO脚的变化来测我延时函数是否准确,但是还不需要精确到IO的翻转速度也需要计算在内,因为一些芯片的驱动是需要严格按照时序的,比如上电需延时300us,那么如果只延时了200us就会出现问题。我追究这个问题的根源是因为我本来调好的延时100us的函数,在我增加了一些应用代码后有可能导致延时100us函数变成延时66us了,当再增加一些代码又可能回复到100us,而只要代码不更改,延时100us就不会变成延时66us,延时66us也不会变成100us,只有当代码增加或者减少,可能导致这一个函数的实际延时变化,并可以确定增加和减少的代码毫不影响这个延时函数。
4.上面两个延时函数Delay_100us11()和Delay_100us22()只是名字不一样,里面的代码完全一样,为什么会导致这样的现象?
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

10
 
楼主的代码是用两样的编译参数进行编译的吗?从现象描述上看似乎是用不同的参数编译了两个函数,而从给的代码上看又不是这样的,楼主可以再给些背景资料吗?
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

11
 
引用 8 楼 qusongsong1 的回复:
3.我用IO脚的变化来测我延时函数是否准确,但是还不需要精确到IO的翻转速度也需要计算在内,因为一些芯片的驱动是需要严格按照时序的,比如上电需延时300us,那么如果只延时了200us就会出现问题。我追究这个问题的根源是因为我本来调好的延时100us的函数,在我增加了一些应用代码后有可能导致延时100us函数变成延时66us了,当再增加一些代码又可能回复到100us,而只要代码不更改,延时100us就不会变成延时66us,延时66us也不会变成100us,只有当代码增加或者减少,可能导致这一个函数的实际延时变化,并可以确定增加和减少的代码毫不影响这个延时函数。


还是要从你增加的代码里面找问题
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

12
 
编译参数都是一样的,我增加的代码页很简单,比如置高P0.23,有时候就会导致延时结果不一样。
while(1)
{
    Delay_100us11(3);
    Delay_100us22(3);
}
这个循环里面是两个名字不一样的函数,但是实际代码是完全一样的,可以看上面的截图
进入函数里面会有三次for(j=0;j<800;j++);执行完后产生一个低脉冲,示波器截图里面的红色框框里面的前三个低脉冲就是执行Delay_100us11(3);产生的,他们的平均宽度是66us,橙色框框里面的三个脉冲是Delay_100us22(3);函数产生的,也是执行三个for(j=0;j<800;j++);循环,但是这三个脉冲的间隔是100us,明显的比前面那三个脉冲的宽度要宽。。。
这是什么原因导致的两个一样的循环,但是延时是不一样的?
 
 
 

回复

55

帖子

0

TA的资源

一粒金砂(初级)

13
 
综上所述,你的Delay_100us11及Delay_22us应该是完全一致的。

我认为你的程序中的输出方式可能有问题,考虑一下你的外循环内的最后一条语句和第一条语句,先复位再置位,如果外循环没有结束,这两个语句(clr和set)之间的时间极短,生成的波形宽度极短,很可能你的示波器都没办法将这么窄的东西捕获并显示,同样的问题也出现在Dealy_100us11结束和Delay_11us22开始时,所以建议你不要用这种方式来显示(输出高低电平)。

建议你只在外循环的的开始或结束处用一条将P0.24变反语句来测试你的循环时间是否正确。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

14
 
示波器的扑捉应该是没有问题的,P0.24放在函数外面置位也是一样,只不过没有了三个低脉冲,如下图所示的一个波形
_________      _________      _________      _________
         ______         ______         ______         ______

呵呵 都不知道咋整了,感觉应该跟延时函数在内存中的存放位置有关系
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

15
 
晕,下划线没对上,下面一行的下划线在上面下划线的空白处
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

16
 
猜测.....你的MCU内的程序存储器是分页的,如果在同一个页内部,访问会快一些,如果跨越页面访问,要慢一些.....纯属猜测,没有根据.
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

17
 
NXP的ARM7有个MAM模块,你把它关闭了再试试...
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

18
 
..........你的示波器波形.....好像并没锁定......
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

19
 
感谢Great兄,果然是高手中的高手!
就目前的情况应该是MAM加速出了问题,因为得我MCU使用的是60M以上的频率,然后可能因为MAM的加速导致了系统在需要精确延时的时候不稳定,目前我在延时函数的开始关闭MAM,当结束延时后再打开MAM加速,暂时还没有发现问题,在后期还需要继续观察会不会有不稳定的现象出现。
虽然目前现象没有了,但是我感觉还需要继续观察,呵呵,因为又发现了一个异常问题:for (j=0;j<342;j++);当我把342改为361,延时为324us,当我把342改为360,延时为288us,但是小于360的时候,比如342,延时为300us。。。。。。就是说在360这个地方导致延时不是线性的,但是大于360和小于360又恢复为线性的。。。。调试中偶然发现的这个问题。

再次感谢Great_Bug兄弟,感谢ID6886兄弟,感谢FLandY1982兄弟。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

20
 
怎么看出来示波器波形没锁定?锁定了的
因为是在驱动一个芯片的时候发现的延时函数延时不确定,比如延时300us,有时候就成了延时200us了,所以才用示波器抓波形来验证的,折腾了我蛮久的。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表