硬汉嵌入式论坛

 找回密码
 立即注册
查看: 839|回复: 5
收起左侧

[UART] 为什么stm32使用串口接收数据都是使用标志位而不使用回调函数

[复制链接]

2

主题

23

回帖

29

积分

新手上路

积分
29
发表于 2024-12-8 11:21:37 | 显示全部楼层 |阅读模式
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*	函 数 名: AppTaskCANFD
*	功能说明: CANFD处理任务。
*	形    参: 无
*	返 回 值: 无
*   优 先 级: osPriorityNormal6  
*********************************************************************************************************
*/
void AppTaskCANFD(void *argument){

	uint8_t tx_buf[64];
	MSG_T msg;
	bsp_StartAutoTimer(0, 500);	/* 启动1个500ms的自动重装的定时器 */
	
	for(uint8_t i = 0;i<64;i++){
		tx_buf[i] = i;
	}
	
	bsp_InitCan1();     /* 初始化CAN1 */
	bsp_InitCan2();     /* 初始化CAN2 */
	
	
	int wi = 0;
		
	while(1)
    {
		/* 相对延迟 */
		osDelay(1);
		wi++;
		if(wi > 1000){
			printf("CAN1发送消息给CAN1\r\n");
			can1_SendPacket(tx_buf, FDCAN_DLC_BYTES_64);
			wi=0;
		}
		
		/* 判断定时器超时时间 */
		if (bsp_CheckTimer(0))	
		{            
			/* 每隔500ms 进来一次 */  
			bsp_LedToggle(2);
		}
		
		if (bsp_GetMsg(&msg))
		{
			switch (msg.MsgCode)
			{
				case MSG_CAN1_RxFIFO0:		
					printf("CAN1 RxFIFO0收到数据:\r\n");
					print_int_array(g_Can1RxData, 64);
					break;
				
				case MSG_CAN1_RxFIFO1:		
					printf("CAN1 RxFIFO1收到数据:\r\n");
					print_int_array(g_Can1RxData, 64);
					break;	
				
				case MSG_CAN1_RxBuffer:		
					printf("CAN1 RxBuffer:\r\n");
					print_int_array(g_Can1RxData, 64);
					break;

				case MSG_CAN1_TxFIFO:		
					printf("CAN1 TxFIFO发送完成数据\r\n");
					break;	

				case MSG_CAN1_TxBuffer:		
					printf("CAN1 TxBuffer发送完成数据\r\n");
					break;	

				case MSG_CAN2_RxFIFO0:		
					printf("CAN2 RxFIFO0收到消息\r\n");
					print_int_array(g_Can2RxData, 64);
					break;
				
				case MSG_CAN2_RxFIFO1:		
					printf("CAN2 RxFIFO1收到消息\r\n");
					print_int_array(g_Can2RxData, 64);
					break;	
				
				case MSG_CAN2_RxBuffer:		
					printf("CAN2 RxBuffer收到消息\r\n");
					print_int_array(g_Can2RxData, 64);
					break;

				case MSG_CAN2_TxFIFO:		
					printf("CAN2 TxFIFO发送完成\r\n");
					break;	

				case MSG_CAN2_TxBuffer:		
					printf("CAN2 TxBuffer发送完成\r\n");
					break;						
			}
		}

		
		
	}
}




这个使用 while 轮询 有个延迟 osDelay(1); 就是非实时的

[C] 纯文本查看 复制代码
//*********************Can1 */
								//空闲中断标志

typedef struct {  
	//EventID ID; 				// 回调事件标志id
    RxFunCan1 fun; 				// 指向函数的指针  
} CallbackStructureCan1;  		//回调结构

CallbackStructureCan1 *CallBatRxCan1 = NULL;	//回调表
uint8_t CallBatRxLenCan1 = 0;				//回调表成员数

//释放回调 表
void CallBatFreeCan1(void) {
    free(CallBatRxCan1);
    CallBatRxCan1 = NULL;
    CallBatRxLenCan1 = 0;
}


/****************
注册回调函数,成功返回ID 失败返回0
****************/
uint8_t CallBatAddCan1(RxFunCan1 func) {

    if (CallBatRxCan1 == NULL) {									//分配初始内存
        CallBatRxCan1 = malloc(sizeof(CallbackStructureCan1));
        if (CallBatRxCan1 == NULL) {
            return 0; 											// 内存分配失败,返回0或错误代码
        }
        CallBatRxLenCan1 = 0; 									// 初始化大小为0(但实际上在第一次添加时会被加1)
    }
 
    CallbackStructureCan1 *temp = realloc(CallBatRxCan1, (CallBatRxLenCan1 + 1) * sizeof(CallbackStructureCan1));// 为回调表分配更多内存
    if (temp == NULL) {
        return 0; 												// realloc失败,返回0或错误代码
    }
    CallBatRxCan1 = temp;
    CallBatRxCan1[CallBatRxLenCan1].fun = func;					// 添加回调并更新大小
    CallBatRxLenCan1++;
    return CallBatRxLenCan1;									// 返回回调的ID(索引+1)
}
 


/****************
触发回调
****************/
static void CallRxFunCan1(_CANMSG* msg) {
	for(uint8_t i=0;i < CallBatRxLenCan1;i++){					//遍历储存在变量的回调函数
		if (CallBatRxCan1[i].fun != NULL ) {
			CallBatRxCan1[i].fun(msg);						//调用
		}
	}
}

//*********************Can1 */



这个是我自己弄的使用注册回调方式将消息直接回调 没有使用到延迟  



但是我看了很多人的代码 大部分没有使用回调的方式这是为什么呢










回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-9 08:55:17 | 显示全部楼层
这个还是用回调方便。
回复

使用道具 举报

102

主题

575

回帖

896

积分

金牌会员

积分
896
QQ
发表于 2024-12-9 19:43:19 | 显示全部楼层
没看懂。咋使用的这些函数。
回复

使用道具 举报

0

主题

290

回帖

290

积分

高级会员

积分
290
发表于 2024-12-10 09:16:16 | 显示全部楼层
都要用os了,就不要再这也搞循环里面主机检测了,用事件驱动。
回复

使用道具 举报

2

主题

23

回帖

29

积分

新手上路

积分
29
 楼主| 发表于 2024-12-10 11:51:42 | 显示全部楼层
regbbs 发表于 2024-12-10 09:16
都要用os了,就不要再这也搞循环里面主机检测了,用事件驱动。

事件驱动 是什么 请大佬指点
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-11 08:19:36 | 显示全部楼层
qq547176052 发表于 2024-12-10 11:51
事件驱动 是什么 请大佬指点

接收回调里面收到数据后,发OS信号量,消息队列等均可,给对应的任务处理。这就叫事件驱动,就是来了事件才去处理。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 01:19 , Processed in 0.041804 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表