大前端

前端学习之家-大前端

51单片机实战教程之学习起步(五 C语言函数及其定义)

       虽然部分C语言函数的返回值与其参数存在对应关系,但是它与数学里的函数不是同一概念。有的书上把它定义为完成特定任务的代码集合。

      C语言函数的格式为:返回值数据格式  函数名(参数列表){函数体}, 函数可以没有返回值,参数列表也可以为空。函数返回值可以是除数组外的任意类型,参数数据类型为C的所有数据类型。函数的定义一般有两个步骤,先是函数声明,然后是实现。一般在头文件中声明函数,然后在源文件中写实现代码。下面列举几个声明与实现的实例:

//************** stcio.h

#ifndef __STCIO_H_
#define __STCIO_H_

//#define STC8F
//#define STC15

#ifdef STC15
#include "stc15w4k.h"
#endif

#ifdef STC8F
#include "stc8f.h"
#endif

#include "mytype.h"

typedef enum
{
    BI_IO = 0, //bidirectional I/O
    PP_OUT,    //push_pull out
    HI_IN,     //high impendence in
    ODR_IO     //open drain I/O
}STCIOTYPE;
//*******************************************************************
typedef enum
{
    GPIO_P0 = 0x01,
    GPIO_P1 = 0x02,
    GPIO_P2 = 0x04,
    GPIO_P3 = 0x08,
    GPIO_P4 = 0x10,
    GPIO_P5 = 0x20,
    GPIO_P6 = 0x40,
    GPIO_P7 = 0x80,
}STC_PORT;
//********************************************************************
typedef enum
{
    GPIO_PIN0 = 0x01,
    GPIO_PIN1 = 0x02,
    GPIO_PIN2 = 0x04,
    GPIO_PIN3 = 0x08,
    GPIO_PIN4 = 0x10,
    GPIO_PIN5 = 0x20,
    GPIO_PIN6 = 0x40,
    GPIO_PIN7 = 0x80,
}IO_PIN;


**********************************************************************/
void STC_PortPinsInit(STC_PORT mPort, ui8 mPins, STCIOTYPE iotype); //init I/O pin type
/*
Example:
STC_IOPinInit(GPIO_P7, GPIO_PIN7,BI_IO);
*/


**********************************************************************/
void STC_IOInit(ui8 mPorts, ui8 mPins, STCIOTYPE iotype); //init  ports'  bit I/O type
/*
Example:
STC_IOInit(0xFF, 0xFF,BI_IO);
*/

#endif

//

   //**********stcio.c

#include "stcio.h"


