
如果想精确延时,一般需要用到定时器,延时时间与晶振有关系,单片机系统一般常选用11059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。
SysTick 就是一个定时器而已,只是它放在了NVIC(嵌套中断控制器)中,主要的目的是为了给 *** 作系统提供一个硬件上的中断(号称滴答中断)。
滴答中断: *** 作系统进行运转的时候,也会有“心跳”。
它会根据“心跳”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统不放。
这个心跳,可以通过定时器来周期性触发,而这个定时器就是systick。很明显,这个“心跳”是不允许任何人来随意地访问和修改的。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。
{
SysTick_Current=0; //当前值为0
SysTick_Reload=72000; //重装载寄存器,系统时钟72M,中断一次1mS(1ms=0001s=1/72M72000)
TimingDelay =nTime; // 读取延时时间
SysTick_CSR=0x07; // 使能SysTick计数器
while(TimingDelay!= 0); // 判断延时是否结束
SysTick_CSR=0x06;// 关闭SysTick计数器
}
void Delay_Nus(uint32_t nTime) //us级的延时函数
{ SysTick_Current=0;
SysTick_Reload=72; //重装载寄存器,系统时钟20M中断一次1mS
TimingDelay=nTime;
SysTick_CSR=0x07; // 使能SysTick计数器
while(TimingDelay!= 0); // 判断延时是否结束
SysTick_CSR=0x06;// 关闭SysTick计数器 }
一般来说要是通过延时函数来得到一个精准的延时时间(比如你说的1us、2us)是让正常人无法忍受的工作量,你可以点击编辑环境中的放大镜图标,在左边会d出显示栏,sys下sec就是延时时间(要通过设置断点),你可以改变函数中变量值大概地调出需要的时间(希望你不要固执地去尝试调出你要的时间,因为这会让你享受到一天都不止的漫长调试“乐趣”中)。晶振频率不同自然在相同参数的情况下得出延时时间不同。另外如果你确实需要得到一个比较精准的延时时间,建议你采用定时/计数器,至于怎么用这玩意儿,很简单!不到十分钟就能学会的事儿!这里就不提供教程了,用你调试的时间去学它会让你更有成就感。写了那么多,希望能帮助点什么应该是 12MHz 吧?单片机内部,计时的单位是《机器周期T》。
下面是每条指令执行时,所用的周期数:
MOV R1,#60 1T
F: MOV R3,#248 1T
DJNZ R3,$ 2T
DJNZ R1,F 2T
RET 2T
下面是程序循环时所用的周期数:
MOV R1,#60
F: MOV R3,#248
DJNZ R3,$ 2 248 = 496 T
DJNZ R1,F (2 + 496 + 1) 60 = 29940T
RET 2 + 29940 + 1 = 29943T
总共是: 29943T。
如果是 12MHz,时间就是:29943us。
另外,执行这个程序,还需要一条 CALL 指令,应该再加上 2T。
--怎么样实现5S的延时?
慢慢算呗。如果单片机晶振为6M,机器周期即为2us=12/fosc
汇编语句对时间的把握精确于C语言,所以参考不同指令的长度,
就可以算出你的延迟时间。
单片机的延时程序:
MOV
R7,#200
LOOP1:MOV
R6,#125
LOOP2:DJNZ
R6,LOOP2
DJNZ
R7,LOOP1
RET
第一句为单周期指令,耗时2us
第二句执行了200次,耗时2200us
第三句为双周期指令,执行了125200次,耗时22125200us
第四句同第三句,耗时22200us
第五句双指令周期
总够耗时2+2200+22125200+22200+22
约为100ms理论上说,可以无限的。用的是循环嵌套, 比如 定时器1 延时了5000ms 产生中断 可以计数。 a++ 到a到你的制定值就可以了,a装不下的话 到了比如说50000 可以计数b++ a=0 以此类推
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)