14962|28

3836

帖子

19

TA的资源

纯净的硅(中级)

楼主
 

C51精确延时,绝对精确! [复制链接]

有些特殊的应用会用到比较精确的延时(比如DS18B20等),而C不像汇编,延时精准度不好算。本人经过反复调试,对照KEIL编译后的汇编源文件,得出了以下几条精确延时的语句(绝对精确!本人已通过实际测试),今天贴上来,希望对需要的朋友有所帮助。

  1. sbit LED  =  P1^0;      // 定义一个管脚(延时测试用)
  2. unsigned int i = 3;     // 注意i,j的数据类型,
  3. unsigned char j = 3;    // 不同的数据类型延时有很大不同
  4. //-----------------各种精确延时语句-----------------------------------
  5. while( (i--)!=1 );      // 延时10*i个机器周期
  6. i = 10; while( --i );   // 延时8*i+2个机器周期
  7. i = 10; while( i-- );   // 延时(i+1)*9+2个机器周期
  8. j = 5;  while( --j );   // 延时2*j+1个机器周期
  9. j = 5;  while( j-- );   // 延时(j+1)*6+1个机器周期

  10. i = 5;  
  11. while( --i )            // 延时i*10+2个机器周期,在i*10+2个机器周期
  12. if( LED==0 )  break; // 内检测到LED管脚为低电平时跳出延时

  13. i = 5;
  14. while( LED )            // 每隔10个机器周期检测一次LED管脚状态,当LED
  15. if( (--i)==0 ) break;// 为低时或者到了10*i+2个机器周期时跳出延时
  16. //--------------------------------------------------------------------

  17. 例如18b20的复位函数(12M晶振):
  18. //***********************************************************************
  19. // 函数功能:18B20复位
  20. // 入口参数:无
  21. // 出口参数:unsigned char x: 0:成功 1:失败
  22. //***********************************************************************
  23. unsigned char ow_reset(void)
  24. {
  25. unsigned char x=0;  // 12M晶振 1个机器周期为1us
  26. DQ = 1;   // DQ复位
  27. j = 10;  while(--j);// 稍做延时(延时10*2+1=21个机器周期,21us)
  28. DQ = 0;   // 单片机将DQ拉低
  29. j = 85;  while(j--);// 精确延时(大于480us) 85*6+1=511us
  30. DQ = 1;   // 拉高总线
  31. j = 10;  while(j--);// 精确延时10*6+1=61us
  32. x = DQ;   // 稍做延时后,
  33. return x;   // 如果x=0则初始化成功 x=1则初始化失败
  34. j = 25;  while(j--);// 精确延时25*6+1=151us
  35. }
  36. //*********************************************************************************
复制代码


再如红外解码程序:
(先说传统红外解码的弊端:
程序中用了while(IR_IO);while(!IR_IO);这样的死循环,如果管脚一直处于一种状态,就会一直执行while,造成“死机”现象。当然这种情况很少,但我们也的考虑到。而用以下程序则不会,在规定的时间内没有正确的电平信号就会返回主程序,这样就不会出现“死机”了)

  1. //***************************外部中断0*******************************
  2. void int0(void) interrupt 0
  3. {
  4. unsigned char i,j;
  5. unsigned int count = 800;
  6. //--------------8.5ms低电平引导码-------------------------------------
  7. while( --count )
  8. if( IR_IO==1 )      return;   // 在小于8ms内出现高电平,返回
  9. count = 100;                     // 延时1ms
  10. while( !IR_IO )                  // 等待高电平
  11. if( (--count)==0 )  return;   // 在9ms内未出现高电平,返回
  12. //-------------4.5ms高电平引导码------------------------------------
  13. count = 410;                     // 延时4.1ms
  14. while( --count )                 // ...
  15. if( IR_IO==0 )      return;   // 在4.1ms内出现低电平,返回
  16. count = 50;                      // 延时0.5ms
  17. while( IR_IO )                   // 等待低电平
  18. if( (--count)==0 )  return;   // 在4.7ms内未出现低电平,返回
  19. //-----------------------------------------------------------------
  20. //------------4个数据码------------------------------------
  21. for( j=0;j<4;j++ )
  22. {
  23. for( i=0;i<8;i++ )
  24. {
  25. IR_data[j] <<= 1;                // 装入数据
  26. count = 60;                      // 延时0.6ms
  27. while( !IR_IO )                  // 等待高电平
  28. if( (--count)==0 )   return;  // 在0.6ms内未出现高电平,返回
  29. count = 40;                      // 低电平结束,继续
  30. while( --count )                 // 延时0.4ms
  31. if( IR_IO==0 )       return;  // 在0.4ms内出现低电平,返回
  32. count = 100;                     // 延时1.4ms
  33. while( IR_IO )                   // 检测IO状态
  34. if( (--count)==0 )            // 等待1.4ms到来
  35. {                             // 在1.4ms内都是高电平
  36. IR_data[j] |= 1;           // 两个单位高电平,为数据1
  37. break;                     // 跳出循环
  38. }
  39. count = 20;                      // 延时0.2ms
  40. while( IR_IO )                   // 等待低电平跳出
  41. if( (--count)==0 ) return;    // 0.2ms内未出现低电平,返回
  42. }
  43. }
  44. //-------------------------------------------------------------------
  45. flag_IR = 1;                           // 置位红外接收成功标志
  46. }
