# STM32F4UartRecvDemo_1 **Repository Path**: fengdaokanhai/stm32-f4-uart-recv-demo_1 ## Basic Information - **Project Name**: STM32F4UartRecvDemo_1 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2022-02-28 - **Last Updated**: 2022-02-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #### 1、工程结构说明 > 1. ChipSetDriver :存放外设IC驱动,如at24cxx、adc0832等等 > 2. ControlDriver:存放控制器驱动,如iic控制器、Uart控制器等等 > 3. Main :主任务 > 4. ModulePkg:模块化的某一逻辑功能,如Modbus,MQTT等 > 5. Project:工程文件 > 6. Startup_config:启动文件,主要是汇编及中断向量表 > 7. STM32F4_FWLIB:SDK > 8. System:存放系统功能一些文件,如delay > 9. ThirdOpenSrc:取自第三方开源库,如cjson等等 #### 2、平台说明 > 1. Demo基于STM32F4平台,Uart3进行测试 #### 3、Demo演示 >**`图示:Uart Demo 效果演示`** > > #### 4、定长数据接收源码说明 ```c ControlUart-FixDataLen.c USART3_IRQRecvFixDataLenWithOutProtocolF0 : 每接收一个字节直接写buff USART3_IRQRecvFixDataLenWithOutProtocolF1 : 每接收到一包完整的数据,再写buff ``` **4.1 、裸跑分析** * `裸跑时上述两个接口分析` 1. 两个接口在主任务能够及时轮询处理,fifo空间写入与读取能够满足,都不会丢包。 2. 两个接口在主任务不能及时轮询处理,fifo被中断写满,都会导致丢包: 2.1. USART3_IRQRecvFixDataLenWithOutProtocolF0 :存在单字节数据丢失,导致ffifo中后续的数据已经不是完整帧,全部错乱。!!所以不建议采用这种方式!! 2.2. USART3_IRQRecvFixDataLenWithOutProtocolF1 :存在丢整帧数据,但是如果丢也是整包数据,不会扰乱fifo中其它的完整帧。 *** * `裸机情况下,如果主任务其它工作耗时特别大,等轮询到读取fifo并处理时,fifo早都被uart中断填满,丢掉了好多数据,所以裸机跑应该注意一下几点:` 1. 尽可能代码优化,减少耗时,这样轮询时间就快一点读取到fifo,不至于fifo满掉。 2. 可以把fifo空间调大,以匹配该项目的时间轮序机制。 *** * `裸机情况下如何尽可能保证不丢包?` > 说明:为何说尽可能,因为fifo不是无限大的,定义大了,很有可能栈错误。所以fifo大小也是有限的,而如果主任务不能及时读取fifo,而数据又不断的发过来填充到fifo,所以fifo大小也是有限的,而如果主任务不能及时读取fifo,必然导致丢数据。 1. 多个fifo实现乒乓操作或者把1个fifo缓冲区调节的足够大**,`其目的是让fifo缓冲尽可能大`**: 1.1. 1个fifo缓冲区调节的足够大,大到满足项目需求。 1.2. 多个fifo实现乒乓操作,以满足项目需求 :有弊端,主任务不能把控先写入fifo的先处理。 2. dma+空闲中断+1个fifo的环形缓冲。 (如果系统资源够,那就把dma用上无妨) `目的:让cpu尽可能高效率的执行,减少时间开销能尽快的轮询到uart读取fifo,处理数据的功能点上。` *** **4.1 、跑OS分析** os下,单个线程中读取fifo处理,问题不大。 #### 5、非定长加协议数据接收源码说明 ``` /*********************************************************************** * 函数名称: FrameDataUnpack * 功能描述: 解析单字节数据流,输出一个完整的数据帧 * 输入参数: data:单字节流数据 frame:此处作为输出参数 * 输出参数: * 返 回 值: 1:数据帧解析成功 0:数据帧解析失败 * 其 它: 包头包尾单字节,带转义功能 0xc0 xx xx 0xc0 ***********************************************************************/ int FrameDataUnpack(ST_FRAME* frame, unsigned char data); /*********************************************************************** * 函数名称: FrameDataUnpackSingleWithoutEsc * 功能描述: 解析单字节数据流,输出一个完整的数据帧 * 输入参数: data:单字节流数据 frame:此处作为输出参数 * 输出参数: * 返 回 值: 1:数据帧解析成功 0:数据帧解析失败 * 其 它: 包头包尾单字节+不带转译功能:需保证数据段不含0xc0 0xc0 .. 0xc0 ***********************************************************************/ int FrameDataUnpackSingleWithoutEsc(ST_FRAME *frame, unsigned char data) /*********************************************************************** * 函数名称: FrameDataUnpackDoubleWithoutEsc * 功能描述: 解析单字节数据流,输出一个完整的数据帧 * 输入参数: data:单字节流数据 frame:此处作为输出参数 * 输出参数: * 返 回 值: 1:数据帧解析成功 0:数据帧解析失败 * 其 它: 包头包尾双字节+不带转译功能,不考虑中间数据字段出现连续0xeb 0x90 0xeb 0x90 ... 0xed 0x03 ***********************************************************************/ int FrameDataUnpackDoubleWithoutEsc(ST_FRAME *frame, unsigned char data); ```