回调函数 结构体

C语言回调函数–结构体

续接上一节

回调函数的一种概括

应用于异步事件的处理,首先将异步事件发生时需要执行的代码编写成一个函数,并将该函数注册成为回调函数,这样当该异步事件发生时,系统会自动调用事先注册好的回调函数。但是,不同异步事件的回调函数注册方法有所不同
  回调函数的注册实际上就是将回调函数的信息填写到一个用于注册回调函数的结构体变量中。

回调函数结构体简介

一、声明被回调函数原型
格式:同正常函数声明方法
例:

int add(int a, int b) { return a+b; }
int sub(int a, int b) { return a-b; }

二、声明结构体
   该结构体包含被回调函数,起到注册回调函数的作用。
格式:同正常结构体声明,不同的是内部包含函数
例:

struct operations{
	int (*ADD)(int a, int b); //格式类型同上面声明的函数原型
	int (*SUB)(int a, int b); //结构体里相当于包含了N个指向函数的指针
	int (*MUL)(int a, int b);
	int (*DIV)(int a, int b);  
};

三、结构体成员赋值,注册回调函数
格式:同正常结构体赋值
例:

struct operations FUN;
		FUN.ADD = add; //让FUN.ADD指向函数add
		FUN.SUB = sub;
		FUN.MUL = mul;
		FUN.DIV = div;

四、编写主程序
  首先初始化两个用于计算的变量
例:
int a=4,b=1,result;
函数调用部分

		result = FUN.ADD(a,b);
		printf("result is %d\n\r",result);
		result = FUN.SUB(a,b);
		printf("result is %d\n\r",result);
		result = FUN.MUL(a,b);
		printf("result is %d\n\r",result);
		result = FUN.DIV(a,b);
		printf("result is %d\n\r",result);

介绍部分到此为止。附main.c代码

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf_gpio.h"
#include "nrf_adc.h"
#include "app_uart.h"
#include "nrf_delay.h"
#include "app_error.h"
#include "app_timer.h"
#include "app_button.h"

#define  RX_PIN_NUMBER	11
#define  TX_PIN_NUMBER	9
#define  RTS_PIN_NUMBER	8
#define  CTS_PIN_NUMBER	10
#define UART_TX_BUF_SIZE 128 /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 128

#define LED0 18
#define LED1 19
#define BUTTON0 16
#define BUTTON1 17
#define BUTTONS_NUMBER 2

#define APP_TIMER_PRESCALER 0
#define APP_TIMER_MAX_TIMERS 8
#define APP_TIMER_OP_QUEUE_SIZE	8

uint32_t err_code;
static void lfclk_config(void);
void uart_error_handle(app_uart_evt_t * p_event);
void uart_init(void);
void button_event_handler(uint8_t pin_no, uint8_t button_action);
void app_button_user_init(void);

int add(int a, int b) { return a+b; } 
int sub(int a, int b) { return a-b; } 
int mul(int a, int b) { return a*b; } 
int div(int a, int b) { return a/b; }

struct operations{
	int (*ADD)(int a, int b); 
	int (*SUB)(int a, int b);  
	int (*MUL)(int a, int b);
	int (*DIV)(int a, int b);  
};

int main()
{
		int a=4,b=1,result;
		struct operations FUN;
		FUN.ADD = add;
		FUN.SUB = sub;
		FUN.MUL = mul;
		FUN.DIV = div;
	
		nrf_gpio_cfg_output(LED0);
nrf_gpio_cfg_output(LED1);  
		lfclk_config();  
uart_init();
		app_button_user_init();
		nrf_delay_ms(100);

		result = FUN.ADD(a,b);
		printf("result is %d\n\r",result);
		result = FUN.SUB(a,b);
		printf("result is %d\n\r",result);
		result = FUN.MUL(a,b);
		printf("result is %d\n\r",result);
		result = FUN.DIV(a,b);
		printf("result is %d\n\r",result);
		
while(1)
{
}
}

void uart_error_handle(app_uart_evt_t * p_event)
{
if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
{
APP_ERROR_HANDLER(p_event->data.error_communication);
}
else if (p_event->evt_type == APP_UART_FIFO_ERROR)
{
APP_ERROR_HANDLER(p_event->data.error_code);
}
}

void uart_init(void)
{
const app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_DISABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud115200
};
APP_UART_FIFO_INIT(&comm_params,
   UART_RX_BUF_SIZE,
   UART_TX_BUF_SIZE,
   uart_error_handle,
   APP_IRQ_PRIORITY_LOW,
   err_code);

APP_ERROR_CHECK(err_code);
}
void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
  static uint8_t i = 0; 
	printf("%d\n\r",i++);
}
void app_button_user_init(void)
{
	uint32_t timer_ticks = APP_TIMER_TICKS(100, APP_TIMER_PRESCALER);
	APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);
	static app_button_cfg_t P_button[BUTTONS_NUMBER] =
	{
			{
					BUTTON0,
					APP_BUTTON_ACTIVE_LOW,
					NRF_GPIO_PIN_NOPULL,
					button_event_handler
			},
			{
					BUTTON1,
					APP_BUTTON_ACTIVE_LOW,
					NRF_GPIO_PIN_NOPULL,
					button_event_handler
			}
	};
	err_code = app_button_init((app_button_cfg_t *)P_button,BUTTONS_NUMBER,timer_ticks);
	err_code = app_button_enable();
}
static void lfclk_config(void)
{
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
{
//Do nothing.
}
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
}

对于回调函数也是在不断的学习和理解中,在这里通过博客的形式分享出来。文章中若有错误希望大家指出,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值