单片机之从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();
	 }
}
相关推荐
安科瑞刘鸿鹏18 分钟前
分布式光伏发电系统如何确保电能质量达到并网要求?
服务器·网络·分布式·嵌入式硬件·能源
侥幸哥f32 分钟前
GD32F103单片机-EXTI外部中断
单片机·gd32·exti
HeiLongMada2 小时前
从边缘设备到云端平台,合宙DTU&RTU打造无缝物联网解决方案
嵌入式硬件·物联网·硬件工程·pcb工艺
铁匠匠匠2 小时前
【C总集篇】第八章 数组和指针
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
王哈哈嘻嘻噜噜2 小时前
c语言中“函数指针”
java·c语言·数据结构
QQ19284999063 小时前
基于STM32无刷直流电机调速蓝牙APP无线监测控制系统
stm32·嵌入式硬件·mongodb
别耗尽4 小时前
错题集锦之C语言
c语言
六点半8884 小时前
【C/C++】速通涉及string类的经典编程题
c语言·开发语言·c++·算法
OH五星上将4 小时前
OpenHarmony(鸿蒙南向开发)——标准系统方案之瑞芯微RK3568移植案例(下)
linux·驱动开发·嵌入式硬件·harmonyos·openharmony·鸿蒙开发·系统移植
Jack黄从零学c++4 小时前
自制网络连接工具(支持tcpudp,客户端服务端)
linux·c语言·开发语言·网络协议·tcp/ip·udp·信息与通信