6850|17

80

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

ATmega16的延时问题 [复制链接]

void Delayms(unsigned char  MS)                  //延时程序
{
unsigned char i,j;
for( i=0;i    
      for(j=0;j<1141;j++);
}

一个for循环要几个机器周期啊,1141怎么算出来的, 怎么算就成1000us了呢

最新回复

还是要用time中断  详情 回复 发表于 2010-2-19 18:05
点赞 关注

回复
举报

78

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
这个咋算也不准确的 C要导成汇编的 如果要精确延时 最好用定时  或者内嵌汇编
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
查看一下生成的汇编文件就可以算出来了
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

4
 
void delay(uint ticks)
{
uchar i;
while(ticks--)for(i=100;i!=0;i--);//约0.1mS
}

首先那些延时程序 都是大家的经验值,最后有人共享,之后大家都一起拿来就用。
而且这些延时 都是大体的延时。 一般多用于要求精度不是很高的应用里。

如果楼主真想弄到114是怎么来的?
最简单的办法 用示波器测试,现在很多人都不愿把C转成汇编,再计算时钟周期与机械周期,都是直接拿示波器测量,根据测量获得一个非常准确的值。

利用仪器最方便 与简单。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

5
 
看你用在什么场合啦?

如果用于点亮小灯的那种,对时序要求不高的,可以不用定时器,就这么拼凑也行
但如果用在时序要求比较高的场合,就不能这么轻率了。就要用定时器中断,确保精确。
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

6
 

用AVRStudio
在进入延时函数的入口设置断点,仿真运行,两次中断的间隔周期数可以看出来。再除以系统时钟,就是循环一次的时间。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

7
 
刚看了一下,你定义的变量i和j都是unsigned char 类型的。在AVR里面应该是0-255。不会大到1141,所以这段程序有问题
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

8
 
首先得看你用的是外部晶振还是内部晶振,晶振的频率是多少,然后乘上1141即可,循环一次,一个时机器周期,另外你的类型也有问题,i,j应该申明成uint16类型
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

9
 
引用 7 楼 wgain 的回复:
首先得看你用的是外部晶振还是内部晶振,晶振的频率是多少,然后乘上1141即可,循环一次,一个时机器周期,另外你的类型也有问题,i,j应该申明成uint16类型


学校刚出来的吧,错得有点离谱哈。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

10
 
就是拿示波器测出来的
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

11
 
如果真的要计算
还是要反汇编之后
才能精确计算

楼主这个1141
不出意外肯定是软件仿真出来的
比如用AVR STUDIO软件
设置断点,然后一点点测试出来的
这个如果设置了正确的晶振频率
软件仿真出来的延时时间
虽然不是精确时间
但也凑合着可以

楼主这个j定义的着实有点。。。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

12
 
如果非要计算的话
反汇编之后
查一下指令系统
每条汇编指令
对应几个机器周期
每个机器周期对应几个时钟周期
时钟周期通过晶振频率确定
理论上也是可以精确计算出来的
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 6 楼 lin0119 的回复:
刚看了一下,你定义的变量i和j都是unsigned char 类型的。在AVR里面应该是0-255。不会大到1141,所以这段程序有问题

还好意思说人家!那个MS只是定多少个1ms的!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

14
 
呃...
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

15
 
用汇编吧.下面是我以前玩AVR时常用的.保存成M8_delay_110592.asm.(如果用8M,12M,16M等整数的晶体就更加精确)

/**************************************************

        延时子程序
        系统时钟=11.0592
        使用R25(高):R24(低)传送参数
        R25:R24内容不改变

**************************************************/

.DEF DELAY_L = R24
.DEF DELAY_H = R25
.DEF DELAY_TEMP = R16

/////////////////////////
//
//        1微秒
//        11.0592M
//
DELAY_1US:
        RJMP DELAY_1US_NEXT1                //2时钟周期*2+7==11个时钟周期,运行时间约1us
DELAY_1US_NEXT1:
        RJMP DELAY_1US_EXIT
DELAY_1US_EXIT:
        RET

//////////////////////////////////////////
//
//        延时程序
//        延时量R25(高):R24(低)
//        最少延时3微秒,最多65535微秒(65.535毫秒)
//        系统时钟=11.0592M
//
DELAY_US:
        PUSH DELAY_H
        PUSH DELAY_L
        PUSH DELAY_TEMP
        IN DELAY_TEMP,SREG
        PUSH DELAY_TEMP
        SBIW DELAY_L,3
        BRCS DELAY_US_EXIT0                //小于3退出
        BREQ DELAY_US_EXIT1                //等于3退出

        LDI DELAY_TEMP,17                        //实际上是每16.89个偱环要加多一个NOP
DELAY_US_LOOP:
        RJMP DELAY_US_NEXT0
DELAY_US_NEXT0:
        DEC DELAY_TEMP
        BRNE DELAY_US_LOOP_NEXT
        RJMP DELAY_US_LOOP_NEXT        //本来是两条NOP指令,但为了节省程序空间,改用一条RJMP指令(这条指令使用两个时钟周期,但只使用一个字的储存空间)
DELAY_US_LOOP_NEXT:
        SBIW DELAY_L,1
        RJMP DELAY_US_LOOP_NEXT1
DELAY_US_LOOP_NEXT1:
        BRNE DELAY_US_LOOP

DELAY_US_EXIT0:
        NOP
DELAY_US_EXIT1:
        NOP
        RJMP DELAY_US_NEXT1
DELAY_US_NEXT1:
        RJMP DELAY_US_NEXT2
DELAY_US_NEXT2:
        POP DELAY_TEMP
        OUT SREG,DELAY_TEMP
        POP DELAY_TEMP
        POP DELAY_L
        POP DELAY_H
        RET

//////////////////////////////////////////////////
//
//        1毫秒
//        每次延时会增加25个时钟周期的损耗
//        使用R25:R24传送参数,返回时R25:R24中的值不变
//
DELAY_MS:
        PUSH DELAY_H
        PUSH DELAY_L
        PUSH DELAY_TEMP
        IN DELAY_TEMP,SREG
        PUSH DELAY_TEMP

DELAY_MS_LOOP0:
        PUSH DELAY_H
        PUSH DELAY_L
        RJMP DELAY_MS_NEXT1
DELAY_MS_NEXT1:
        RJMP DELAY_MS_NEXT2
DELAY_MS_NEXT2:
        RJMP DELAY_MS_NEXT3
DELAY_MS_NEXT3:
        RJMP DELAY_MS_NEXT4                //这4个指令是为了产生8个时钟周期的损耗
DELAY_MS_NEXT4:
        LDI DELAY_H,HIGH(1008)
        LDI DELAY_L,LOW(1008)
        RCALL DELAY_US
        POP DELAY_L
        POP DELAY_H
        SBIW DELAY_L,1
        BRNE DELAY_MS_LOOP0

        POP DELAY_TEMP
        OUT SREG,DELAY_TEMP
        POP DELAY_TEMP
        POP DELAY_L
        POP DELAY_H
        RET

/*********************************************************

        以上延时程序共使用42个字(82字节)的程序储存空间

*********************************************************/

 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

16
 
AVR GCC上有精确延时函数_delay_us与_delay_ms
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

17
 
这个是测试出来的
如果要精确延时的话 还是用TIME中断延时
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

18
 
还是要用time中断
 
 
 

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

猜你喜欢
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条
电源解决方案和技术 | DigiKey 应用探索站
当月好物、电源技术资源、特色活动、DigiKey在线实用工具,干货多多~

查看 »

 
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
快速回复 返回顶部 返回列表