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
1.png QQ截图20171030115221.png
发送端一直不定时发此类数据

但是我用STM32F103RCT6单片机接收丢包挺多,丢包的频率很规律  应该是我程序代码没写严谨,求大神指点

error2 和 error3  都有错误  但是error1一直为0   说明校验是成功的



  1. void Init_NVIC(void)
  2. {        
  3.         NVIC_InitTypeDef NVIC_InitStructure;                        //定义一个NVIC向量表结构体变量

  4.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断组 为2
  5.   
  6.         NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                                //配置串口1为中断源
  7.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;           //设置占先优先级
  8.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                               //设置副优先级
  9.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
  10.         NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器
  11.        
  12.        
  13.         NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;                                //配置串口1为中断源
  14.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =        0;           //设置占先优先级
  15.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                               //设置副优先级
  16.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
  17.         NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器

  18.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;                                  //配置串口1为中断源
  19.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;           //设置占先优先级
  20.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;                               //设置副优先级
  21.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
  22.         NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器
  23.        
  24.         NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                                //配置串口1为中断源
  25.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;           //设置占先优先级
  26.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                               //设置副优先级
  27.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
  28.         NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器

  29.        
  30. }

  31. void Init_IO(void)
  32. {
  33.         GPIO_InitTypeDef GPIO_InitStructure;                                                                                                                //定义一个GPIO结构体变量
  34.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);                                                //使能各个端口时钟,重要!!!
  35.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  36.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource0);

  37.   GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2;                      //警报灯               
  38.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                           //通用输出推挽
  39.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                           //配置端口速度为50M
  40.   GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                                   //根据参数初始化GPIOD寄存器
  41.        
  42.   GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_3;                                               //警报灯   
  43.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                           //通用输出推挽
  44.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                           //配置端口速度为50M
  45.   GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                                   //根据参数初始化GPIOD寄存器
  46.        
  47.   GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;                      //移动指示                        
  48.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;                                                          
  49.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                           //配置端口速度为50M
  50.   GPIO_Init(GPIOC, &GPIO_InitStructure);                                                                                                   //根据参数初始化GPIOD寄存器
  51. }
