51单片机自定义毫秒级延时函数时遇到定时不准确的问题
编程环境keil5,语言C
不明白具体原因
1.问题描述
刚接触51单片机编程,使用C语言想实现延迟,通过官方STC-ISP软件只能自动生成指定时间的延迟函数。非常不方便每次需要修改延迟时间都要重新生产延迟函数。于是想自己设计一个可以在编程时自己控制的毫秒级延迟程序。
自动生成的一毫秒延迟函数为:
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
这个时候是没有形式参数,和返回值。于是想修改成需要一个参数的函数,参数既为具体需要延迟的毫秒数的函数:
void Delayms(unsigned int count) //@11.0592MHz
{
unsigned int i, j;
_nop_();
_nop_();
_nop_();
i = 11 * count;
j = 190;
do
{
while (--j);
} while (--i);
}
将数据类型unsigned char 修改成unsigned int是因为unsigned char 最大只能存储500+的数值容易溢出于是修改为unsign int类型。结果发现实际延迟效果远远大于于其的延迟效果。
2.可能原因
51延迟是通过多次计算来实现延迟,因为每次计算的机器周期数量是固定的,调用能实现精确的延迟。所以我觉得可能是因为修改类型后每次计算所需要的机器周期数量增大,所以实际延迟效果远远大于预期效果。
3.一种解决办法,改变嵌套循环i、j的类型,将count用于外层的while循环此时延迟效果与预期效果相近。
void Delayms(unsigned int count) //@11.0592MHz
{
unsigned char i, j;
while(count)
{
count-=1;
_nop_();
_nop_();
_nop_();
i = 11 ;
j = 190;
do
{
while (--j);
} while (--i);
}
}
4.所以到底是为什么呢