共2条
1/1 1 跳转至页
c51 请问用c51编写一个精确延时的程序?

问
精确到微秒~
大虾赐教~~ 答 1: re精确延时用_nop_()函数;不过前面要加#include <intrins.h>. 答 2: 如下:n = DelayValue;
for(i = n; i != 0;i--)
;
第二个表达式采用不等式时,反汇编后是:
mov r7,#n
djnz r7,$
如想长延时,可在循环中加_nop()_; 答 3: _nop_()这个函数是什么库里大?周期是多少阿? 答 4: 可以看一下这个:51单片机 Keil C 延时程序的简单研究http://www.c51bbs.com/show.aspx?id=85&cid=9 答 5: 干吗不用TIMER? 答 6: 可以精确到us的延时程序:#define uint unsigned int
//---------------------------------------------------------------------------//
void delay(uint x)
{
uint i,j; //
for (i=0; i<x;i++) { //
for (j=0; j<36; j++) ; //j变化1 相差 8 个机器周期/每x ( j=(?Khz*12-20)/8 )
//j=(?Khz*12-20)/8 )6MHz时j=60;3.6864MHz时j=36;
_nop_();_nop_();_nop_();_nop_();_nop_(); //修正到 500个机器周期/每x
}
}
//
//(机器周期数)(j=10)无_nop_行: 有_nop_行;(j=60)有_nop_行:(6MHz)
// delay(2); //206 216 1016
// delay(1); //110 115 515
// delay(2); //205 215 1015
// delay(3); //300 315 1515
// delay(4); //395 415 2015
// delay(5); //490 515 2515
// delay(6); //585 615 3015
// delay(7); //680 715 3515
// delay(8); //775 815 4015
// delay(9); //870 915 4515
// delay(10); //965 1015 5015
//---------------------------------------------------------------------------//
void dlus (unsigned char us)//us=(实际延时-5)/2
{ //us=1:7;2:9;3:11;4:13;5:15;6:17;9:19;10:21周期
while(--us); //5 +n*2 DJNZ R7,dlus RET
// while(us){us--;} //8 +n*6
// for (;--us>0;); //5 +n*6
// for (;us>0;us--); //10+n*8
// unsigned char i;for (i=0;i<us;i++); //12+n*8
}
答 7: 实际上精确到us是有困难的,因为任何中断都会使延时时间增加就算用查询定时器的方法也会有误差的,因为受到查询间隔及中断响应时间的影响 答 8: 在设定定时值的时候要考虑到中断处理的影响还必须注意:使用精确定时的时候要关闭高优先级中断!使用100US延时做时间片(TIME SLICE),是常用的技巧。
大虾赐教~~ 答 1: re精确延时用_nop_()函数;不过前面要加#include <intrins.h>. 答 2: 如下:n = DelayValue;
for(i = n; i != 0;i--)
;
第二个表达式采用不等式时,反汇编后是:
mov r7,#n
djnz r7,$
如想长延时,可在循环中加_nop()_; 答 3: _nop_()这个函数是什么库里大?周期是多少阿? 答 4: 可以看一下这个:51单片机 Keil C 延时程序的简单研究http://www.c51bbs.com/show.aspx?id=85&cid=9 答 5: 干吗不用TIMER? 答 6: 可以精确到us的延时程序:#define uint unsigned int
//---------------------------------------------------------------------------//
void delay(uint x)
{
uint i,j; //
for (i=0; i<x;i++) { //
for (j=0; j<36; j++) ; //j变化1 相差 8 个机器周期/每x ( j=(?Khz*12-20)/8 )
//j=(?Khz*12-20)/8 )6MHz时j=60;3.6864MHz时j=36;
_nop_();_nop_();_nop_();_nop_();_nop_(); //修正到 500个机器周期/每x
}
}
//
//(机器周期数)(j=10)无_nop_行: 有_nop_行;(j=60)有_nop_行:(6MHz)
// delay(2); //206 216 1016
// delay(1); //110 115 515
// delay(2); //205 215 1015
// delay(3); //300 315 1515
// delay(4); //395 415 2015
// delay(5); //490 515 2515
// delay(6); //585 615 3015
// delay(7); //680 715 3515
// delay(8); //775 815 4015
// delay(9); //870 915 4515
// delay(10); //965 1015 5015
//---------------------------------------------------------------------------//
void dlus (unsigned char us)//us=(实际延时-5)/2
{ //us=1:7;2:9;3:11;4:13;5:15;6:17;9:19;10:21周期
while(--us); //5 +n*2 DJNZ R7,dlus RET
// while(us){us--;} //8 +n*6
// for (;--us>0;); //5 +n*6
// for (;us>0;us--); //10+n*8
// unsigned char i;for (i=0;i<us;i++); //12+n*8
}
答 7: 实际上精确到us是有困难的,因为任何中断都会使延时时间增加就算用查询定时器的方法也会有误差的,因为受到查询间隔及中断响应时间的影响 答 8: 在设定定时值的时候要考虑到中断处理的影响还必须注意:使用精确定时的时候要关闭高优先级中断!使用100US延时做时间片(TIME SLICE),是常用的技巧。
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
“我踩过的那些坑”主题活动——第001期 | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
分享汽车通信和多媒体总线结构被打赏20分 | |
【我踩过的那些坑】结构堵孔导致的喇叭无声问题被打赏50分 | |
NUCLEO-U083RC学习历程38+串口通过队列的方式输出两个字符串被打赏20分 | |
【我踩过的那些坑】分享一下调试一款AD芯片的遇到的“坑”被打赏50分 | |
电流检测模块MAX4080S被打赏10分 | |
【我踩过的那些坑】calloc和malloc错误使用导致跑飞问题排查被打赏50分 | |
分享电控悬架的结构与工作原理(一)被打赏20分 | |
多组DCTODC电源方案被打赏50分 | |
【我踩过的那些坑】STM32cubeMX软件的使用过程中的“坑”被打赏50分 | |
新手必看!C语言精华知识:表驱动法被打赏50分 |