本讲在上一讲的代码基础上讲解新的编程知识:函数参数传递调用!


1.推陈出新

上一讲的函数封装“delay();”是一个固定的功能,只能做延时1秒的作用,大多数情况下我们希望一个函数用相同的函数名通过修改一个值可以实现不一样的功能,所以就产生了函数带参调用的编程手法。

我们根据前面章节的基础实现通过修改函数参数值来实现LED不同延时的间隔闪烁,因为参数的传入在函数内容中是可以使用这个参数变量的,所以我们用“while(x--)”来让x决定延时的毫秒数。

延时部分如下,函数名改为“delay_ms”代表要延时多少毫秒

void delay_ms(unsigned int x)
{
    unsigned int j;
    while(x--)//循环x次下面的语句,执行原理与上一讲for语句相同
    {
        for(j=115;j>0;j--);//延时1ms
    }
}

 

2.知识普及

在这里普及一下C语言知识技巧,因为“for(j=115;j>0;j--);”只是一条语句,在while循环时可以不用镶嵌到大括号中。

所以我们简写成“while(x--)for(j=115;j>0;j--);”来节约版面。

但是在其他代码内容中需要循环两条及以上的语句时一定要有大括号包裹住这些语句。

 

3.缺陷

我们想要LED2间隔1秒闪烁则代码书写如下吗?

#include <reg52.h> 
sbit LED2  = P0^0;
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;

void delay_ms(unsigned int x)
{
    unsigned int j;//定义一个用来完成延时功能的16位的变量
    while(x--)for(j=115;j>0;j--);
}

void main()
{  
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    ADDR2 = 1;//**************************
    ADDR1 = 1;//让三八译码器的IO6输出低电平
    ADDR0 = 0;//**************************
  
    while (1)
    {
        LED2=0;
        delay_ms(1000);//延时1秒  
        LED2=1;
        delay_ms(1000);//延时1秒
    }
}

可是我们在本章第七讲已经知道,当x等于1000时,“while(x--)for(j=115;j>0;j--);”这个语句不能成比例地延时1秒,我们在单片机中要准确延时还需要软件调试仿真。不过很多时候我们不需要太准确的延时,在一定范围即可,所以改善一下代码,传入的参数为1000时是准确延时1秒,其他参数则为大概的延时毫秒数。

 

4.改善

笔者在这里为大家写了一个准确延时1秒和不准确延时其他时间的函数

void delay_ms(unsigned int x)
{
    unsigned int i,j;
    if(x==1000)
    {
        for(i=0;i<19601;i++)//延时1s
        {
            for(j=5;j>0;j--);
        }
    }
    else while(x--)for(j=115;j>0;j--);
}

我们想准确延时1秒时,“delay_ms(1000); ”在软件调试中的执行花费时间的确为1秒,当我们不需要很准确延时时,就随便添加个参数进去即可,比如我们要延时在200ms左右,“delay_ms(200);”是做不到延时200ms那么准确的,但在此一定时间范围也是可以接受的。


我们实现灯的闪烁间隔接近500ms,参数为500,虽然不是准确的500ms,但这并不妨碍我们只是用来观察灯的闪烁时间不同而已。

#include <reg52.h> 
sbit LED2  = P0^0;
sbit ADDR2 = P1^2;
sbit ADDR1 = P1^1;
sbit ADDR0 = P1^0;
sbit ENLED = P1^4;
sbit ADDR3 = P1^3;

void delay_ms(unsigned int x)
{
    unsigned int i,j;
    if(x==1000)
    {
        for(i=0;i<19601;i++)//延时1s
        {
            for(j=5;j>0;j--);
        }
    }
    else while(x--)for(j=115;j>0;j--);
}

void main()
{  
    ADDR3 = 1;//使能三八译码器
    ENLED = 0;// 
  
    ADDR2 = 1;//**************************
    ADDR1 = 1;//让三八译码器的IO6输出低电平
    ADDR0 = 0;//**************************
  
    while (1)
    {
        LED2=0;
        delay_ms(500);//延时了500ms左右 
        LED2=1;
        delay_ms(500);
    }
}

大家也可把500改为其他数字看看闪烁的间隔时间,必要的话,改为100进行软件调试仿真观看“delay_ms(100);”花费的时间是多少。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)