喝水卡牙 发表于 2020-8-16 22:15:22

89C51延时函数看不懂

#include <reg51.h>
#include <intrins.h>
#defineNOP() _nop_()/* 定义空指令 */       
void delay(unsigned int i);      //函数声明


// 此表为LED字模         
unsigned char code LED7Code[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
                               /*{ ~0x01,~0x02,~0x04,~0x08,~0x10,~0x20,~0x40,~0x80}*/

main()
{
   unsigned int LedNumVal=1 ,C ;//定义变量
   
while(1)
{       
           if (++C>= 300)
                  { LedNumVal++ ;       //每隔300个扫描周期加1
                  C =0;                 //每隔300个扫描周期清0
               }       
           // 将字模送到P0口       
                P0 = LED7Code;   //LED7
                 
                         
                delay(150);          //调用延时函数
       
}   
}
       
/*****************************************************************
*                                                                                                                               *
*                         延时函数                                                                               *
*                                                                                                                               *
*****************************************************************/
void delay(unsigned int i)
{
    char j;
    for(i; i > 0; i--)
      for(j = 200; j > 0; j--);
}


以上程序为89C51 8位数码管显示程序,延时看不懂。delay(150),这个150啥意思,与下面的相乘还是搞啥?下面的 for 语句,第一个,i没初始化,定义无符号的i,想不通,i--为啥值?下面的for,后面有分号,初始化j=200,条件判断j已经大于0,应该不循环,百思不得其解。。。。百度无果。自己转程序,打delay 的值,2个都为4199866,改delay(150)里面的值,明显数码管刷新变快,但打印值还是4199866。

jhanker 发表于 2020-8-16 22:15:23

第一个,i没初始化,定义无符号的i,想不通 其实是已经初始化了,就是函数传入的参数 150

下面的for,后面有分号,初始化j=200,条件判断j已经大于0,应该不循环,百思不得其解。。。。 的解答是:
分号就是运行一句空语句
因为后面还有j--所以当j减到0的时候再下一次循环就不满足条件了,那时才停止循环

最好delay函数的作用就是单词的含义,延迟的作用让单片机执行领个嵌套的for循环。因为每一个语句的执行都需要时间,这样就达到延时的效果

喝水卡牙 发表于 2020-8-16 22:16:08

#include <stdio.h>
void delay(unsigned int i);
unsigned charLED7Code = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
main()
{
   unsigned int LedNumVal=1 ,C ;   
while(1)
{       
           if (++C>= 3000)
                  { LedNumVal++ ;       
                  C =0;                
               }                         
                printf("LED此时状态:%X\n",LED7Code);          
                delay(150);       
                break ;
}   
printf ("delay=%d\n",delay);
}



void delay(unsigned int i)
{
    char j;
    for(i; i > 0; i--)
      for(j = 200; j > 0; j--);
      printf ("delay=%d\n",delay);
}


这个是我自己修改打印delay的程序。

喝水卡牙 发表于 2020-8-17 01:22:49

首先,感谢 jhanker 兄弟答惑,明白了 i的值,也明白了delay(150)的含义,{:5_90:}哎,谭浩强视频,写的C程序跟羊子拉屎一样,函数东扯一下,西扯一下,郁闷。。。。反复打印J   的值,一直是 -56,根本没看见J--循环,最后发现,定义的是   char j,for循环里面给的值是200,已超出范围。。。。。光坑。

SHRS23 发表于 2020-8-17 09:05:07

本帖最后由 SHRS23 于 2020-8-17 09:10 编辑

喝水卡牙 发表于 2020-8-17 01:22
首先,感谢 jhanker 兄弟答惑,明白了 i的值,也明白了delay(150)的含义,哎,谭浩强视频, ...

51单片机的C语言编程只推荐一个老师的书和视频,金沙滩工作室http://www.qdkingst.com/cn/download

视频教程,教材PDF,工具软件全部可以在官网直接下载

另外你说的是郭天祥吧,程序确实一言难尽,变量全是abc,像是刚学C语言的人写的。。

你的问题:
单片机的这种延时函数就是用循环空语句的方式占用CPU时间,正常里面没有printf只有两层循环,在更短时间的延时中一层循环就够了,每执行一次delay函数延迟多久取决于外部晶振频率,你这个程序我目测大概是11.0592MHz晶振下的1ms延时吧,STC单片机的下载程序STC-ISP有生成延时代码的功能可以试一下。

不同平台运行这段代码得到的时间是不同的,如果你尝试在电脑上编译这段代码,时间肯定不对,即使是在不同的51单片机里时间也是有些差别,而且这种延时实际上是
让CPU做没有意义的工作来实现延时,是阻塞CPU的程序,浪费了CPU的性能,所以这种延时程序只适合初学单片机做一些简单的示例程序,或者实际应用时一些很短的小延时
以后用的更多的是用定时器中断来产生延时效果,中断能让CPU更高效。

喝水卡牙 发表于 2020-8-17 22:45:33

{:5_108:}感谢4楼兄弟的回复,以及推荐的网站,感谢。
另外也帮分析了一下MCU延时的一些特性,谢谢。再次慢慢学习,

喝水卡牙 发表于 2020-8-17 22:46:15

嗯,应该是5楼,说错了
页: [1]
查看完整版本: 89C51延时函数看不懂