**********************************************************************/
void STC_PortPinsInit(STC_PORT mPort, ui8 mPins, STCIOTYPE iotype) //init I/O pin type
{
    switch(mPort)
    {
        case GPIO_P0:
            switch(iotype)
            {
                case BI_IO:
                    P0M0 &= ~mPins;
                    P0M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P0M0 |= mPins;
                    P0M1 &= ~mPins;
                    break;
                case HI_IN:
                    P0M0 &= ~mPins;
                    P0M1 |= mPins;
                    break;
                case ODR_IO:
                    P0M0 |= mPins;
                    P0M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P1:
            switch(iotype)
            {
                case BI_IO:
                    P1M0 &= ~mPins;
                    P1M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P1M0 |= mPins;
                    P1M1 &= ~mPins;
                    break;
                case HI_IN:
                    P1M0 &= ~mPins;
                    P1M1 |= mPins;
                    break;
                case ODR_IO:
                    P1M0 |= mPins;
                    P1M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P2:
            switch(iotype)
            {
                case BI_IO:
                    P2M0 &= ~mPins;
                    P2M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P2M0 |= mPins;
                    P2M1 &= ~mPins;
                    break;
                case HI_IN:
                    P2M0 &= ~mPins;
                    P2M1 |= mPins;
                    break;
                case ODR_IO:
                    P2M0 |= mPins;
                    P2M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P3:
            switch(iotype)
            {
                case BI_IO:
                    P3M0 &= ~mPins;
                    P3M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P3M0 |= mPins;
                    P3M1 &= ~mPins;
                    break;
                case HI_IN:
                    P3M0 &= ~mPins;
                    P3M1 |= mPins;
                    break;
                case ODR_IO:
                    P3M0 |= mPins;
                    P3M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P4:
            switch(iotype)
            {
                case BI_IO:
                    P4M0 &= ~mPins;
                    P4M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P4M0 |= mPins;
                    P4M1 &= ~mPins;
                    break;
                case HI_IN:
                    P4M0 &= ~mPins;
                    P4M1 |= mPins;
                    break;
                case ODR_IO:
                    P4M0 |= mPins;
                    P4M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P5:
            switch(iotype)
            {
                case BI_IO:
                    P5M0 &= ~mPins;
                    P5M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P5M0 |= mPins;
                    P5M1 &= ~mPins;
                    break;
                case HI_IN:
                    P5M0 &= ~mPins;
                    P5M1 |= mPins;
                    break;
                case ODR_IO:
                    P5M0 |= mPins;
                    P5M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P6:
            switch(iotype)
            {
                case BI_IO:
                    P6M0 &= ~mPins;
                    P6M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P6M0 |= mPins;
                    P6M1 &= ~mPins;
                    break;
                case HI_IN:
                    P6M0 &= ~mPins;
                    P6M1 |= mPins;
                    break;
                case ODR_IO:
                    P6M0 |= mPins;
                    P6M1 |= mPins;
                    break;
            }
            break;
        case GPIO_P7:
            switch(iotype)
            {
                case BI_IO:
                    P7M0 &= ~mPins;
                    P7M1 &= ~mPins;
                    break;
                case PP_OUT:
                    P7M0 |= mPins;
                    P7M1 &= ~mPins;
                    break;
                case HI_IN:
                    P7M0 &= ~mPins;
                    P7M1 |= mPins;
                    break;
                case ODR_IO:
                    P7M0 |= mPins;
                    P7M1 |= mPins;
                    break;
            }
            break;
    }
}


**********************************************************************/
void STC_IOInit(ui8 mPorts, ui8 mPins, STCIOTYPE iotype) //init  ports'  bit I/O type
{
    ui8 i,j;
    for(i = 0; i < 8; i++)
    {
        j = mPorts&(1 << i);
        if(j)
        {
            STC_PortPinsInit(j, mPins, iotype);
        }
    }
    
}
//End of STC_IOInit(ui8 mPorts, ui8 mPins, STCIOTYPE iotype)

   上面函数的返回值皆为空,但其参数列表不为空,下面有一个返回值为空(void),参数列表也为空的例子:

ltc1658is8.h//LTC1658IS8 driver

#ifndef __LTC1658IS8_H__
#define __LTC1658IS8_H__

#include "myport.h" //defined ltc1658DIN,ltc1658CS,ltc1658CLK
#include "mytype.h"
#include "delay.h"

//***********************************************************
void LTC1658_CLK();

//************************************************************
void LTC1658_DacOutput(ui16 mData);

#endif

//ltc1658is8.c//LTC1658IS8 driver

#include "ltc1658is8.h"

//***********************************************************
void LTC1658_CLK()
{
    ltc1658CLK = 1;
    Delayxus(1,8);
    ltc1658CLK = 0;
    Delayxus(1,8);
}

//************************************************************
void LTC1658_DacOutput(ui16 mData)
{
    ui8 i;
    ltc1658CS = 0;
    ltc1658CLK = 0;
    Delayxus(1,8);
    for(i = 0; i < 16; i++)
    {
        mData = (mData << 1);
        if(CY)
            ltc1658DIN = 1;
        else
            ltc1658DIN = 0;
        Delayxus(1,8);
        LTC1658_CLK();
    }
    ltc1658CS = 1;
    ltc1658CLK = 1;
}

       在定义有返回值函数时,须注意那些可以做返回值哪些不能,先不下结论。有书上说,数组不可以做返回值,  整个数组肯定不可以做返回值,返回值不可能为多个,那数组名呢?数组名实际是一个指针,指向数组的首地址。请看下面例子:

 编译结果如下:

编译成功,说明数组名是可以做返回值的,因为它实际是个指针。同样数组元素(数组名加下标,如destArray[0]) ,标准C数据及标准C的扩展数据都看做函数参数(类型),除数组外都可做返回值(类型)。

       Keil C51的扩展数据类型可否做函数返回值与参数呢?sbit,srf,srf16 类型是既不能做返回值,也不可做参数的。

发表评论:

Copyright Your WebSite.Some Rights Reserved.