微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STM32串口接收字符串问题

STM32串口接收字符串问题

时间:10-02 整理:3721RD 点击:
单个字节的收发都没问题,看了下字符串的收发,还是不明白原理,在串口中断里面还是会用的查询数据寄存器的函数USART_ReceiveData(USART1),虽然定义了一个变量来读取数据data=USART_ReceiveData(USART1);然后在把这个变量data赋给一个数组,但是data的值不是一样永远是字符串的最后一个字节吗?因为我发送的字符串是一次性发送的啊,不是一个一个的发送啊,数据寄存器里的数据会被最后一个字符覆盖啊。如果我发送一个字符就读取一次数据,然后赋给数组,这样是可以的,但是这就不是接收字符串了啊!

数组是有标号的,第一个接收到的数据放到标号0里,第二个接收到的数据放到标号1里,以此类推,数据包一定会有一个数据包结束的标示字节的,数组长度一定大于数据包长度的。

void USART1_IRQHandler(void)                  //接收数据
{
         
         if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
             {
                      for(RS485_RX_CNT=0;RS485_RX_CNT<5;RS485_RX_CNT++)      
                                {
                                     res=USART_ReceiveData(USART1);
                                         if(RS485_RX_CNT<64)
                                             {
                                                 RS485_RX_BUF[RS485_RX_CNT]=res;
                                                         RS485_RX_CNT++;
                                                  }
                                         
                                         }
                          
                                      flag++;
                                  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                                         
                                       
                 }
       
}
中断函数,这样完全没用啊,接收到的还是字符串的最后一个字符               

void USART1_IRQHandler(void)                  //接收数据
{
         
         if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
             {
                   //   for(RS485_RX_CNT=0;RS485_RX_CNT<5;RS485_RX_CNT++)      
                   //               {
                                     res=USART_ReceiveData(USART1);
                                         if(RS485_RX_CNT<64)
                                             {
                                                 RS485_RX_BUF[RS485_RX_CNT]=res;
                                                         RS485_RX_CNT++;
                                                  }
                                         
                        //                 }
                          
                                      flag++;
                                  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                                         
                                       
                 }
       
}
应该是 这样,去掉那个循环,但是接收到的还是字符串的最后一个字符                        

做测试用,先假定数组长度为12,数据接收后大于12长度的数据覆盖最早的数据,可以试试发送一个长度大于12,但小于24的字符串看看效果,每调试过,应该是接收的第13个字符会覆盖数组第一个字符,以此类推
void USART1_IRQHandler(void)                  //接收数据
{
         if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
              {
                                     res=USART_ReceiveData(USART1);
                                          if(RS485_RX_CNT<12)
                                              {
                                                  RS485_RX_BUF[RS485_RX_CNT]=res;
                                                          RS485_RX_CNT++;
                                                   }
                                             RS485_RX_CNT = 0;
                                      flag++;
                                   USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                                          
                                         
                  }
         
}

问题不在数组上面, res=USART_ReceiveData(USART1);res只是一个整型变量,接收数据后res的值只可能是字符串的最后一个字符啊;难道第一字符接收给res后,res在赋值给数组的【1】元素,但是这里没有循环啊,而且发送端是一次性发送啊,串口的数据寄存器要一个个的处理了?这不可能啊。
  res是整型变量也只能表示一个字符啊,所以这个中断不可能接收一个字符串啊。但是网上都是这样的啊

看来我得去看看以前51的程序了,实在想不明白了

RS485_RX_CNT++;这里就是在循环了,原理和过程跟51是一样的

如果我一次发了10个字符,那么会进10次中断,分别把这10个字符放到数组里面?但STM32有那么快吗?我是一次发了10个字符啊,STM32每次接收到一个字符就中断一次来处理这个字符到数组里面,真的有那么快?明天在把程序好好修理一下试试。

今天试试了,字符会丢失一部分,也就是说中断处理并没有把每个字符都接收到,在处理的时候一部分字符被覆盖掉了。为啥网上那么多这样的程序呢?

传统的字符串接收,就是一个字符一个字符的接收,
判断结束有两个方法,一个是固定结束符;一个是延时,延时到了没有数据就算这包数据的结束

void USART1_IRQHandler(void)                  //接收数据
{
         if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
              {
                                     res=USART_ReceiveData(USART1);
                                          if(RS485_RX_CNT<12)
                                              {
                                                  RS485_RX_BUF[RS485_RX_CNT]=res;
                                                          RS485_RX_CNT++;
                                                         return;//加上这句
                                                   }
                                             RS485_RX_CNT = 0;
                                      flag++;
                                   USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                  }
         
}//试一下

void USART1_IRQHandler(void)                  //接收数据
{
         if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)
              {
                                     res=USART_ReceiveData(USART1);
                                          if(RS485_RX_CNT<12)
                                              {
                                                  RS485_RX_BUF[RS485_RX_CNT]=res;
                                                          RS485_RX_CNT++;
                                                         return;//加上这句
                                                   }
                                             RS485_RX_CNT = 0;
                                      flag++;
                                   USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                  }
         
}//试一下


看看这图,这出来完全是乱的,每次出来根本不是10个字符啊,第一次出来是12345,第二次出来一个9.如果是一个字符一个的接收,那应该进10次中断。但是我觉得串口数据寄存器里面的数据会被覆盖掉,也就是说中断处理来不急转移每个字符。

加了这句已经接收不到数据了,

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top