延时程序在单片机系统开发中是必不可少的。如我们常用蜂鸣器声的长短来表示系统开机自检结果,蜂鸣器声的长短就离不开延时程序。延时程序分软件延时,与硬件延时。硬件延时是利用等待定时计数器溢出实现延时,这个先不讲,等讲了定时器后再讲。软件延时是利用执行空运算,占用CPU,实现延时。软件延时不太准确,用于要求不高的场合。由于51单片机的内部资源有限,很多时候还是使用软件延时。下面演示,完成STC单片机软件延时程序的过程,并完成常用延时程序的源代码。
1. 新建库文件 打开前面教程中创建的C51 Template 文件夹中Proj文件夹下的C51 Template.uvproj。创建两个新文件,分别以文件名delay.h,delay.c存入C51 Template文件夹下Library文件夹中。
2. 完成头文件
2.1 添加条件编译宏,及包含文件。在头文件中输入如下代码(程序前段注释里的内容请依自己的情况输入):
/*delay.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/07/2021
*/
#ifndef __DELYAY_H_
#define __DELYAY_H_
#include "mtype.h"
#endif
2.2 软件延时函数定义 stc15w系列单片机内部含有时钟电路,不需要外部晶振,并且可以在下载程序时设置系统时钟。在定义函数之前,先定义一个枚举,列出常用可选时钟,然后再定义延时函数。代码如下:
/*delay.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/07/2021
*/
#ifndef __DELYAY_H_
#define __DELYAY_H_
#include "mtype.h"
typedef enum
{
F11_0592MHz = 1, //11.0592MHz
F12MHz,
F18_432MHz, //18.432MHz
F20MHz,
F22_1184MHz, //22.1184MHz
F24MHz,
F27MHz,
F30MHz,
F33MHz,
F33_1776MHz //33.1776MHz
}FSYSCLOCK;
/****************************************
Function: Delay1us(FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 1us at fsclk
Example:
Delay1us(F11_0592MHz);
****************************************/
void Delay1us(FSYSCLOCK fsclk);
/****************************************
Function: Delay10us(FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 10us at fsclk
Example:
Delay10us(F11_0592MHz);
****************************************/
void Delay10us(FSYSCLOCK fsclk);
/****************************************
Function: Delay1ms(FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 1ms at fsclk
Example:
Delay1ms(F11_0592MHz);
****************************************/
void Delay1ms(FSYSCLOCK fsclk);
/****************************************
Function: Delay10ms(FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 10ms at fsclk
Example:
Delay10ms(F11_0592MHz);
****************************************/
void Delay10ms(FSYSCLOCK fsclk);
/****************************************
Function: Delayxus(ui8 x,FSYSCLOCK fsclk);
Return value: void
Discription: soft delay xus at fsclk
Example:
Delayxus(5,F11_0592MHz);
****************************************/
void Delayxus(ui8 x,FSYSCLOCK fsclk);
/****************************************
Function: Delay10xus(ui8 x, FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 10xus at fsclk
Example:
Delay10us(5,F11_0592MHz);
****************************************/
void Delay10xus(ui8 x, FSYSCLOCK fsclk);
/****************************************
Function: Delayxms(ui8 x,FSYSCLOCK fsclk);
Return value: void
Discription: soft delay xms at fsclk
Example:
Delay1ms(5,F11_0592MHz);
****************************************/
void Delayxms(ui8 x,FSYSCLOCK fsclk);
/****************************************
Function: Delay10xms(ui8 x, FSYSCLOCK fsclk);
Return value: void
Discription: soft delay 10xms at fsclk
Example:
Delay10xms(5,F11_0592MHz);
****************************************/
void Delay10xms(ui8 x, FSYSCLOCK fsclk);
#endif
3 .函数实现 STC ISP 下载工具内嵌了软件延时代码生成工具,有了这个工具就可以不用自己写代码,将生成的代码Copy下来,粘贴到自己的程序中即可。代码生成界面如下:
可以利用这个工具,完成基础延时程序。然后自己写少量代码,就可完成延时程序代码。完成后的代码如下:
/*delay.c
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/13/2021
*/
#include "delay.h"
//****************************************/
void Delay1us(FSYSCLOCK fsclk)
{
ui8 i;
switch(fsclk)
{
case F11_0592MHz: //at syslck 11.0592MHz
_nop_();
_nop_();
_nop_();
break;
case F12MHz: //at syslck 12.000MHz
_nop_();
_nop_();
_nop_();
_nop_();
break;
case F18_432MHz: //at syslck 18.432MHz
i = 2;
while (--i);
break;
case F20MHz: //at syslck 20.000MHz
_nop_();
_nop_();
i = 2;
while (--i);
break;
case F22_1184MHz: //at syslck 22.1184MHz
i = 3;
while (--i);
break;
case F24MHz: //at syslck 24.000MHz
_nop_();
_nop_();
i = 3;
while (--i);
break;
case F27MHz: //at syslck 27.000MHz
_nop_();
i = 4;
while (--i);
break;
case F30MHz: //at syslck 30.000MHz
i = 5;
while (--i);
break;
case F33MHz: //at syslck 33.000MHz
_nop_();
_nop_();
_nop_();
i = 5;
while (--i);
break;
case F33_1776MHz: //at syslck 33.1776MHz
_nop_();
_nop_();
_nop_();
i = 5;
while (--i);
break;
}
}
//End of Delay1us(FSYSCLOCK fsclk)
//****************************************/
void Delay10us(FSYSCLOCK fsclk)
{
ui8 i;
switch(fsclk)
{
case F11_0592MHz: //at syslck 11.0592MHz
_nop_();
i = 25;
while (--i);
break;
case F12MHz: //at syslck 12.000MHz
_nop_();
_nop_();
i = 27;
while (--i);
break;
case F18_432MHz: //at syslck 18.432MHz
_nop_();
_nop_();
i = 43;
while (--i);
break;
case F20MHz: //at syslck 20.000MHz
_nop_();
_nop_();
i = 47;
while (--i);
break;
case F22_1184MHz: //at syslck 22.1184MHz
_nop_();
_nop_();
_nop_();
i = 52;
while (--i);
break;
case F24MHz: //at syslck 24.000MHz
_nop_();
_nop_();
i = 57;
while (--i);
break;
case F27MHz: //at syslck 27.000MHz
i = 65;
while (--i);
break;
case F30MHz: //at syslck 30.000MHz
_nop_();
_nop_();
i = 72;
while (--i);
break;
case F33MHz: //at syslck 33.000MHz
i = 80;
while (--i);
break;
case F33_1776MHz: //at syslck 33.1776MHz
_nop_();
_nop_();
i = 80;
while (--i);
break;
}
}
//End of Delay10us(FSYSCLOCK fsclk)
//****************************************/
void Delay1ms(FSYSCLOCK fsclk)
{
ui8 i,j;
switch(fsclk)
{
case F11_0592MHz: //at syslck 11.0592MHz
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
break;
case F12MHz: //at syslck 12.000MHz
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
break;
case F18_432MHz: //at syslck 18.432MHz
i = 18;
j = 235;
do
{
while (--j);
} while (--i);
break;
case F20MHz: //at syslck 20.000MHz
i = 20;
j = 113;
do
{
while (--j);
} while (--i);
break;
case F22_1184MHz: //at syslck 22.1184MHz
_nop_();
_nop_();
i = 22;
j = 128;
do
{
while (--j);
} while (--i);
break;
case F24MHz: //at syslck 24.000MHz
i = 24;
j = 85;
do
{
while (--j);
} while (--i);
break;
case F27MHz: //at syslck 27.000MHz
i = 27;
j = 64;
do
{
while (--j);
} while (--i);
break;
case F30MHz: //at syslck 30.000MHz
i = 30;
j = 43;
do
{
while (--j);
} while (--i);
break;
case F33MHz: //at syslck 33.000MHz
i = 33;
j = 22;
do
{
while (--j);
} while (--i);
break;
case F33_1776MHz: //at syslck 33.1776MHz
_nop_();
_nop_();
i = 33;
j = 66;
do
{
while (--j);
} while (--i);
break;
}
}
//End of Delay1ms(FSYSCLOCK fsclk)
//****************************************/
void Delay10ms(FSYSCLOCK fsclk)
{
ui8 i,j,k;
switch(fsclk)
{
case F11_0592MHz: //at syslck 11.0592MHz
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
break;
case F12MHz: //at syslck 12.000MHz
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
break;
case F18_432MHz: //at syslck 18.432MHz
_nop_();
_nop_();
i = 1;
j = 180;
k = 71;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F20MHz: //at syslck 20.000MHz
_nop_();
_nop_();
i = 1;
j = 195;
k = 136;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F22_1184MHz: //at syslck 22.1184MHz
_nop_();
_nop_();
i = 1;
j = 216;
k = 35;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F24MHz: //at syslck 24.000MHz
_nop_();
_nop_();
i = 1;
j = 234;
k = 113;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F27MHz: //at syslck 27.000MHz
_nop_();
_nop_();
i = 2;
j = 7;
k = 159;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F30MHz: //at syslck 30.000MHz
_nop_();
_nop_();
i = 2;
j = 36;
k = 206;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F33MHz: //at syslck 33.000MHz
_nop_();
_nop_();
i = 2;
j = 65;
k = 253;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
case F33_1776MHz: //at syslck 33.1776MHz
_nop_();
_nop_();
i = 2;
j = 67;
k = 183;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
break;
}
}
//End of Delay10ms(FSYSCLOCK fsclk)
//****************************************/
void Delayxus(ui8 x,FSYSCLOCK fsclk)
{
while(x)
{
Delay1us(fsclk);
x--;
}
}
//End of Delayxus(ui8 x,FSYSCLOCK fsclk)
//****************************************/
void Delay10xus(ui8 x, FSYSCLOCK fsclk)
{
while(x)
{
Delay10us(fsclk);
x--;
}
}
//End of Delay10xus(ui8 x, FSYSCLOCK fsclk)
//****************************************/
void Delayxms(ui8 x,FSYSCLOCK fsclk)
{
while(x)
{
Delay1ms(fsclk);
x--;
}
}
//End of Delayxms(ui8 x,FSYSCLOCK fsclk)
//****************************************/
void Delay10xms(ui8 x, FSYSCLOCK fsclk)
{
while(x)
{
Delay10ms(fsclk);
x--;
}
}
//End of Delay10xms(ui8 x, FSYSCLOCK fsclk)
该程序会上传到CSDN,文件名为Source Code of stc15w soft delay.rar,如需要可搜索下载。