本帖最后由 杨为民 于 2024-10-14 19:35 编辑
(1)用C51语言编写51单片机程序,软件延迟函数是最基本的函数之一,通常是用空循环语句来实现。 (2)用C51语言编写的延迟函数有一个重要的缺点就是其延迟时间依赖于C51项目的编译模式和优化等级。Small的编译模式将循环变量安排在DATA空间,Large的编译模式将循环变量安排在XDATA空间,即使对同一个C语言延时函数的它们的运行时间是不同的。优化等级也会影响延迟时间,最极端的情况是将延迟函数的全部局部变量优化在寄存器中,这时由于不涉及内存变量存取,延迟函数的运行速度最快。 (3)因此最通用的软件延迟函数应该是用汇编语言编写的,这样就不会受编译模式和优化等级的影响了。本文介绍一种在C51程序中用内嵌汇编语言方式编写的毫秒和微秒软件延迟函数。 (4)下图是对AI8051U单片机的8Bit模式写的毫秒软件延迟函数的具体程序: 其中第42行是以KHz为单位的单片机运行主频。 (5)该函数的参数MS是16位无符号整数,因此该函数的最大延迟时间是65535毫秒=65.535秒,对一般应用是足够了。 (6)该函数采用双层循环的方法来实现,外层循环的次数就是要延时的毫秒数,内层循环的次数是对应主频下消耗1毫秒时间需要进行的循环次数。内层循环次数R2R3由第57和58行计算,其中的除数10是根据实际测试得到的。 (7)在AI8051U单片机上对上面毫秒延迟函数的延时精度测试结果如下: 给定值(毫秒) 测试值(毫秒) 1.000 1.00091 5.000 5.00200 10.000 10.0045 50.000 50.0207 100.000 100.051 500.000 500.205 这个测试结果表明该毫秒软件延时函数的精度高于1%。
(8)微秒级的延迟在单片机对低速外设的输入输出函数中也是必须的,它用于维持外部总线信号以便外设能正确读取和等待外设信号稳定后再读。本文介绍的微秒级软件延迟函数也是用双层空循环的方法实现的。 (9)下图是对AI8051U单片机的8Bit模式写的微秒软件延迟函数的具体程序: 其中内层循环次数R2由第94行程序计算,其中的除数3500是根据实际测试得到的。 同样该函数的参数uS是16位无符号整数,因此该函数的最大延迟时间是65535微秒=65.535毫秒,可以与上面的毫秒延迟函数进行衔接了。 (10)在AI8051U单片机上对上面微秒延迟函数的延时精度测试结果如下: 给定值(微秒) 测试值(微秒) 1.000 1.5833 5.000 5.467 10.000 10.000 50.00 47.333 100.00 94.000 500.00 467.25 (11)测试结论:对于微秒软件延迟函数而言,由于除了双层延迟循环外,还附加了调用函数对参数的赋值和对函数的访问等额外指令,所以对16位这样大范围的延迟函数是难以在全程范围都准确的。
(12)考虑到51单片机大多数低速外设的信号速度在100KHz左右,因此本文第94行程序内循环次数的计算公式中的除数是根据10微秒校准的。
|