关于STM32串口断帧问题

目前我知道的断帧的方式有两种:

1、通过判断特殊字符0x0d 0x0a或者自定义字符如0x5a 0xa5(起始),0xfa,0xaf(结束)

其串口程序可以为

void USART3_4_IRQHandler(void)                    
{
     unsigned char Res3;
   if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  
     {
        Res3 =USART_ReceiveData(USART3);//(USART3->DR);
          USART_ClearITPendingBit(USART3,USART_IT_RXNE);
         
          Usart3_Buff[Usart3_Data_Number]=Res3 ;
          Usart3_Data_Number++;
          if(Usart3_Buff[0]!=0x5A)  Usart3_Data_Number=0; 
            if(Usart3_Data_Number>=Usart_Max_Recive_Data-2) Usart3_Data_Number=0;
          if((Usart3_Buff[Usart3_Data_Number-2] == 0xfa)&&(Res3 == 0xaf))         
            {
               usart3_data_len=Usart3_Data_Number;
                 Usart3_Recive_flag=1;
                 Usart3_Data_Number=0;
            }
     }            
     if(( USART_GetITStatus(USART3, USART_IT_ORE) != RESET ) || ( USART_GetFlagStatus(USART3,          USART_FLAG_ORE) != RESET ) )
     {
            USART_ReceiveData(USART3); 
          USART_ClearITPendingBit(USART3,USART_IT_RXNE);
     }

方式2:通过定时器断帧

void USART3_IRQHandler(void)
{
  if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)      //串口接收中断
  {
     USART_ClearITPendingBit(USART3, USART_IT_RXNE);         //清除空闲中断标志
     USART3_RBuf[USART3_RBuf_CNT]=USART_ReceiveData(USART3);
     USART3_RBuf_CNT++;
     if(USART3_RBuf_CNT>=100) USART3_RBuf_CNT=0;
     MBMasterTimersEnable(1);                                //开启定时器断帧
  }
 if(USART_GetFlagStatus(USART3, USART_FLAG_ORE) != RESET) 
 {
     USART_ClearFlag(USART3,USART_FLAG_ORE);    //读SR
     USART_ReceiveData(USART3);//清除ORE中断(先读SR 再读DR)
 }
}  

void DMA_TIMER_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStruct;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct; 
    u16 PrescalerValue = 0;
    
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStruct);
    
  PrescalerValue = (uint16_t) (SystemCoreClock / 20000) - 1;                      // 1/20000=50us 
  TIM_TimeBaseStruct.TIM_Period = (USART3_Baud>19200?35:500000/(USART3_Baud));    //定时器计数值 count much n_50us 
  TIM_TimeBaseStruct.TIM_Prescaler = PrescalerValue;                              //定时器分频系数
  TIM_TimeBaseStruct.TIM_ClockDivision = 0;                                       //设置时钟分割
  TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;                        //定时器计数模式向上计数
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
  TIM_ARRPreloadConfig(TIM3, ENABLE);                                            //使能ARR上的预装载寄存器
}

 

void MBMasterTimersEnable(u8 Timer_EN)
{
  if (1 == Timer_EN)
    {
        TIM_SetCounter(TIM3,0x0000);                  //复位定时器计数值为0
        TIM_Cmd(TIM3, ENABLE);                        //使能定时器
        TIM_ClearFlag(TIM3, TIM_FLAG_Update);         //清除定时器更新标志
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);      //使能定时器中断
    }
    else
    {
        TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);    //关闭定时器中断
        TIM_Cmd(TIM3, DISABLE);                      //关闭定时器
    }
}

void TIM3_IRQHandler(void)  
{
   if (RESET != TIM_GetITStatus(TIM3, TIM_IT_Update))
    {
       TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除定时器中断标志
       MBMasterTimersEnable(0);                     //关闭定时器
       mb_rtu_Fram.MB_CNT=USART3_RBuf_CNT;          //获取接收到的数据
       USART3_RBuf_CNT=0;                           //清零
       mb_rtu_Fram.MB_PORT_STA = 1;                 //串口接收到数据置位
    }

代码贴上来了  代码是经过测试的  可以直接使用    

 

转载于:https://my.oschina.net/u/3497345/blog/906674

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值