/*** @file usart2.c* @author zhaoguangxin (zhaoguangxin@qq.com)* @brief * @version 0.1* @date 2022-08-25* * @copyright Copyright (c) 2022* */#include <rtthread.h>
#include <string.h>
#include <serial.h>/* 设备句柄 */
#define UART_NAME       "uart2"
static rt_device_t serial;/* 消息传递队列 */
#define USART2_QUE_NUM           (10)
static struct rt_messagequeue  rx_que;
typedef struct{rt_uint32_t p_read;         //开始读取地址rt_uint32_t p_end;          //读取的结束地址
}Rx_Index_t;
static rt_uint8_t msg_pool[sizeof(Rx_Index_t) * USART2_QUE_NUM];/* FIFO */
#define USART2_RX_MAX            (1024UL)
typedef struct{rt_uint32_t wIndex;rt_uint32_t rIndex;rt_uint8_t overFlag;rt_uint8_t *fifo;
}Rx_FIFO_t;
static Rx_FIFO_t usart2FIFO;/* 分帧定时器 */
static struct rt_timer firTimer;
static rt_uint8_t timerStatus = 0;  //0未启动 1:启动/*** @name: firTimer_timeout* @func: 分帧定时器回调函数* @input: * parameter:参数* @output: none* @return: none*/
static void firTimer_timeout(void* parameter)
{Rx_Index_t rIndex;rIndex.p_read = usart2FIFO.rIndex;rIndex.p_end = (usart2FIFO.wIndex == 0) ? (USART2_RX_MAX - 1) : (usart2FIFO.wIndex  - 1);usart2FIFO.rIndex = usart2FIFO.wIndex;if( rt_mq_send( &rx_que, &rIndex, sizeof(rIndex) ) == -RT_EFULL )rt_kprintf("message queue full!\n");
}/*** @name: uart_input* @func: 串口2接收回调函数* @input: * dev:设备* size:接收的数据量* @output: none* @return: none*/
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{while( 1 ){if( rt_device_read(serial, -1, &usart2FIFO.fifo[usart2FIFO.wIndex], 1) == 1 ){usart2FIFO.wIndex += 1;if( usart2FIFO.wIndex >= USART2_RX_MAX )usart2FIFO.wIndex = 0;if( usart2FIFO.wIndex == usart2FIFO.rIndex )usart2FIFO.overFlag = 1;}else{break;}}if( timerStatus == 0 )rt_timer_start(&firTimer);else{int arg = 10;rt_timer_control(&firTimer, RT_TIMER_CTRL_SET_TIME, &arg);}return RT_EOK;
}/*** @name: USART2_GetData* @func: 串口2获取数据* @input: * timeout:超时* @output:* getBuff:输出获取的数据 需要外部释放* len:获取的数据长度* @return: * 0:成功  其他失败*/
int USART2_GetData(rt_uint8_t **getBuff, rt_uint32_t *len, rt_uint32_t timeout)
{rt_uint32_t tempLen = 0;Rx_Index_t recIndex;rt_uint8_t *p = RT_NULL;if( getBuff == RT_NULL || len == RT_NULL){return -1;}memset(&recIndex, 0, sizeof(recIndex));if(rt_mq_recv(&rx_que, &recIndex, sizeof(recIndex), timeout) != RT_EOK){  //读取串口队列消息,没有数据就阻塞等待return -1;}if( usart2FIFO.overFlag != 0 ){usart2FIFO.overFlag = 0;}if( recIndex.p_end >= recIndex.p_read ){*len = recIndex.p_end - recIndex.p_read + 1;p = rt_malloc(*len + 1);if( p != RT_NULL ){memset(p, 0, *len + 1);memcpy(p, &usart2FIFO.fifo[recIndex.p_read], *len);}}else{tempLen = USART2_RX_MAX - recIndex.p_read;*len = tempLen + recIndex.p_end +1;p = rt_malloc(*len + 1);if( p != RT_NULL ){memset(p, 0, *len + 1);memcpy(p, &usart2FIFO.fifo[recIndex.p_read], tempLen);memcpy(p + tempLen, usart2FIFO.fifo,recIndex.p_end + 1);}}*getBuff = p;return 0;
}/*** @name: serial_thread_entry* @func: 串口2线程* @input: * parameter:线程参数* @output: none* @return: * 初始化结果*/
static void serial_thread_entry(void *parameter)
{rt_uint8_t *buf;rt_uint32_t len;while(1){if( 0 == USART2_GetData(&buf, &len, (rt_uint32_t)RT_WAITING_FOREVER)){rt_device_write(serial, 0, buf, len);rt_free(buf);}}
}/*** @name: uart2_init* @func: 串口2初始化* @input: * bound:波特率* @output: none* @return: * 初始化结果*/
int uart2_init(int bound)
{serial = rt_device_find(UART_NAME);if( !serial ){rt_kprintf("find %s failed!\n", UART_NAME);return RT_ERROR;}rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);struct serial_configure serialConfig = RT_SERIAL_CONFIG_DEFAULT;serialConfig.baud_rate = bound;rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &serialConfig);rt_device_set_rx_indicate(serial, uart_input);rt_mq_init(&rx_que, "rx_que",               //队列名称msg_pool,                       //存放队列的数据sizeof(Rx_Index_t),             //队列元素的大小sizeof(msg_pool),               //队列缓存的大小RT_IPC_FLAG_FIFO);              //有多个线程等待时,先到先得rt_timer_init(&firTimer, "firTimer",        //定时器名字是 firTimerfirTimer_timeout,           //超时时回调的处理函数RT_NULL,                  //超时函数的入口参数10,                       //定时长度为 30 个 OS Tick RT_TIMER_FLAG_ONE_SHOT);    //单次定时器 usart2FIFO.fifo = rt_malloc(USART2_RX_MAX);if( usart2FIFO.fifo == RT_NULL )return RT_ERROR;#if 1rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);if( thread != RT_NULL ){rt_thread_startup(thread);}else{return RT_ERROR;}
#endifreturn RT_EOK;
}

