HAL库中的函数指针

函数指针:即指向函数指针变量

因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数

正如用指针变量可指向整型变量、字符型、数组一样,这里的指针变量是指向函数

C语言在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址

有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的

函数指针有两个用途:调用函数和做函数的参数

我们首先定义了一个函数指针pfun ,这个函数指针的返回值为void

void (*pfun)(int data);

然后我们给函数指针赋值,赋值为myfun,也就是myfun函数的首地址,在C99中myfun函数名就是myfun函数的首地址

pfun = myfun;

此时pfun获得了myfun的地址,pfun的地址等于myfun的地址,所以最终调用pfun(); 也就相当于调用了myfun();

(*pfun)(100);

typedef

也可以用typedef来定义一个指针函数

定义了一种pfun的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数并返回void类型

typedef void (*pfun)(int data);

pfun p= myfun; //函数指针指向执行函数的地址

这里面的pfun代表的是函数的类型,通过pfun来代表void (*)(int)函数类型即pfun是指针函数的别名,pfun p相当于定义了一个void (*p)(int)函数指针

p = myfun可以理解为将函数指针p指向myfun函数的地址,p(100);相当于执行myfun(100);

结构体

用结构体函数指针的方法

#include <stdio.h>
#include <stdlib.h>
typedef struct gfun{
	void (*pfun)(int);	
}gfun;
void myfun(int data)
{
	printf("get data:%d\n",data);
}
int main(int argc,char *argv[])
{
	gfun gcode={
		.pfun = myfun,   //将函数指针指向要调用函数的地址
	};
	gcode.pfun(100);
	return 0;
} 

回调函数

即通过函数指针调用的函数

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应

通过下面的例子我们可以看到将结构体中的函数指针pfun指向了myfun函数地址,在回调函数中我们将函数指针gf.pfun作为rt_data(int data,int (*tr_fun)())函数的参数,即为int (*tr_fun)();

回调函数中的return (*tr_fun)(data)相当于对指针进行了简引用,返回这个指针指向地址的内容值。

#include <stdio.h>
#include <stdlib.h>
typedef struct gfun{
	int (*pfun)(int);	
}gfun;

int myfun(int data)
{
	printf("get data:%d\n",data);
	return (data*2);
}
int rt_data(int data,int (*tr_fun)())
{
	return ((*tr_fun)(data));
}  
int main(int argc,char *argv[])
{
	int ret;
	gfun gf;
	gf.pfun = myfun;
	ret = rt_data(100,gf.pfun);
	printf("return data:%d\n",ret);
	return 0;
}

回调函数可以把调用者与被调用者分开,所以调用者不关心谁是被调用者

它只需知道存在一个具有特定原型和限制条件的被调用函数

简而言之,回调函数就是允许用户把需要调用的函数的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

STM32Cube中的回调函数

看一下DMA的中断服务函数 

接着往里面跳

这个XferHalfCpltCallback就是函数指针

 看一下其定义

 这里就跳不下去了,我们看看它是在哪赋值的

 我们找找这个函数指针被赋值的地方

这里才是函数指针被赋值的地方

这里才是函数指针实际指向的函数 

 

内部是执行到这个地方

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HAL库是针对STM32微控制器的一套高级API,包含了丰富的功能库,包括ADC模块的驱动。在HAL库,ADC模块的驱动框架已经被封装好了,我们只需要调用相应的函数即可使用。下面是HAL库ADC相关函数的详解: 1. ADC初始化函数 函数原型:HAL_ADC_Init(ADC_HandleTypeDef* hadc) 函数作用:配置ADC模块的基本参数,包括参考电压、采样分辨率、采样周期等。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体。 2. ADC通道配置函数 函数原型:HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) 函数作用:配置ADC转换通道的相关参数,包括通道号、采样时间、采样时钟等。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体;sConfig:ADC_ChannelConfTypeDef类型指针,指向已经定义好的ADC_ChannelConfTypeDef结构体。 3. ADC启动函数 函数原型:HAL_ADC_Start(ADC_HandleTypeDef* hadc) 函数作用:启动ADC模块的转换过程。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体。 4. ADC停止函数 函数原型:HAL_ADC_Stop(ADC_HandleTypeDef* hadc) 函数作用:停止ADC模块的转换过程。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体。 5. ADC轮询模式获取转换结果函数 函数原型:HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) 函数作用:在轮询模式下获取ADC转换结果。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体;Timeout:等待转换结果的超时时间,单位为毫秒。 6. ADC断模式获取转换结果函数 函数原型:HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) 函数作用:在断模式下启动ADC转换过程。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体。 7. ADC断回调函数 函数原型:HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) 函数作用:当ADC转换完成后,自动调用此函数,用户可以在此函数进行转换结果的处理。 参数说明:hadc:ADC_HandleTypeDef类型指针,指向已经定义好的ADC_HandleTypeDef结构体。 以上就是HAL库ADC相关函数的详解,使用HAL库可以方便快捷地实现ADC模块的驱动。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值