泰凌微(Telink)8258配置串口收发自定义数据

news2024/11/25 11:33:04

在官网下载SDK后(以Mesh SDK为例)使用Eclipse打开,对应MCU的配置文件在app_config_8258.h,默认的HCI接口是HCI_USE_NONE,如果改成HCI_USE_UART后可以通过串口收发数据,此时默认接收函数处理的是以Telink的协议格式收到的SIG model 命令,函数原型为blc_rx_from_uart(),这个主要用在Gateway工程中。

8258支持一个串口外设,可以不使用HCI_ACCESS宏,自己定义串口相关,以便于连接其他模块等,收发自定义数据。

用户相关的配置可以放在user_app_config.h文件中,比如需要定义一下Tx和Rx引脚。

#define UART_TX_PIN				UART_TX_PB1
#define UART_RX_PIN				UART_RX_PA0

串口可以使用的引脚在硬件设计手册中查找。
在这里插入图片描述
其次是在user_app.h中定义串口需要的相关结构体和宏定义,其中user_uart_data_t结构体为单次DMA接收的数据区内容,dma_len必须是4字节,在收到数据时表示接收到数据的长度;user_uart_que_t为串口数据处理的结构体,采用循环队列控制接收和发送,里面的rx_irq_cnt和tx_irq_cnt只是用来记录进入中断的次数,可以通过BDT工具读取判断是否成功收发数据,无实际意义。

#define USER_UART_DATA_LEN		12
#define USER_UART_DMA_LEN		4

typedef struct{
	unsigned int dma_len;
	unsigned char data[USER_UART_DATA_LEN];
}user_uart_data_t;

typedef struct{
	unsigned char rx_rear;
	unsigned char rx_front;
	unsigned char tx_rear;
	unsigned char tx_front;
	u16 rx_irq_cnt;
	u16 tx_irq_cnt;
	user_uart_data_t *p_rx_buf;
	user_uart_data_t *p_tx_buf;
}user_uart_que_t;

另外user_uart_data_t结构体的大小必须是16的整数倍,因为在设置接收缓冲的时候会用接收缓冲区的长度除以16。
在这里插入图片描述
串口的初始化放在Mesh的初始化函数user_init中:
在这里插入图片描述

串口相关变量定义:

user_uart_data_t user_uart_recv_data[USER_MAX_QUE_LEN];
user_uart_data_t user_uart_trans_data[USER_MAX_QUE_LEN];
user_uart_que_t  user_uart_que = {0};
const u16 UART_TX_LEN_MAX = sizeof(user_uart_data_t);

串口的初始化函数原型放在user_app.c中:

void user_uart_drv_init(void)
{
	user_uart_que_init();
	uart_recbuff_init( (unsigned char *)&user_uart_recv_data[0], sizeof(user_uart_recv_data), (unsigned char *)&user_uart_trans_data[0]);
	uart_gpio_set(UART_TX_PIN, UART_RX_PIN);

	uart_reset();  //will reset uart digital registers from 0x90 ~ 0x9f, so uart setting must set after this reset

	//baud rate: 115200
	uart_init(30, 8, PARITY_NONE, STOP_BIT_ONE);

	uart_dma_enable(1, 1); 	//uart data in hardware buffer moved by dma, so we need enable them first

	irq_set_mask(FLD_IRQ_DMA_EN);
	dma_chn_irq_enable(FLD_DMA_CHN_UART_RX | FLD_DMA_CHN_UART_TX, 1);   	//uart Rx/Tx dma irq enable
}

串口接收处理函数通过判断user_uart_que.rx_rear和user_uart_que.rx_front变量是否相等,来判断接收缓冲队列中是否有未处理的数据,主要更改的是user_uart_que.rx_rear变量,由于是循环队列,中断处理函数在队列已满时也需要改变user_uart_que.rx_rear的值,因此串口接收处理函数中改变user_uart_que.rx_rear的值时需要通过开关中断的方式处理一下。同样串口发送处理函数中是通过user_uart_que.tx_front和user_uart_que.tx_rear的值是否相等来判断是否有待发送的数据,同时也要判断一下串口是否空闲。

int user_rx_from_uart (void)
{
	u8 curr_p = 0;
	user_uart_data_t *p_data = NULL;
	uart_ErrorCLR();

	if(user_uart_que.rx_front != user_uart_que.rx_rear)
	{
		u32 r = irq_disable();
		curr_p = user_uart_que.rx_rear;
		user_uart_que.rx_rear = (user_uart_que.rx_rear + 1) % USER_MAX_QUE_LEN;
		irq_restore(r);
		p_data = &user_uart_recv_data[curr_p];
		user_recv_data_process(p_data);//对接收到的数据进行处理
	}
	return 0;
}

int user_tx_to_uart (void)
{
	if((user_uart_que.tx_front != user_uart_que.tx_rear) && (!uart_tx_is_busy ()))
	{
		if(uart_Send(user_uart_trans_data[user_uart_que.tx_rear].data, user_uart_trans_data[user_uart_que.tx_rear].dma_len))
		{
			user_uart_que.tx_rear = (user_uart_que.tx_rear + 1) % USER_MAX_QUE_LEN;
		}
	}

	return 0;
}