STM32+RTThread串口不定长接收相关推荐

  1. STM32使用串口空闲中断接收不定长数据帧-USART_IT_IDLE使用(不使用DMA方式)

    STM32使用串口空闲中断接收不定长数据帧-USART_IT_IDLE使用(不使用DMA方式) 前言 串口空闲中断介绍 清中断方法 串口中断处理函数 串口中断用到的全局变量定义 串口初始化(使能接收中 ...

  2. STM32单片机串口空闲中断接收不定长数据

    在使用单片机的串口通信功能时,常用的接收数据方法是通过固定的字节数来判断一帧数是否发送完成,或者是通过固定的结束标志位来表示一帧数据发送完成.但是有时候会遇到发送的数据长度不固定,也没有固定的结束标志 ...

  3. 国民技术 N32G45x RTThread 串口 IDLE 不定长接收 踩坑

    最近在使用国民技术的MCU芯片.串口是很重要的一个外设.在这里遇到了一些问题,总结如下: 一.串口引脚默认模式: 之前在用STM32串口时候,我们知道,STM32的串口使能后,RXD.TXD两个引脚默 ...

  4. java串口设备中断_利用DMA双缓冲或半完成中断实现串口不定长数据的接收

    在<HAL版本DMA循环模式串口数据收发>中介绍了利用DMA循环模式进行串口数据的收发,STM32F4xx的DMA还提供了双缓冲的功能,采用双缓冲模式,可以在一个DMA完成接收后,对其缓冲 ...

  5. 嵌入式Linux 串口编程系列3——通过VTIM、VMIN、select实现串口不定长数据接收功能

    上一篇文章中,我们详细分析了VTIM和VMIN的功能, <嵌入式Linux 串口编程系列2--termios的VMIN和VTIME深入理解> 也明白了这两个参数设计的初衷和使用方法,接下来 ...

  6. STM32CubeMX系列教程8:配置工程模板(串口+不定长数据收发+DMA+IDLE中断+软中断)

    文章目录 摘要 生成工程 配置外设 1.配置时钟与Debug 2.配置串口与DMA 3.配置定时器与中断 配置时钟树 配置工程设置 点击`GENERATE CODE`生成工程 修改源码 配置软中断 配 ...

  7. stm32 hal 串口只可以接收到一包数据数据

    stm32 串口笔记 问题 利用串口中断接收数据,只可以接收到一包数据数据 产生问题原因 串口产生了ORE过载错误,所以下一次再次使能接收中断,就不可以再次接收 解决办法就是 清除错误状态和数据寄存器 ...

  8. STM32单片机串口空闲中断+DMA接收不定长数据

    在上一篇文章STM32单片机串口空闲中断接收不定长数据中介绍了利用串口空闲中断接收不定长数据,这种方式有一个问题就是串口每接收到一个字节就会进入一次中断,如果发送的数据比较频繁,那么串口中断就会不停打 ...

  9. STM32从零到一,从标准库移植到HAL库,UART串口1以DMA模式收发不定长数据代码详解+常见问题 一文解析

    前言 本文的参考资料 感谢提供标准库版本的CSDN同学:这两篇文章至少是我看过的最详细的标准库配置DMA版本.而且代码实测稳定能用. STM32 | DMA配置和使用如此简单(超详细)_...| .. ...

最新文章

  1. 什么是软件定义数据中心
  2. HALCON双目重建
  3. 一则关于运算符的小例
  4. 洗被套的时候洗衣机里面不要再放其他东西
  5. 工单系统的设计与实现(3)
  6. Docker日志大小限制
  7. Android音频开发(3):如何播放一帧音频
  8. 修改Mysql默认 编码
  9. 机器学习在美团配送系统的实践:用技术还原真实世界
  10. css3 z-index,z-index的工作原理
  11. 2020年这个副业,能让你彻底告别死工资,你敢试吗?
  12. 电脑计算器_教训!19年中级败给了电脑计算器,CPA难道要步后尘?
  13. socket.onmessage没有接收到服务器消息_IM服务器设计-如何解决消息的乱序
  14. PS下载Adobe Photoshop 2020中文安装教程 亲测可用
  15. 你理解的智能家居就是智能家居么?
  16. 怎样批量替换Word中的文字?这一招Word文字替换技巧你会吗
  17. ubuntu下如何打开root文件夹,如何用root权限管理员权限打开文件夹,以及如何获取root权限
  18. 程序猿的办公桌都长啥样?
  19. 互联网创业公司融资、产品、运营快速迭代和人才模式总结
  20. PHP使用阿里云(语音合成)实现文字转语音“TTS“

热门文章

  1. 详解K-Means算法
  2. 移动设备 小米2S不显示CD驱动器(H),便携设备,MTP,驱动USB Driver,MI2感叹号的解决方法...
  3. jvm万字总结(图文+代码示例)
  4. 告别「热」情的大武汉,TiDB TechDay 2019 收官站杭州见!
  5. 一分钟搞懂如何修改VOS上话机注册端口
  6. 40款奇特的透明名片设计作品欣赏(上篇)
  7. mysql数据库及应用 作业_MySQL数据库设计与应用作业答案
  8. 融云Android对接视频,Android studio接入融云IM
  9. 2021年量子计算的研发现状与未来展望
  10. 如何画出一张合格的技术架构图? 1