鱼C论坛

 找回密码
 立即注册
查看: 1548|回复: 6

[已解决]89C51延时函数看不懂

[复制链接]
发表于 2020-8-16 22:15:22 | 显示全部楼层 |阅读模式
5鱼币
#include <reg51.h> 
#include <intrins.h>
#define  NOP() _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[LedNumVal%10];     //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。
最佳答案
2020-8-16 22:15:23
第一个,i没初始化,定义无符号的i,想不通 其实是已经初始化了,就是函数传入的参数 150

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

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

最佳答案

查看完整内容

第一个,i没初始化,定义无符号的i,想不通 其实是已经初始化了,就是函数传入的参数 150 下面的for,后面有分号,初始化j=200,条件判断j已经大于0,应该不循环,百思不得其解。。。。 的解答是: 分号就是运行一句空语句 因为后面还有j--所以当j减到0的时候再下一次循环就不满足条件了,那时才停止循环 最好delay函数的作用就是单词的含义,延迟的作用让单片机执行领个嵌套的for循环。因为每一个语句的执行都需要时间,这 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-8-16 22:15:23 | 显示全部楼层    本楼为最佳答案   
第一个,i没初始化,定义无符号的i,想不通 其实是已经初始化了,就是函数传入的参数 150

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

最好delay函数的作用就是单词的含义,延迟的作用让单片机执行领个嵌套的for循环。因为每一个语句的执行都需要时间,这样就达到延时的效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-16 22:16:08 | 显示全部楼层
#include <stdio.h>
void delay(unsigned int i);  
unsigned char  LED7Code[10] = {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[LedNumVal%10]);              
                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  的程序。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-17 01:22:49 | 显示全部楼层
首先,感谢 jhanker 兄弟答惑,明白了 i  的值,也明白了  delay(150)的含义,哎,谭浩强视频,写的C程序跟羊子拉屎一样,函数东扯一下,西扯一下,郁闷。。。。反复打印  J   的值,一直是 -56,根本没看见  J--  循环,最后发现,定义的是   char j  ,for  循环里面给的值是  200  ,已超出范围。。。。。光坑。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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更高效。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-17 22:45:33 | 显示全部楼层
感谢4楼兄弟的回复,以及推荐的网站,感谢。
另外也帮分析了一下MCU延时的一些特性,谢谢。再次慢慢学习,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-8-17 22:46:15 | 显示全部楼层
嗯,应该是5楼,说错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-13 07:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表