STM32串口接收数据包丢包严重
2019-07-14 19:12发布
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
接收数据为:BB 97 11 30 00 11 22 33 44 55 66 77 88 99 00 11 22 FD 6F 03 1A 0D 0A
发送端一直不定时发此类数据
但是我用STM32F103RCT6单片机接收丢包挺多,丢包的频率很规律 应该是我程序代码没写严谨,求大神指点
error2 和 error3 都有错误 但是error1一直为0 说明校验是成功的
- void Init_NVIC(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure; //定义一个NVIC向量表结构体变量
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断组 为2
-
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //配置串口1为中断源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //设置占先优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //设置副优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
- NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
-
-
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //配置串口1为中断源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //设置占先优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //设置副优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
- NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //配置串口1为中断源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //设置占先优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //设置副优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
- NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
-
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //配置串口1为中断源
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //设置占先优先级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //设置副优先级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
- NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
-
- }
- void Init_IO(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能各个端口时钟,重要!!!
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource0);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //警报灯
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用输出推挽
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根据参数初始化GPIOD寄存器
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //警报灯
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用输出推挽
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根据参数初始化GPIOD寄存器
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //移动指示
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
- GPIO_Init(GPIOC, &GPIO_InitStructure); //根据参数初始化GPIOD寄存器
- }
复制代码
- /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- ** 函数名称: USART1_Send_Byte
- ** 功能描述: 串口发送一个字符串
- ** 参数描述:Data 要发送的数据
- ** 作 者: Dream
- ** 日 期: 2011年6月20日
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
- void USART2_Send_Byte(uint16_t Data)
- {
- while(!USART_GetFlagStatus(USART2,USART_FLAG_TXE)); //USART_GetFlagStatus:得到发送状态位
- //USART_FLAG_TXE:发送寄存器为空 1:为空;0:忙状态
- USART_SendData(USART2,Data); //发送一个字符
- }
- /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- ** 函数名称: USART1_Send_Byte
- ** 功能描述: 串口发送一个字符串
- ** 参数描述:Data 要发送的数据
- ** 作 者: Dream
- ** 日 期: 2011年6月20日
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
- uint8_t USART2_Receive_Byte(void)
- {
- while(!(USART_GetFlagStatus(USART2,USART_FLAG_RXNE))); //USART_GetFlagStatus:得到接收状态位
- //USART_FLAG_RXNE:接收数据寄存器非空标志位
- //1:忙状态 0:空闲(没收到数据,等待。。。)
- return USART_ReceiveData(USART2); //接收一个字符
- }
- /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- ** 函数名称: Usart_Init
- ** 功能描述: 串口引脚初始化
- ** 参数描述: 无
- ** 作 者: Dream
- ** 日 期: 2011年6月20日
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
- void Init_Usart2(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO结构体变量
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 ,ENABLE);
- //使能各个端口时钟,重要!!!
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //配置串口发送端口挂接到9端口
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能输出开漏
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置端口速度为50M
- GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数初始化GPIOA寄存器
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //接收
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入(复位状态);
- GPIO_Init(GPIOA, &GPIO_InitStructure); //根据参数初始化GPIOA寄存器
- }
- /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- ** 函数名称: Usart_Configuration
- ** 功能描述: 串口配置函数
- ** 参数描述: BaudRate设置波特率
- ** 作 者: Dream
- ** 日 期: 2011年6月20日
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
- void Usart2_Configuration(uint32_t BaudRate)
- {
- USART_InitTypeDef USART_InitStructure; //定义一个串口结构体
- USART_InitStructure.USART_BaudRate = BaudRate ; //波特率115200
- USART_InitStructure.USART_WordLength = USART_WordLength_8b; //传输过程中使用8位数据
- USART_InitStructure.USART_StopBits = USART_StopBits_1; //在帧结尾传输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); //根据参数初始化串口寄存器
- USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); //使能串口中断接收
- USART_Cmd(USART2, ENABLE); //使能串口外设
- }
- /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- ** 函数名称: USART1_IRQHandler
- ** 功能描述: 串口中断函数
- ** 参数描述: 无
- ** 作 者: Dream
- ** 日 期: 2011年6月20日
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
- void USART2_IRQHandler()
- {
- int i=0;
- u8 a=0;
- extern u8 UART2_Save_data_box[UART2_Save_data_box_number]; //放置UART2接收到的字节 需要溢出归0
- extern u16 UART2_Save_data_box_pointer; //放置UART2接收到的字节盒子下一个数据放置的位置指向标志 需要溢出归0
- extern u32 EPC_box[EPC_number];
- extern u16 EPC_box_pointer;
- extern u8 back_correct;
- extern u32 error1;
- extern u32 error2;
- extern u32 error3;
- extern u32 EPC_count_l;
- extern u32 EPC_count_h;
- extern u32 timer1;
- extern u8 zisuo3;
-
-
- if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //读取接收中断标志位USART_IT_RXNE
- //USART_FLAG_RXNE:接收数据寄存器非空标志位
- //1:忙状态 0:空闲(没收到数据,等待。。。)
- {
- if(UART2_Save_data_box[0]==0xBB) //判断数据包头
- {
- UART2_Save_data_box[UART2_Save_data_box_pointer]=USART_ReceiveData(USART2); //继续存储数据
- UART2_Save_data_box_pointer++;
-
-
-
- if(UART2_Save_data_box[1]==0x98 && UART2_Save_data_box[5]==0x0D && UART2_Save_data_box[6]==0x0A) //判断数据包尾
- {
- for(i=1;i<4;i++) //计算校验值
- {
- a+=(u8)UART2_Save_data_box[i];
- }
- if(a==UART2_Save_data_box[4]) //校验成功
- {
- if(UART2_Save_data_box[3]==0x01)
- {
- back_correct=1;
- OUT2_LED=0;
- }
- }
- for(i=0;i<UART2_Save_data_box_number;i++)
- {
- UART2_Save_data_box[i]=0; //一旦判断到数据包的尾部则数组初始化
- }
- UART2_Save_data_box_pointer=1; //一旦判断到数据包的尾部则置1
- }
-
-
-
- else if(UART2_Save_data_box[1]==0x97 && UART2_Save_data_box[21]==0x0D && UART2_Save_data_box[22]==0x0A) //判断数据包尾
- {
- for(i=1;i<20;i++) //计算校验值
- {
- a+=(u8)UART2_Save_data_box[i];
- }
- if(a==UART2_Save_data_box[20]) //校验成功
- {
- for(i=0;i<3;i++)
- {
- EPC_box[EPC_box_pointer]=(UART2_Save_data_box[i*4+5]<<24)+(UART2_Save_data_box[i*4+1+5]<<16)+(UART2_Save_data_box[i*4+2+5]<<8)+(UART2_Save_data_box[i*4+3+5]<<0); //存储EPC
- EPC_box_pointer++;
- }
- zisuo3=0;
- OUT1_jingbao=1; //输出报警
- timer1=0; //计时清0
-
- EPC_count_l++; //标签总数+1
- if(EPC_count_l>=1000000000)
- {
- EPC_count_l=0;
- EPC_count_h++;
- }
- }
- else
- {
- error1++; //偶然错误 错误标志加1
- }
- for(i=0;i<UART2_Save_data_box_number;i++)
- {
- UART2_Save_data_box[i]=0; //一旦判断到数据包的尾部则数组初始化
- }
- UART2_Save_data_box_pointer=1; //一旦判断到数据包的尾部则置1
- }
-
-
-
-
-
- else if(UART2_Save_data_box_pointer>=23) //偶尔性的数据错误 开始清0
- {
- for(i=0;i<UART2_Save_data_box_number;i++)
- {
- UART2_Save_data_box[i]=0;
- }
- UART2_Save_data_box_pointer=1;
- error2++; //偶然错误 错误标志加1
- }
-
-
-
- if(EPC_box_pointer>=EPC_number)
- {
- EPC_box_pointer=0;
- }
- }
-
-
-
- else if(UART2_Save_data_box[0]==0x00) //如果上个数据不是数据包头
- {
- UART2_Save_data_box[0]=USART_ReceiveData(USART2); //储存数据到UART2
- }
- else
- {
- error3++;
- UART2_Save_data_box[0]=USART_ReceiveData(USART2); //储存数据到UART2
- }
- USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志位
- }
- }
复制代码
一周热门 更多>