复制代码
此帖出自51单片机论坛

最新回复

  详情 回复 发表于 2013-7-31 17:09

点评

eie
非常棒,非常感谢!  详情 回复 发表于 2013-7-31 02:30
好极了,雪中送碳,夏天送冰!  详情 回复 发表于 2013-7-30 21:03

赞赏

1

查看全部赞赏

点赞 关注(1)
 

回复
举报

43

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
支持楼主,谢谢分享
此帖出自51单片机论坛
 
 
 

回复

42

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

先顶后看

先顶后看
此帖出自51单片机论坛
 
 
 

回复

12

帖子

0

TA的资源

一粒金砂(初级)

4
 
经典
此帖出自51单片机论坛
 
个人签名study
 
 

回复

11

帖子

0

TA的资源

一粒金砂(初级)

5
 
好东西,顶
此帖出自51单片机论坛
 
 
 

回复

203

帖子

0

TA的资源

一粒金砂(中级)

6
 
此帖出自51单片机论坛
 
个人签名新人上道,努力学习!
 
 

回复

73

帖子

0

TA的资源

一粒金砂(高级)

7
 
学习了
此帖出自51单片机论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

8
 
经典!谢谢楼主分享!
此帖出自51单片机论坛
 
 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

9
 

原创精品,经验之说啊!

此帖出自51单片机论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

85

帖子

0

TA的资源

一粒金砂(高级)

10
 
支持楼主,谢谢分享
此帖出自51单片机论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

11
 
初学者,反正我现在还不懂得,先捡下来了,非常感谢。
此帖出自51单片机论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

12
 
dingle.................
此帖出自51单片机论坛
 
 
 

回复

129

帖子

0

TA的资源

一粒金砂(中级)

13
 
谢谢分享
平时写的时候总是习惯用i--
此帖出自51单片机论坛
 
个人签名我一直在努力着。。。
 
 

回复

7219

帖子

192

TA的资源

五彩晶圆(高级)

14
 
MARK好东西
此帖出自51单片机论坛
 
 
 

回复

186

帖子

0

TA的资源

纯净的硅(中级)

15
 
支持楼主……
此帖出自51单片机论坛
 
 
 

回复

22

帖子

0

TA的资源

一粒金砂(中级)

16
 
嗯,很详细,有收藏价值,但不晓得是否真的可行,有待一试
此帖出自51单片机论坛
 
 
 

回复

140

帖子

0

TA的资源

一粒金砂(初级)

17
 
呵呵 不错   顶一下。。
此帖出自51单片机论坛
 
个人签名广交朋友!!!
 
 

回复

90

帖子

0

TA的资源

一粒金砂(中级)

18
 

学习

刚刚开始学习单片机,虽然还看不太明白,可楼主的精神深深的感动着我。无私的奉献。
此帖出自51单片机论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

19
 

好东西,收藏一下

此帖出自51单片机论坛
 
 
 

回复

38

帖子

0

TA的资源

一粒金砂(中级)

20
 
不敢说好,一旦开了中断全都不能用
此帖出自51单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

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