STM32接收不定长数据
来源:互联网 发布:路由器显示网络不可用 编辑:程序博客网 时间:2024/05/22 12:12
接受不定长数据的原理:建立一个数据缓冲的数组,开启接收中断和串口空闲中断,每一次接收则把数据存入缓存区,当产生空闲中断表示这一帧数据接受完成。
(1)构造缓冲
struct STRUCT_USARTx_Fram strUsart_Fram_Record = {0};
#if defined ( __CC_ARM )#pragma anon_unions#endif/******************************* ESP8266 外部全局变量声明 ***************************/#define RX_BUF_MAX_LEN 500 //最大接收缓存字节数extern struct STRUCT_USARTx_Fram //串口数据帧的处理结构体{char Data_RX_BUF [ RX_BUF_MAX_LEN ]; union { __IO u16 InfAll; struct { __IO u16 FramLength :15; // 14:0 __IO u16 FramFinishFlag :1; // 15 } InfBit; }; }strUsart_Fram_Record;
其中需要注意的是#pragma anon_unions, #pragma no_anon_unions
这些编译指示启用和禁用对匿名结构和联合的支持。没有这句话是编译不过的。
(2)注意需要打开空闲检测
(3)接受中断将字符保存到缓冲区内,接受的长度大于缓冲区长度,则不处理。
检查到空闲中断,则 finish 位置1.
这里需要注意的是,如果发送一次数据,finish完成,此时数据没有处理,下一次串口的数据会继续放入缓存中。
代码如下:
/** ****************************************************************************** * 文件名程: bsp_usartx.c * 作 者: 硬石嵌入式开发团队 * 版 本: V1.0 * 编写日期: 2015-10-04 * 功 能: 串口底层驱动程序 ****************************************************************************** * 说明: * 本例程配套硬石stm32开发板YS-F1Pro使用。 * * 淘宝: * 论坛:http://www.ing10bbs.com * 版权归硬石嵌入式开发团队所有,请勿商用。 ****************************************************************************** *//* 包含头文件 ----------------------------------------------------------------*/#include "bsp/usart/bsp_usartx.h"/* 私有类型定义 --------------------------------------------------------------*//* 私有宏定义 ----------------------------------------------------------------*//* 私有变量 ------------------------------------------------------------------*//* 扩展变量 ------------------------------------------------------------------*//* 私有函数原形 --------------------------------------------------------------*//* 函数体 --------------------------------------------------------------------*//** * 函数功能: 配置NVIC,设定USART接收中断优先级. * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); /* 配置USART为中断源 */NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn; /* 抢断优先级为0 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; /* 子优先级为1 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* 使能中断 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */NVIC_Init(&NVIC_InitStructure);}/** * 函数功能: 串口参数配置. * 输入参数: 无 * 返 回 值: 无 * 说 明:使用宏定义方法代替具体引脚号,方便程序移植,只要简单修改bsp_led.h * 文件相关宏定义就可以方便修改引脚。 */void USARTx_Init(void){ /* 定义IO硬件初始化结构体变量 */ GPIO_InitTypeDef GPIO_InitStructure; /* 定义USART初始化结构体变量 */USART_InitTypeDef USART_InitStructure; /* 配置NVIC,设定USART接收中断优先级 */ NVIC_Configuration(); /* 使能USART时钟 */ USARTx_ClockCmd(USARTx_CLK,ENABLE); /* 使能USART功能GPIO时钟 */ USARTx_GPIO_ClockCmd(USARTx_TX_CLK | USARTx_RX_CLK | RCC_APB2Periph_AFIO,ENABLE); /* 调试USART功能GPIO初始化 *//* 设定USART发送对应IO编号 */GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN; /* 设定USART发送对应IO模式:复用推挽输出 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; /* 设定USART发送对应IO最大操作速度 :GPIO_Speed_50MHz */GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 初始化USART发送对应IO */GPIO_Init(USARTx_TX_PORT, &GPIO_InitStructure); /* 设定USART接收对应IO编号 */GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN; /* 设定USART发送对应IO模式:浮空输入 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 其他没有重新赋值的成员使用与串口发送相同配置 */ /* 初始化USART接收对应IO */GPIO_Init(USARTx_RX_PORT, &GPIO_InitStructure);/* USART工作环境配置 */ /* USART波特率:115200 */USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE; /* USART字长(有效位):8位 */USART_InitStructure.USART_WordLength = USART_WordLength_8b; /* USART停止位:1位 */USART_InitStructure.USART_StopBits = USART_StopBits_1; /* USART校验位:无 */USART_InitStructure.USART_Parity = USART_Parity_No ; /* USART硬件数据流控制(硬件信号控制传输停止):无 */USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;/* USART工作模式使能:允许接收和发送 */ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* 初始化USART */USART_Init(USARTx, &USART_InitStructure); /* 使能接收中断 */ USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); USART_ITConfig ( USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断 /* 使能USART */USART_Cmd(USARTx, ENABLE); /* 清除发送完成标志 */USART_ClearFlag(USARTx, USART_FLAG_TC|USART_FLAG_TXE|USART_FLAG_RXNE);}/** * 函数功能: 重定向c库函数printf到USARTx * 输入参数: 无 * 返 回 值: 无 * 说 明:无 */int fputc(int ch, FILE *f){ /* 发送一个字节数据到调试串口 */ USART_SendData(USARTx, (uint8_t) ch); /* 等待串口数据发送完毕 */ while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); return (ch);}///**// * 函数功能: 串口发送一个字节数据 // * 输入参数: ch:待发送字符// * 返 回 值: 无// * 说 明:无// *///void Usart_SendByte(uint8_t ch)//{// /* 发送一个字节数据到USART1 */// USART_SendData(USARTx,ch);// /* 等待发送完毕 */// while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);//}///**// * 函数功能: 串口发送指定长度的字符串// * 输入参数: str:待发送字符串缓冲器// * strlen:指定字符串长度// * 返 回 值: 无// * 说 明:无// *///void Usart_SendStr_length(uint8_t *str,uint32_t strlen)//{// unsigned int k=0;// do // {// Usart_SendByte(*(str + k));// k++;// } while(k < strlen);//}///**// * 函数功能: 串口发送字符串,直到遇到字符串结束符// * 输入参数: str:待发送字符串缓冲器// * 返 回 值: 无// * 说 明:无// *///void Usart_SendString(uint8_t *str)//{//unsigned int k=0;// do // {// Usart_SendByte(*(str + k));// k++;// } while(*(str + k)!='\0');//}struct STRUCT_USARTx_Fram strUsart_Fram_Record = {0};void USARTx_IRQHANDLER(void){uint8_t ucCh;if(USART_GetITStatus(USARTx,USART_IT_RXNE)!=RESET){ ucCh=USART_ReceiveData(USARTx);if(strUsart_Fram_Record.InfBit.FramLength<(RX_BUF_MAX_LEN-1)){strUsart_Fram_Record.Data_RX_BUF[strUsart_Fram_Record.InfBit.FramLength++]=ucCh;}}if(USART_GetITStatus(USARTx,USART_IT_IDLE)==SET){ strUsart_Fram_Record .InfBit .FramFinishFlag = 1;ucCh = USART_ReceiveData(USARTx); //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)}}
#ifndef __BSP_USARTX_H__#define __BSP_USARTX_H__/* 包含头文件 ----------------------------------------------------------------*/#include <stm32f10x.h>#include <stdio.h>/* 类型定义 ------------------------------------------------------------------*//* 宏定义 --------------------------------------------------------------------*/#define USARTx_BAUDRATE 115200#define USARTx_ClockCmd RCC_APB2PeriphClockCmd#define USARTx_CLK RCC_APB2Periph_USART1#define USARTx_GPIO_ClockCmd RCC_APB2PeriphClockCmd #define USARTx_TX_PORT GPIOA #define USARTx_TX_PIN GPIO_Pin_9#define USARTx_TX_CLK RCC_APB2Periph_GPIOA #define USARTx_RX_PORT GPIOA #define USARTx_RX_PIN GPIO_Pin_10#define USARTx_RX_CLK RCC_APB2Periph_GPIOA#define USARTx_IRQHANDLER USART1_IRQHandler#define USARTx_IRQn USART1_IRQn#define USARTx USART1/* 扩展变量 ------------------------------------------------------------------*//* 函数声明 ------------------------------------------------------------------*/void USARTx_Init(void);void Usart_SendByte(uint8_t ch);void Usart_SendStr_length(uint8_t *str,uint32_t strlen);void Usart_SendString(uint8_t *str);#if defined ( __CC_ARM )#pragma anon_unions#endif/******************************* ESP8266 外部全局变量声明 ***************************/#define RX_BUF_MAX_LEN 500 //最大接收缓存字节数extern struct STRUCT_USARTx_Fram //串口数据帧的处理结构体{char Data_RX_BUF [ RX_BUF_MAX_LEN ]; union { __IO u16 InfAll; struct { __IO u16 FramLength :15; // 14:0 __IO u16 FramFinishFlag :1; // 15 } InfBit; }; }strUsart_Fram_Record;#endif // __BSP_USARTX_H__/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
阅读全文
0 0
- STM32接收不定长数据
- STM32串口接收不定长数据原理与源程序
- STM32空闲中断+DMA解决接收不定长数据问题
- stm32 串口接收不定长数据 清测可行
- STM32串口接收不定长数据原理与源程序
- STM32空闲中断+DMA解决接收不定长数据问题
- STM32串口接收不定长数据原理与源程序
- Stm32——串口空闲中断+DMA接收不定长数据
- stm32串口DMA收发,可以接收不定长数据,格式化输出。
- STM32串口使用IDLE中断接收不定长数据原理与源程序
- STM32使用串口IDLE中断的两种接收不定长数据的方式
- STM32使用串口1配合DMA接收不定长数据,大大减轻CPU载荷。
- stm32使用两路串口及接收不定长数据的实现
- stm32-串口接受不定长数据方法(3种)
- stm32-串口使用IDLE中断接受不定长数据方法
- stm32-串口接受不定长数据方法(3种)
- stm32-串口接受不定长数据方法(3种)
- STM32F207运用串口空闲中断+DMA接收不定长数据
- HDU 2018 母牛的故事
- Python查找一个文章里出现次数最多的10的单词
- A1025. PAT Ranking (25)
- STM32的RS485调试过程记录
- WXH♂Round
- STM32接收不定长数据
- HDU
- 锁的粒度:ThreadLocal、volatile、Atomic和Synchronized
- 扩展entity framework core 实现默认字符串长度,decimal精度,entity自动注册和配置
- [leetcode]546. Remove Boxes
- HDU 2044 一只小蜜蜂...
- 从头到尾打印链表
- 数据结构——五
- python 网络编程之socketserver模块