复制代码

  1. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. ** 函数名称: USART1_Send_Byte
  3. ** 功能描述: 串口发送一个字符串
  4. ** 参数描述:Data 要发送的数据
  5. ** 作   者: Dream
  6. ** 日   期: 2011年6月20日
  7. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  8. void USART2_Send_Byte(uint16_t Data)
  9. {
  10.         while(!USART_GetFlagStatus(USART2,USART_FLAG_TXE));          //USART_GetFlagStatus:得到发送状态位
  11.                                                                                                                   //USART_FLAG_TXE:发送寄存器为空 1:为空;0:忙状态
  12.         USART_SendData(USART2,Data);                                                  //发送一个字符
  13. }
  14. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  15. ** 函数名称: USART1_Send_Byte
  16. ** 功能描述: 串口发送一个字符串
  17. ** 参数描述:Data 要发送的数据
  18. ** 作   者: Dream
  19. ** 日   期: 2011年6月20日
  20. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  21. uint8_t USART2_Receive_Byte(void)
  22. {
  23.            while(!(USART_GetFlagStatus(USART2,USART_FLAG_RXNE))); //USART_GetFlagStatus:得到接收状态位
  24.                                                                                                                    //USART_FLAG_RXNE:接收数据寄存器非空标志位
  25.                                                                                                                    //1:忙状态  0:空闲(没收到数据,等待。。。)
  26.         return USART_ReceiveData(USART2);                                           //接收一个字符
  27. }
  28. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  29. ** 函数名称: Usart_Init
  30. ** 功能描述: 串口引脚初始化
  31. ** 参数描述: 无
  32. ** 作   者: Dream
  33. ** 日   期: 2011年6月20日
  34. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  35. void Init_Usart2(void)
  36. {
  37.         GPIO_InitTypeDef GPIO_InitStructure;                                        //定义一个GPIO结构体变量

  38.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
  39.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 ,ENABLE);               
  40.                                                                                                                         //使能各个端口时钟,重要!!!

  41.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                                 //配置串口发送端口挂接到9端口
  42.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                           //复用功能输出开漏
  43.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //配置端口速度为50M
  44.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器       

  45.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;          //接收
  46.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入(复位状态);                                          
  47.   GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器       
  48. }
  49. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  50. ** 函数名称: Usart_Configuration
  51. ** 功能描述: 串口配置函数
  52. ** 参数描述: BaudRate设置波特率
  53. ** 作   者: Dream
  54. ** 日   期: 2011年6月20日
  55. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  56. void Usart2_Configuration(uint32_t BaudRate)
  57. {
  58.         USART_InitTypeDef USART_InitStructure;                                                                    //定义一个串口结构体

  59.         USART_InitStructure.USART_BaudRate            = BaudRate ;                                  //波特率115200
  60.         USART_InitStructure.USART_WordLength          = USART_WordLength_8b;         //传输过程中使用8位数据
  61.         USART_InitStructure.USART_StopBits            = USART_StopBits_1;                 //在帧结尾传输1位停止位
  62.         USART_InitStructure.USART_Parity              = USART_Parity_No ;                 //奇偶失能
  63.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流失能
  64.         USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx; //接收和发送模式
  65.         USART_Init(USART2, &USART_InitStructure);                                                                //根据参数初始化串口寄存器
  66.         USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);                                                        //使能串口中断接收
  67.         USART_Cmd(USART2, ENABLE);                                                                                             //使能串口外设
  68. }
  69. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  70. ** 函数名称: USART1_IRQHandler
  71. ** 功能描述: 串口中断函数
  72. ** 参数描述: 无
  73. ** 作   者: Dream
  74. ** 日   期: 2011年6月20日
  75. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  76. void USART2_IRQHandler()       
  77. {
  78.         int i=0;
  79.         u8 a=0;
  80.         extern u8 UART2_Save_data_box[UART2_Save_data_box_number];                          //放置UART2接收到的字节  需要溢出归0
  81.         extern u16 UART2_Save_data_box_pointer;                                                                  //放置UART2接收到的字节盒子下一个数据放置的位置指向标志        需要溢出归0
  82.         extern u32 EPC_box[EPC_number];
  83.         extern u16 EPC_box_pointer;
  84.         extern u8 back_correct;
  85.         extern u32 error1;
  86.         extern u32 error2;
  87.         extern u32 error3;
  88.         extern u32 EPC_count_l;
  89.         extern u32 EPC_count_h;
  90.         extern u32 timer1;
  91.         extern u8 zisuo3;
  92.        
  93.        
  94.         if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)           //读取接收中断标志位USART_IT_RXNE
  95.                                                                                                                 //USART_FLAG_RXNE:接收数据寄存器非空标志位
  96.                                                                                                                 //1:忙状态  0:空闲(没收到数据,等待。。。)
  97.         {
  98.                 if(UART2_Save_data_box[0]==0xBB)                                                                                          //判断数据包头
  99.                 {
  100.                         UART2_Save_data_box[UART2_Save_data_box_pointer]=USART_ReceiveData(USART2);       //继续存储数据
  101.                         UART2_Save_data_box_pointer++;
  102.                        
  103.                        
  104.                        
  105.                         if(UART2_Save_data_box[1]==0x98 && UART2_Save_data_box[5]==0x0D && UART2_Save_data_box[6]==0x0A)   //判断数据包尾
  106.                         {
  107.                                 for(i=1;i<4;i++)                                                  //计算校验值
  108.                                 {
  109.                                         a+=(u8)UART2_Save_data_box[i];
  110.                                 }
  111.                                 if(a==UART2_Save_data_box[4])                            //校验成功
  112.                                 {
  113.                                         if(UART2_Save_data_box[3]==0x01)
  114.                                         {
  115.                                                 back_correct=1;
  116.                                                 OUT2_LED=0;
  117.                                         }
  118.                                 }
  119.                                 for(i=0;i<UART2_Save_data_box_number;i++)
  120.                                 {
  121.                                         UART2_Save_data_box[i]=0;                                   //一旦判断到数据包的尾部则数组初始化
  122.                                 }
  123.                                 UART2_Save_data_box_pointer=1;                                //一旦判断到数据包的尾部则置1
  124.                         }
  125.                        
  126.                        
  127.                        
  128.                         else if(UART2_Save_data_box[1]==0x97 && UART2_Save_data_box[21]==0x0D && UART2_Save_data_box[22]==0x0A)   //判断数据包尾
  129.                         {
  130.                                 for(i=1;i<20;i++)                                                  //计算校验值
  131.                                 {
  132.                                         a+=(u8)UART2_Save_data_box[i];
  133.                                 }
  134.                                 if(a==UART2_Save_data_box[20])                            //校验成功
  135.                                 {
  136.                                         for(i=0;i<3;i++)
  137.                                         {
  138.                                                 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
  139.                                                 EPC_box_pointer++;
  140.                                         }
  141.                                         zisuo3=0;
  142.                                         OUT1_jingbao=1;             //输出报警
  143.                                         timer1=0;                                //计时清0
  144.                                                
  145.                                         EPC_count_l++;              //标签总数+1
  146.                                         if(EPC_count_l>=1000000000)
  147.                                         {
  148.                                                 EPC_count_l=0;
  149.                                                 EPC_count_h++;
  150.                                         }
  151.                                 }
  152.                                 else
  153.                                 {
  154.                                         error1++;                                                      //偶然错误 错误标志加1
  155.                                 }
  156.                                 for(i=0;i<UART2_Save_data_box_number;i++)
  157.                                 {
  158.                                         UART2_Save_data_box[i]=0;                                   //一旦判断到数据包的尾部则数组初始化
  159.                                 }
  160.                                 UART2_Save_data_box_pointer=1;                                //一旦判断到数据包的尾部则置1
  161.                         }
  162.                        
  163.                        
  164.                        
  165.                        
  166.                        
  167.                         else if(UART2_Save_data_box_pointer>=23)                                                                                                //偶尔性的数据错误   开始清0
  168.                         {
  169.                                 for(i=0;i<UART2_Save_data_box_number;i++)
  170.                                 {
  171.                                         UART2_Save_data_box[i]=0;                             
  172.                                 }
  173.                                 UART2_Save_data_box_pointer=1;     
  174.                                 error2++;                                                      //偶然错误 错误标志加1
  175.                         }
  176.                        
  177.                        
  178.                        
  179.                         if(EPC_box_pointer>=EPC_number)
  180.                         {
  181.                                 EPC_box_pointer=0;
  182.                         }
  183.                 }
  184.                
  185.                
  186.                
  187.                 else if(UART2_Save_data_box[0]==0x00)                                                              //如果上个数据不是数据包头
  188.                 {
  189.                         UART2_Save_data_box[0]=USART_ReceiveData(USART2);                 //储存数据到UART2
  190.                 }
  191.                 else
  192.                 {
  193.                         error3++;
  194.                         UART2_Save_data_box[0]=USART_ReceiveData(USART2);                 //储存数据到UART2
  195.                 }
  196.                 USART_ClearITPendingBit(USART2,USART_IT_RXNE);                                                                                   //清除中断标志位
  197.         }
  198. }
复制代码



0条回答

一周热门 更多>