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