串口接收处理数据

串口接收处理数据

串口初始化

stm32的串口初始化

void USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	// 打开串口GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 打开串口外设的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

        // 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 配置串口的工作参数
	// 配置波特率
	USART_InitStructure.USART_BaudRate = 115200;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式,收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(USART2, &USART_InitStructure);

          NVIC_InitTypeDef NVIC_InitStructure;
  
        /* 嵌套向量中断控制器组选择 */
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
         
        /* 配置USART为中断源 */
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        /* 抢断优先级*/
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        /* 子优先级 */
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
          /* 使能中断 */
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        /* 初始化配置NVIC */
          NVIC_Init(&NVIC_InitStructure);
	
	// 使能串口接收中断
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);	
	USART_ClearITPendingBit(USART2, USART_IT_RXNE);  //清楚中断标志
	// 使能串口
	USART_Cmd(USART2, ENABLE);		

   
        
        for(int i=0;i<r_BufNum;i++)
    {
    	_rw_para._r_buf_status[i] = empty;//清空缓存器
        
    }
}

数据接收结构体

#define  USART_TX_GPIO_PIN        GPIO_Pin_2
#define  USART_RX_GPIO_PIN        GPIO_Pin_3

//枚举类型
typedef enum data_ht {
	yes, no
} data_ht; //数据接收包头状态
typedef enum BufStatus {
	empty, full
} BufStatus; //数据缓存器状态 空还是满

//发送接收数据宏定义
#define r_BufNum 5  //数据接收缓存器个数
#define w_BufNum 5  //数据发送缓存器个数
#define r_BtyeNum 16 //数据接收缓存器长度
#define w_BtyeNum 16 //数据发送缓存器长度


//数据发送以及接受结构体
typedef struct _RW_Data {
	uint8_t _r_buf[r_BufNum][r_BtyeNum]; //数据接收缓存器
	uint8_t _w_buf[w_BufNum][r_BtyeNum]; //数据发送缓存器
	uint8_t _r_pos; //数据接收缓存器偏移地址 指在哪个缓存器
	uint8_t _w_pos; //数据发送缓存器偏移地址 指在哪个缓存器
	uint8_t _r_pos_byte; //数据接收缓存器字节偏移地址
	uint8_t _w_pos_byte; //数据发送缓存器字节偏移地址
	data_ht _r_header; //数据包头状态   yes=已经收到包头 no=未收到包头
	data_ht _r_first; //数据包头第一个字节状态  yes=已经收到第一个字节 no=未收到第一个字节
	BufStatus _r_buf_status[r_BufNum]; //数据接送缓存器状态 empty=空 full=满
	BufStatus _w_buf_status[w_BufNum]; //数据发送缓存器状态 empty=空 full=满
	uint8_t Cur_DealPackage_Pos; //当前数据包处理的位置

} _RW_Data;

中断接收函数

//中断接收
void USART2_IRQHandler(void)    //串口2中断服务程序
{
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断
  {
    uint8_t Receivedata;
   
    
    //USART_ClearITPendingBit(USART2, USART_IT_RXNE);  //清楚中断标志
    USART_ClearFlag(USART2, USART_FLAG_RXNE);
    
    Receivedata  = USART_ReceiveData(USART2);
    
    
    uint8_t i;
    crc=0;
    
    if(_rw_para._r_header == no)//包头数据还未找到
    {
      if(_rw_para._r_first == yes)//第一个字节已经收到
      {
        if(Receivedata == 0x55)//如果数据是55 则说明包头数据接收成功
        {
          _rw_para._r_buf[_rw_para._r_pos][1] = 0x55;//存储数据
          _rw_para._r_pos_byte=2;	//数据储存位置为2
          _rw_para._r_header = yes;//包头数据已经找到
        }
        else//如果数据不对 则清除数据
        {
          _rw_para._r_pos_byte=0;	//数据储存位置清零
          _rw_para._r_first=no;//清空
          _rw_para._r_header = no;//包头数据清空
        }
      }
      else//还未收到第一个字节
      {
        if((uint8_t)Receivedata == 0xAA)//接收到包头数据
        {
          if(_rw_para._r_pos>=r_BufNum)//判断是否越界
            _rw_para._r_pos = 0;
          
          //判断缓存器是否是空的
          if(_rw_para._r_buf_status[_rw_para._r_pos] == empty)
          {
            _rw_para._r_buf[_rw_para._r_pos][0] = 0xAA;//存储数据
            _rw_para._r_pos_byte=1;	//数据储存位置为1
            _rw_para._r_first=yes;//第一个字节数据已经收到
          }
          else
          {
            //这里要做报警处理
          }
        }
        else//数据不对 则直接抛掉
        {
          _rw_para._r_pos_byte=0;	//数据储存位置清零
          _rw_para._r_first=no;//清空
          _rw_para._r_header = no;//包头数据清空
        }
      }
    }
    else//包头数据已经找到 开始接收数据
    {
      if(_rw_para._r_pos_byte>=r_BtyeNum)//如果越界的话
      {
        _rw_para._r_pos_byte = 0;
        //这里要添加报警
      }
      else//数据储存
      {
        _rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte] = Receivedata;//存储数据
        //如果数据个数到达了 那么可以进行数据处理了
        if((_rw_para._r_buf[_rw_para._r_pos][2]+4) == _rw_para._r_pos_byte)
        {
          //判断包尾的数据是否正确 如果正确 则进行解析
          if(_rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte] == 0xFF && _rw_para._r_buf[_rw_para._r_pos][_rw_para._r_pos_byte-1] == 0x55)
          {
            //这里要做CRC校验
            for(i=3;i<13;i++)
            {
              crc += _rw_para._r_buf[_rw_para._r_pos][i];//CRC
            }
            if(crc == _rw_para._r_buf[_rw_para._r_pos][13])//CRC校验成功
            {
              _rw_para._r_buf_status[_rw_para._r_pos] = full;//数据为满状态
              _rw_para._r_pos++;//缓存地址增加
              if(_rw_para._r_pos>=r_BufNum)//判断是否越界
                _rw_para._r_pos = 0;
              //这里开始进行数据处理 或者在中断外部处理 这里到时候看情况
              Deal_Package();//数据处理完后 状态要变成空
            }
            else;//这里发送CRC校验错误报警
          }
          else//如果数据包尾不正确 则需要进行报警
          {
            //这里添加报警
          }
          _rw_para._r_pos_byte=0;	//数据储存位置清零
          _rw_para._r_first=no;//清空
          _rw_para._r_header = no;//包头数据清空
        }
        else//数据个数没有到达 则继续接收
        {
          _rw_para._r_pos_byte++;//地址进行偏移
        }
      }
      
    }
    
  }
  
}

数据处理函数

//数据处理
void Deal_Package(void){
  
  if(_rw_para._r_buf_status[_rw_para.Cur_DealPackage_Pos] == full)
    
  {
   ................................................
  }
  _rw_para._r_buf_status[_rw_para.Cur_DealPackage_Pos] = empty;//数据为空状态
  _rw_para.Cur_DealPackage_Pos++;//偏移量增加
  
  if(_rw_para.Cur_DealPackage_Pos>=r_BufNum)//地址越界判断
  _rw_para.Cur_DealPackage_Pos = 0;
  
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值