单片机之从C语言基础到专家编程 - 4 C语言基础 - 4.11函数

在单片机开发中,一般使用C语言进行编程,C语言提供了一种结构化的编程方法,能有效地管理和控制硬件资源。函数是C语言中的一个基本构建块,它允许开发者将程序分解成更小、更易于管理的部分。

1 函数的基本概念
1)定义

函数是一段执行特定任务的代码块,它可以接受输入(称为参数),并可以返回一个结果。函数的主要目的是提高代码的可重用性和模块性。

2)声明

函数在使用前必须被声明。声明通常包括函数的返回类型、函数名和参数列表。这告诉编译器函数的存在,其具体实现可以在别处。

和变量类似,一般在源文件中对函数进行定义,在头文件中对需要对外提供的函数进行声明,如某函数不需要对外提供,但又需要在其他函数中提前使用,请在源文件头部对函数进行声明。

3)调用

当需要执行函数中的代码时,会进行函数调用。调用函数时,需要按照声明时的参数列表提供相应的参数。

4)参数

函数可以有参数,这些参数为函数提供了执行操作所需的数据。参数在函数调用时指定,并在函数执行期间使用。为了编译器的兼容性,如果函数没有参数,也最好将参数类型设为void。

5)返回类型

函数可以有一个返回类型,指定了函数执行完成后返回给调用者的数据类型。如果函数不返回任何值,则其返回类型为void

2 函数在单片机开发中的应用

在STM32等单片机开发中,函数的使用非常广泛,例如:

1)标准库函数

STM32提供了一套标准库,里面提供了单片机底层硬件的访问和控制,如GPIO、FLASH、IIC、USART等,如在stm32f10x_gpio中,GPIO_SetBits用于将某GPIO口的引脚电平拉高(置1,输出高电平),GPIO_ResetBits用于将某GPIO口的引脚电平拉低(置0,输出低电平)。

2)硬件抽象层(HAL)函数

STM32提供了一套硬件抽象层库,这些库的函数简化了对底层硬件的访问和控制。例如,HAL_GPIO_TogglePin()函数用于切换GPIO引脚的状态。

3)中断服务例程(ISR)

中断服务例程是特殊的函数,用于响应硬件中断。例如,当外部设备(如按钮)生成中断信号时,相应的ISR会被执行,以处理该中断。

4)用户定义函数

开发者可以定义自己的函数来执行特定的任务,比如数据处理、通信协议的实现等。这些函数增加了代码的模块性和可读性。

5)回调函数

在某些异步操作中,可以使用回调函数来处理完成后的事件。例如,在完成异步串行通信后,可以通过回调函数来处理接收到的数据。

3 函数的好处
1)可重用性

通过函数,可以将常用的代码封装起来,以便在多个地方重用,减少代码冗余。

2)模块化

函数允许开发者将复杂的程序分解成更小的、易于管理的单元,每个单元执行特定的任务。

3)易于维护

当程序逻辑需要更改或修复时,有了函数划分,开发者只需关注与问题相关的部分,而不必梳理整个程序代码。

4 函数的语法结构

返回类型 函数名(参数声明)

{

​ 函数体;

}

返回类型:void、char、unsigned char、int、unsigned int、float、double、uint8_t、uint16_t、uint32_t等

函数名:由英文字母、数字、下划线组成。函数名的起始位只能为字母或下划线

参数声明:可以是多个参数或void

函数体:由多个语句或代码段组成。

5 函数的使用举例
1)标准库函数的使用
c 复制代码
#include "stm32f10x.h"
#include "stdbool.h"

#define LED_DEBUG_PORT				GPIOA
#define LED_DEBUG_PIN				GPIO_Pin_10

void LED_DebugSetOn(void) 
{
	GPIO_SetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 打开
}

void LED_DebugSetOff(void) 
{
	GPIO_ResetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 关闭
}

void LED_DebugSet(bool value) 
{
	if(value == false)
	{
		GPIO_ResetBits(LED_DEBUG_PORT , LED_DEBUG_PIN);			// 关闭
	}	
	else
	{
		GPIO_SetBits(LED_DEBUG_PORT, LED_DEBUG_PIN);			// 点亮
	}	
}

2)自定义函数的使用

c 复制代码
void DELAY_1us(void)
{
	uint32_t ticks;
	
	//MCU执行1us所走的时钟步数
	ticks = (SystemCoreClock / 1000000);
	//非精确延时等待
	while (ticks--);
}

void DELAY_Nus(uint16_t nus)
{
	 while(nus--)
	 {
		  DELAY_1us();
	 }
}

void DELAY_1ms(void)
{
	for (int i = 0;i < 1000; i++)
	{
		  DELAY_1us();
	}
}
 
void DELAY_Nms(uint16_t nms)
{
	 while(nms--)
	 {
		  DELAY_1ms();
	 }
}
相关推荐
青い月の魔女1 小时前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
最后一个bug2 小时前
STM32MP1linux根文件系统目录作用
linux·c语言·arm开发·单片机·嵌入式硬件
FeboReigns2 小时前
C++简明教程(4)(Hello World)
c语言·c++
FeboReigns2 小时前
C++简明教程(10)(初识类)
c语言·开发语言·c++
wenchm2 小时前
细说STM32F407单片机IIC总线基础知识
stm32·单片机·嵌入式硬件
嵌入式lover3 小时前
STM32项目之环境空气质量检测系统软件设计
stm32·单片机·嵌入式硬件
小猿_003 小时前
C语言实现顺序表详解
c语言·开发语言
kenwblack3 小时前
STM32 SPI读取SD卡
stm32·单片机
Dola_Pan3 小时前
C语言:随机读写文件、实现文件复制功能
c语言·开发语言
佳心饼干-3 小时前
C语言-08复合类型-结构体
c语言·开发语言