关于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_TimeBaseInitTypeDefTIM_TimeBaseStruct;
u16 PrescalerValue = https://www.it610.com/article/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 = https://www.it610.com/article/(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; //串口接收到数据置位
}
}
代码贴上来了代码是经过测试的可以直接使用

【关于STM32串口断帧问题】转载于:https://my.oschina.net/u/3497345/blog/906674

    推荐阅读