OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3438|回复: 11

求助关于STM32F103RCT6串口3收到的32字节存放数组错位

[复制链接]

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
发表于 2017-11-10 10:05:56 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 GSYxz2012 于 2017-11-10 10:12 编辑

各位大神,我最近再做一个小东西,通过串口2和3读取CO2和PM2.5的数据然后通过串口1发送。串口2收到12字节完全没问题,但是串口3收到32字节的数据存放在数组发现最后的8字节跑到最前面去了,反复验证发现跑到前面的8字节确实为这一组数据的最后八个字节。然后就很纳闷串口2的数据就没有一点问题,本人新手C语言功底薄弱希望大家不吝赐教。
unsigned int CO2_Data[12];
unsigned int PM25_Data[32];
unsigned int i=0;
unsigned int j=0;

这是定义在中断外边的
PM25_Data[j]=PM25;        
j++;               
if(j==32)
{
        j=0;
}

这个是下面存放数组的部分,按照我的理解初始值J=0,收到的PM25第一个字节应该放在PM25_Data【0】里面然后j+1第二次进入依次循环,但是实验发现收到的第一个字节放在PM25_Data【8】里面了。发送程序经过测试发现没有问题,然后我直接把串口3的收到的数据直接转发串口1这样如果收到的数据错位就直接在串口助手上显示出来了,但是发现收到的数据没有错位就是往PM25_Data【】里面存放的时候错位了,最奇怪的是串口2同样的程序接收12字节的数据就完全没问题。希望有人能为我解惑。

最佳答案

查看完整内容[请看2#楼]

if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //假如pm25的包头是0xAA,0x55 我忘记了 { PM25 =USART_ReceiveData(USART3); Usart_Recieve_Buff[Recieve_Cnt]=PM25; switch(Usart_Status) { case 0: { if( Usart_Recieve_Buff[0]==0xAA) { ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-11-10 10:05:57 | 显示全部楼层
本帖最后由 aiyeba 于 2017-11-14 11:21 编辑
GSYxz2012 发表于 2017-11-10 16:21
前辈麻烦你帮忙看一下这个是不是逻辑问题。。。

if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //假如pm25的包头是0xAA,0x55  我忘记了
{
              PM25 =USART_ReceiveData(USART3);
              Usart_Recieve_Buff[Recieve_Cnt]=PM25;  
              switch(Usart_Status)
             {
                   case 0:
                   {
                             if(  Usart_Recieve_Buff[0]==0xAA)
                            {
                                Usart_Status=1;  
                                Recieve_Cnt ++;
                            }
                            break;
                   }
                   case 1:
                   {
                                if(  Usart_Recieve_Buff[1]==0x55)
                               {
                                      Usart_Status=2;  
                                      Recieve_Cnt ++;
                               }
                               else
                              {
                                       Usart_Status=0;  
                                       Recieve_Cnt =0;

                              }
                              break;
                   }
                   case 2:
                   {
                              Recieve_Cnt++;
                              if(Recieve_Cnt==32)      
                              {
                                   Recieve_Cnt=0;      
                                   Recieve_Flag=1;//表示一包数据接收成功了
                              }
                              break;
                   }
             }
}
自己选择的路,成家前走完。
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-10 14:25:56 | 显示全部楼层
自己先顶一下,有没有大神在的
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-10 14:26:14 | 显示全部楼层
在线等,急。。。
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-11-10 15:15:25 | 显示全部楼层
GSYxz2012 发表于 2017-11-10 14:26
在线等,急。。。

把你中断函数内容截图给我看看,我马上帮你解决了。
自己选择的路,成家前走完。
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-10 16:20:49 | 显示全部楼层
本帖最后由 GSYxz2012 于 2017-11-10 16:22 编辑
aiyeba 发表于 2017-11-10 15:15
把你中断函数内容截图给我看看,我马上帮你解决了。

void USART3_IRQHandler(void)                  
{
          u8 PM25;
        #if SYSTEM_SUPPORT_OS                             
                OSIntEnter();   
        #endif
        
                if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
                        {
                        PM25 =USART_ReceiveData(USART3);     
                        
                        if((USART_RX_STA&0x8000)==0)
                                {
                                if(USART_RX_STA&0x4000)
                                        {
                                        if(PM25!=0x0a)
                                                USART_RX_STA=0;
                                        else USART_RX_STA|=0x8000;      
                                        }
                                else
                                        {        
                                        if(PM25==0x0d)USART_RX_STA|=0x4000;
                                        else
                                                {
                                                USART_RX_BUF[USART_RX_STA&0X3FFF]=PM25 ;
                                                USART_RX_STA++;
                                                if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;     
                                                }                 
                                        }
                                }                    
                         }

                         PM25_Data[j]=PM25;        
                         j++;               
                         if(j==32)
                                 {
                                                j=0;
                                 }

        #if SYSTEM_SUPPORT_OS  
                OSIntExit();                                                                                          
        #endif
}
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-10 16:21:24 | 显示全部楼层
aiyeba 发表于 2017-11-10 15:15
把你中断函数内容截图给我看看,我马上帮你解决了。

前辈麻烦你帮忙看一下这个是不是逻辑问题。。。
回复

使用道具 举报

56

主题

520

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2014-11-18
在线时间
160 小时
发表于 2017-11-11 10:25:06 | 显示全部楼层
GSYxz2012 发表于 2017-11-10 16:21
前辈麻烦你帮忙看一下这个是不是逻辑问题。。。

你那里有串口打印马     应该是串口1   

在中断里面      接收完PM25  下面  加一句话     USART_SendData(USART1,PM25);

在串口调试助手里面看看内容是什么   

基本分析是     你对接收包没有做判断,就是什么时候接收到一包数据了。

也没有对数据包做过滤。  pm25是有协议的   包头对了才往下接收,不然就清零从来。





自己选择的路,成家前走完。
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-11 22:20:26 | 显示全部楼层
我就是用了串口打印,发现数据没问题,然后单独做了个数组给发送程序发现发送程序也没问题,也就是在接收数据往目标数组存放的时候错位了。
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-11 22:20:52 | 显示全部楼层
aiyeba 发表于 2017-11-11 10:25
你那里有串口打印马     应该是串口1   

在中断里面      接收完PM25  下面  加一句话     USART_Sen ...

我就是用了串口打印,发现数据没问题,然后单独做了个数组给发送程序发现发送程序也没问题,也就是在接收数据往目标数组存放的时候错位了。
回复

使用道具 举报

5

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2017-11-10
在线时间
46 小时
 楼主| 发表于 2017-11-14 14:43:24 | 显示全部楼层
aiyeba 发表于 2017-11-14 11:19
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //假如pm25的包头是0xAA,0x55  我忘记了
{ ...

谢谢前辈!我这边已经找到原因啦!本来程序针对32字节是没错的,但是那个PM2.5模块开头会先发8字节设置等等信息回来,占用了数组前8字节的空间,后续才发送32字节正式数据。而我写的那段程序是针对32字节的正式数据格式写的,不到32字节收满“j”不清0,所以所有数据都往后挪了8字节。
回复

使用道具 举报

0

主题

6

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2017-11-21
在线时间
0 小时
发表于 2017-11-21 12:13:39 | 显示全部楼层
STM8S103RCT6  热卖型号,陆续到货!有需求随时联系曾小姐:13163716750
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 15:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表