关于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
推荐阅读
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- 四首关于旅行记忆的外文歌曲
- 醒不来的梦
- 关于自我为中心的一点感想
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- 关于Ruby的杂想
- 关于读书的思考
- 关于this的一些问题(1)
- 《声之形》
- 关于如何沟通的1/2/3