待发送数据入列函数,如果有数据需要发送,可以通过调用user_uart_que_push函数来入列。

void user_uart_que_push(user_uart_data_t *data)
{
	memcpy((unsigned char *)&user_uart_trans_data[user_uart_que.tx_front],(unsigned char *)data,(data->dma_len + USER_UART_DMA_LEN));
	user_uart_que.tx_front = (user_uart_que.tx_front + 1) % USER_MAX_QUE_LEN;
	if(user_uart_que.tx_front == user_uart_que.tx_rear)
	{
		user_uart_que.tx_rear = (user_uart_que.tx_rear + 1) % USER_MAX_QUE_LEN;
	}
}

然后在main.c中的irq_uart_handle函数中添加串口的中断处理函数,在收到一帧数据时,需要设置一下串口DMA接收缓冲的地址,指向下一个空闲的数据接收区域,这样的话就不用把接收到的数据拷贝到另外的地方,这也就是为什么需要用队列的方式接收数据。

在串口中断中主要更改的是串口队列中的user_uart_que.rx_front变量,用于指示下一个接收的缓冲区,当user_uart_que.rx_front加1和user_uart_que.rx_rear变量相等时,意味着接收缓冲区满了,接收到的数据一直没有被处理,此时user_uart_que.rx_rear变量也要加1,也就是覆盖掉最早接收到的数据。

_attribute_ram_code_ void user_irq_uart_handle()
{
	unsigned char irqS = reg_dma_rx_rdy0;
	if(irqS & FLD_DMA_CHN_UART_RX)	//rx
	{
		user_uart_que.rx_irq_cnt++;
		reg_dma_rx_rdy0 = FLD_DMA_CHN_UART_RX;

		user_uart_que.rx_front = (user_uart_que.rx_front + 1) % USER_MAX_QUE_LEN;

	    if (user_uart_que.rx_rear == user_uart_que.rx_front)
	    {
	    	user_uart_que.rx_rear = (user_uart_que.rx_rear + 1) % USER_MAX_QUE_LEN;
	    }

	    user_uart_que.p_rx_buf = &user_uart_recv_data[user_uart_que.rx_front];

	    reg_dma0_addr = (u16)((u32)user_uart_que.p_rx_buf);
	}

	if(irqS & FLD_DMA_CHN_UART_TX)	//tx
	{
		user_uart_que.tx_irq_cnt++;
		reg_dma_rx_rdy0 = FLD_DMA_CHN_UART_TX;
	}
}

然后就是在主函数中循环调用串口收发处理函数:

void user_main_loop(void)
{
	user_rx_from_uart();
	user_tx_to_uart();
}

在user_app_config.h中补充CB_USER_MAIN_LOOP()宏定义

#define CB_USER_MAIN_LOOP()		user_main_loop()
#define CB_USER_INIT()			user_app_init()

至此,就可以通过串口收发自定义数据。

如果需要使用串口打印log,可以使用模拟串口,只能发送,打开HCI_LOG_FW_EN宏,同时定义一下串口的引脚:

#define HCI_LOG_FW_EN				1

#if HCI_LOG_FW_EN
#define DEBUG_INFO_TX_PIN           		GPIO_PC2
#define PRINT_DEBUG_INFO                    1
#endif

模拟串口的波特率在myprintf.h中设置,默认1000000,如果接收到的数据乱码,可以更换串口或者降低波特率。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1292355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mfc140.dll丢失的解决方法,以及解决方法的优缺点

如果你在使用电脑时遇到了“mfc140.dll丢失”的错误提示,这可能会阻止你运行特定的应用程序或游戏。这篇文章将向你介绍导致此错误出现的原因以及mfc140.dll丢失的解决方法,让你的电脑系统恢复正常运行。 一.mfc140.dll丢失的解决方法以及优缺点 方法 1…

解析企业云性能监控几个重要作用

随着企业业务的数字化转型,云计算在企业中的应用越来越广泛。在这个背景下,保障云计算环境的性能和稳定性显得尤为重要。企业云性能监控作为一种有效的管理手段,对于确保云计算系统的顺利运行和业务的高效展开起到了关键作用。以下是企业云性…

银行业反洗钱培训报名流程及一寸蓝底报名照片制作

欢银行业反洗钱培训旨在加强银行业从业人员对反洗钱法规的理解,提升防范洗钱风险的专业技能。培训根据法规要求,帮助参训者更好地识别和应对潜在的洗钱威胁。培训内容包括反洗钱的基本原理、实际操作技能和风险评估策略等。下面主要介绍由中国金融培训中…

C# WPF上位机开发(抽奖软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 每到年末或者是尾牙的时候,很多公司都会办一些年终的清楚活动,感谢员工过去一年辛苦的付出。这个时候,作为年会…

智能优化算法应用:基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于野马算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.野马算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

VINS编译, opencv多版本的原因导致的问题

1. 通用问题 问题一 编译时报错 error: ‘CV_GRAY2RGB’ was not declared in this scope 等 解决方法 在报错文件上添加头文件 #include <opencv2/imgproc/imgproc_c.h> 单独遇到CV_AA的报错时&#xff0c;也可以将 CV_AA 改为 cv::LINE_AA 问题二 编译时报错 erro…

