共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网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |