linux 串口 断帧,关于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;                 //串口接收到数据置位

}

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值