inBuilder低代码平台新特性推荐-第十五期

各位CSDN的友友们&#xff0c;大家好~ 今天来给大家介绍一下inBuilder低代码平台社区版中特性推荐系列第十五期——消息服务 一、 消息服务 inBuilder低代码平台有很多地方需要对结果发送云加、短信、邮件及GS消息等&#xff0c;并对这些不同的消息进行查看、处理。为了统一…

1688API接口系列,商品详情数据丨搜索商品列表丨商家订单类丨1688开放平台接口使用方案

1688商品详情接口是指1688平台提供的API接口&#xff0c;用于获取商品详情信息。通过该接口&#xff0c;您可以获取到商品的详细信息&#xff0c;包括商品标题、价格、库存、描述、图片等。 要使用1688商品详情接口&#xff0c;您需要先申请1688的API权限&#xff0c;并获取ac…

debian10 安装 tabby

tabby-1.0.205-linux-x64.debtabby-1.0.205-linux-x64.deb资源-CSDN文库 chmod 777 tabby-1.0.205-linux-x64.deb dpkg -i tabby-1.0.205-linux-x64.deb 会报错 用这个安装一下依赖 apt --fix-broken install dpkg -i tabby-1.0.205-linux-x64.deb tabby

一个技巧,解决企业大厦门禁问题!

随着科技的迅速发展&#xff0c;门禁监控系统在各个领域得到了广泛应用。这一技术不仅提高了安全性&#xff0c;还为管理者提供了更加高效的管理手段。 在各种环境中&#xff0c;从企业办公楼到学校校园&#xff0c;门禁监控系统都展现了其卓越的功能和优势。 客户案例 企业大…

RT_Thread_修改为外部晶振及验证

关注两处&#xff1a; 1、stm32f4xx_hal_conf.h&#xff0c;外部晶振频率HSE宏定义 2、drv_clk.c&#xff0c;system_clock_config函数 1、外部晶振频率HSE宏定义 根据实际外部晶振的频率去定义&#xff0c;使用的是8MHz&#xff1b; 2、system_clock_config 开启HSE&#…

【智能家居】六、摄像头安装实现监控功能点、人脸识别(face_recognition的使用)

一、定义及第三方库的说明 OCR &#xff08;光学字符识别&#xff09;文字识别、图像识别mjpg-streamer实时流式传输视频工具树莓派mjpg-streamer Face Recognition人脸识别 Dlib 计算机视觉问题的工具和算法face_recognition库OpenCV 计算机视觉和机器学习的开源库 三、香…

Jsoup爬取HTTPS页面数据资源,并导入数据库(Java)

一、实现思路 示例页面&#xff1a; 2020年12月中华人民共和国县以上行政区划代码 忽略https请求的SSL证书通过Jsoup获取页面标签遍历行标签&#xff0c;分别获取每个行标签的第二个和第三个列标签将获取到的行政代码和单位名称分别插入sql语句占位符执行sql语句&#xff0c…

【网络编程】-- 01 概述、IP

网络编程 1 概述 1.1 计算机网络 (连接分散计算机设备以实现信息传递的系统) 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&…

图的存储(邻接矩阵,边集数组,邻接表,链式前向星)

目录 &#x1f33c;图的存储 &#xff08;1&#xff09;邻接矩阵 &#xff08;2&#xff09;边集数组 &#xff08;3&#xff09;邻接表 &#xff08;4&#xff09;链式前向星 &#x1f600;刷题 &#x1f40d;最大节点 &#x1f40d;有向图 D 和 E &#x1f40d;奶牛…

3 文本分类入门finetune:bert-base-chinese

项目实战&#xff1a; 数据准备工作 bert-base-chinese 是一种预训练的语言模型&#xff0c;基于 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;架构&#xff0c;专门用于中文自然语言处理任务。BERT 是由 Google 在 2018 年提出的一…

Leetcode—1466.重新规划路线【中等】

2023每日刷题&#xff08;五十二&#xff09; Leetcode—1466.重新规划路线 算法思想 实现代码 class Solution { public:int minReorder(int n, vector<vector<int>>& connections) {vector<pair<int, int>> g[n];for(auto e: connections) {in…

“掌握高效视频分割技巧,降低误差,提高精度“

如果你是一名视频编辑爱好者或者专业人士&#xff0c;那么你一定会在视频剪辑的过程中遇到各种挑战。其中&#xff0c;如何准确高效地进行视频分割是一个至关重要的问题。现在&#xff0c;我们将向你展示一种全新的解决方案&#xff0c;帮助你轻松解决这些问题。 首先第一步&a…

Vue使用百度地图以及实现轨迹回放 附完整代码

百度地图开放平台 https://lbs.baidu.com/index.php?title%E9%A6%96%E9%A1%B5 javaScript API https://lbs.baidu.com/index.php?titlejspopularGL 百度地图实例 https://lbsyun.baidu.com/index.php?titleopen/jsdemoVue Baidu Map文档 https://dafrok.github.io/vue-baidu…