51单片机实战教程之C语言基础(五 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 类型是既不能做返回值,也不可做参数的。
51单片机实战教程之C语言基础(五 C语言函数及其定义)相关推荐
- 51单片机实战教程之C语言基础(一 创建Keil Project)
创建Keil Project 第 1 步 添加STC单片机型号及头文件到Keil 后面所有教程及示例将以STC15W4K61S4系列单片机为例,因此需先将STC单片机型号及头文件加入到Keil中.Ke ...
- 51单片机实战教程(28 人机界面编程五)
2本文将介绍Usart HMI常用指令 1 page指令 用于页面切换,使用格式 : page obj obj指页面名称或id, 示例: 有下面两个页面, 要从page0 切换到main 代码如下: ...
- 学单片机需要多少C语言基础,C语言单片机编程教程
很多学员和朋友经常找我给他们推荐C语言的书,他们可能想和我当年一样,闷头大干一场,学个几个月的C语言,把C语言吃透,再开始单片机程序开发! 别!别!别! 大家千万别这么干,我当年自学了3个月的C语言, ...
- java+mysql性能优化_Java培训实战教程之mysql优化
Java培训实战教程之mysql优化 更新时间:2015年12月29日13时30分 来源:传智播客Java培训学院 浏览次数: 1. mysql引擎 1.1. 引擎类型 MySQL常用的存储引擎 ...
- Wireshark数据抓包教程之Wireshark的基础知识
Wireshark数据抓包教程之Wireshark的基础知识 Wireshark的基础知识 在这个网络信息时代里,计算机安全始终是一个让人揪心的问题,网络安全则有过之而无不及.Wireshark作为国 ...
- 51单片机数码管显示60秒倒计时(C语言)
51单片机数码管显示60秒倒计时(C语言) 基于普中51单片机开发板,运用定时器/计数器0和1,实现60秒的倒计时和LED灯0.5s间隔闪烁 文章目录 51单片机数码管显示60秒倒计时(C语言) 前言 ...
- 4. Vue入门实战教程之vue-element-admin后端API适配
Vue入门实战教程之vue-element-admin后端API适配 1.1 前言 1.2 分析框架 1.1.1 第一个接口:根据账号密码登陆获取token 1.1.2 第二个接口:根据token获取 ...
- 叩丁狼—Java培训实战教程之mysql优化
Java培训实战教程之mysql优化 Java培训过程中精点.难点知识解析 1. mysql引擎1.1. 引擎类型MySQL常用的存储引擎为MyISAM.InnoDB.MEMORY.MERGE,其中I ...
- [GO语言基础] 五.顺序控制语句和条件控制语句(if、else、switch)
作为网络安全初学者,会遇到采用Go语言开发的恶意样本.因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识:另一方面是分享与读者,希望大家一起进步.前文介绍了Golang的 ...
最新文章
- 计算机英语protocols,计算机网络协议词汇Protocols
- java中isclosed_java.sql.SQLException: Conntion is closed.解决方法
- 优酷开放SDK之setOnCompletionListener
- maven-将maven工程打包成可执行jar包
- 嵌入式系统分类及其应用场景_词嵌入及其应用简介
- Centos6.4 本地yum源配置
- kibana 后台启动
- 服务提供者框架理解草图
- 西门子PLC S7-1200程序实例,博图版本V15,仅供电气编程者学习借鉴
- python+appium+夜神模拟器APP自动化测试
- sl4a最新版下载_SL4A Script Launcherapp
- 自动驾驶综述|定位、感知、规划常见算法汇总
- java多态、抽象类和接口
- ps cc2019 安装教程
- C#实现ODBC驱动代码连接Sql Server数据库
- base关键字的用法
- Altera下载脚本二
- Python 画图学习入门
- PyQt5 QCalendarWidget日历控件
- 前端获取页面的高度/宽度