OpenEdv-开源电子网

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

STM32中串口prinft打印函数出现丢数据现象

[复制链接]

9

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2017-6-16
在线时间
46 小时
发表于 2018-1-2 14:49:45 | 显示全部楼层 |阅读模式
任务是测量数据,一下测量多次,然后将数据通过串口打印出来,现在的问题是出现数据漏打/丢失/少打现象。
重定向函数:
#if 1
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
        int handle;
};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{      
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
    USART_SendData(USART1,(u8)ch);   
        return ch;
}
#endif

串口函数:(使用串口1,波特率256000)
void USART_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate=256000;//波特率
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        USART_InitStructure.USART_StopBits=USART_StopBits_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(USART1,&USART_InitStructure);
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);     //开启串口接收中断 查询方式也可以不开启
        USART_Cmd(USART1,ENABLE);

}

串口接收中断函数:(串口随便发送一个数,当作一个开关用shice=1控制主函数中的if,cs设置测量多少次数)
void USART1_IRQHandler(void)
{
        u8 cstx;                                                                                //和GP21的通信测试
        GPIO_SetBits(GPIOC, GPIO_Pin_6);                                           //亮led灯看现象
        delay(100);
        if(!(USART_GetITStatus(USART1,USART_IT_RXNE))); //读取接收中断标志位USART_IT_RXNE
                                                        //USART_FLAG_RXNE:接收数据寄存器非空标志位
                                                        //1:忙状态  0:空闲(没收到数据,等待。。。)
        {
                  USART_ClearITPendingBit(USART1, USART_IT_RXNE);        //清除中断标志
                  GPIO_init();                                                                 //SPI2_WriteReadData(0x70);delay(1);
                  GPIO_ResetBits(GPIOC, GPIO_Pin_7);delay(1);
                  SPI2_WriteReadData(0xB5);                                                 //tongxin测试
                  cstx=SPI2_WriteReadData(0xFF);
                  GPIO_SetBits(GPIOC, GPIO_Pin_7);delay(1);
                  printf("REG_8=%d\n",cstx);

                  shice=0;                                                                       //  这时shice还不能为别的数 因为还没有配置完成
                  GPIO_init();GP2_init();delay(10);                                         //GPIO中执行电平复位并拉高SPI片选CS端            GP2中执行相关寄存器配置          
                  kflag=0;cs=500;delay(5);                                             //设置一次测量多少数据
                   pj=0;memset(c1,0,sizeof(c1));c2=0;cnt1=0;cnt2=0; delay(1);        //对相关统计数进行清0
                                             
                  printf("cs=%d\n",cs);
                  shice=1;t0=1;                                                            //打开shice使主函数中的if成立
                  GPIO_ResetBits(GPIOC, GPIO_Pin_6);
        }  
}

主函数:(打印测量出来的500个数据,并对数据进行处理再打印)
int main(void)
{
   RCC_Configuration();
   GPIO_Configuration();
   TIM2_Configuration();
   TIM3_Configuration();
   TIM4_Configuration();
   USART_Configuration();
   SPI2_Configuration();
   NVIC_Configuration();

   GPIO_SetBits(GPIOC, GPIO_Pin_7);      //SPI片选管脚先为1 不打开CS
   GPIO_init();                                       //GP21电源reset  
   GPIO_SetBits(GPIOC, GPIO_Pin_0|GPIO_Pin_1);        //使能GP21的start和stop1管脚

   while(1)                 //  串口执行完后cs=500;shice=1;if成立开始打印测量数据
           {       
                if((shice!=0)&&(t0==1 ))        //t0初始为1 shice初始为0 不成立 在串口里修改为1后才成立
             {       
                         GPIO_ResetBits(GPIOC, GPIO_Pin_7); delay(1);
                         SPI2_WriteReadData(0x70);                                       // 初始化
                       GPIO_SetBits(GPIOC, GPIO_Pin_7);
                        ret=shishicl();                         //时间测量        float型浮点数         调用之后SSN=1          kflag在累加   每用完一次后t0都被置1使if一直成立                           
                        if(kflag==cs)                         //cs是设置的测量次数         kflag在shishicl函数里累加 一直加到cs停止
                                    { t0=0;kflag=0;
                                  pj=pj/cnt1;p=cnt1;                              //计算499个数的平均值并打印
                                  printf("pj=%f\n cnt1=%d\n",pj,cnt1);    //数据处理
                                  while(p--)
                                           { if((c1[p]>(pj-0.0035))&&(c1[p]<(pj+0.0035)))           //499个数要剔除分散较大的数
                                                        {c2+=c1[p];cnt2++;}                                                 
                                     }
                                  printf("pj=%f\n cnt2=%d\n",c2/cnt2,cnt2);
                         }                                                      
                    pj+=ret;c1[cnt1]=ret;cnt1+=1;    //499个数据累加 并送入数组c1
                        printf("%f\n",ret);                       //打印500个数据
                 }               
        }
}


现象:
第一次cs设置成500打印出数据如下
REG_8=85
cs=500
0.371277
0.371277
0.358246
0.347900
0.341919
0.338013
0.3279541
0.290619
0.308105
0.313507
0.326263
0.326263
0.3271759
0.270905
0.272217
0.276550
0.280457
0.306793
0.3160710
0.289246
0.276581
0.274323
0.274323
0.274261
0.2767317
0.304993
0.302185
0.294373
0.280548
0.273346
0.275085
0.2728857
0.322296
0.322296
0.311462
0.301270
0.291779
0.287872
0.280396
0.276276
0.271210
0.275970
0.275970
0.290314
0.294098
0.303162
0.318787
0.323151
0.323792
0.320587
0.309753
0.309753
0.291504
0.286072
pj=0.298637
cnt1=499
pj=0.297745
cnt2=30
0.282837

大概只打引了60个数不到,从结果看cnt和pj都计算出来了,只是单纯的串口漏打。
第二次把数组大小和cs修改为100,打印数据如下
REG_8=85
cs=100
0.310120
0.305481
0.304565
0.311310
0.307068
0.322693
0..275604
0.265350
0.261505
0.262421
pj=0.286911
cnt1=99
pj=0.287140
cnt2=5
0.260132

100个数只打印出10个数。蓝色标记应该是打印出错的数。
以上原因未知,还在继续调试,不知道有没有朋友遇到过这种问题,还求不吝赐教,谢谢!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

86

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2017-6-16
在线时间
46 小时
 楼主| 发表于 2018-1-2 15:26:15 | 显示全部楼层
发现把波特率改为9600和19200则打印数据正常,改成28800则数据出现丢失。
初步判断与波特率有关,只是奇怪,波特率高了为啥会丢失数据,这样的话,串口速度就无法保证了
,高一些的波特率岂不成了摆设。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-16 08:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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