15级的许同学 发表于 2019-5-10 11:19:51

麻烦各位帮忙看下,关于串口发送数据的问题


                  各位大哥好,小弟我用的是stm32f103:通过串口发数据,在不加入延时函数,串口调试助手接收到的数据会有丢失

          以下OV7670_CreatColor()是通过串口向pc发送数据的,重点在两个for循环上,内for循环,我加入了延时20ms时候接收到的数据是完整的,延时10ms也会出现数据丢失。但是我觉得串口发送数据,通过判断发送标志位TC,应该能确保发发送正确的。现在困惑问题出在哪里了。


admin 发表于 2019-5-11 08:57:19

15级的许同学 发表于 2019-5-10 11:20
void OV7670_CreatColor()
{
   uint16_t i,j,k = 0;


你的这个应该是串口通信问题吧,有没有单独测试printf打印?快速的通过printf输出。你的重定向fputc函数前面两句删掉试试,参考下我们printf重定向实验

15级的许同学 发表于 2019-5-10 11:20:07

本帖最后由 15级的许同学 于 2019-5-10 11:22 编辑

void OV7670_CreatColor()
{
   uint16_t i,j,k = 0;
   uint16_t color = 0; //列缓存区
   uint16_t buff;
   u8 buf;
   u8 color1,color2;
   while(1)
   { //数据开始(从上往下,从左往右)
      USART1_SendStr("data:\r\n");   
      for(i=0;i<240;i++)
      {   

         for(j=0;j < 640;j++)//一列   
         { //生成彩条 9E F7,8D EF ,9E 3F,83 1F,FF F0,43 D9,95 28,82 10   
             if(i < 30 && i >= 0)   
            {   
            color = 0x9EF7;
            color1=0x9E;
            color2=0xF7;
            }
            else if(i < 60&& i >= 30)   
            {   
               color = 0x8DEF;
               color1=0x8D;
               color2=0xEF;   
            }
            else if(i < 90&& i >= 60)   
            {   
            color = 0x9E3F;
            color1=0x9E;
            color2=0x3F;   
             }
            else if(i < 120&& i >= 90)   
            {   
            color = 0x831F;
            color1=0x83;
            color2=0x1F;   
            }
            else if(i < 150&& i >= 120)   
            {   
            color = 0xFFF0;
            color1=0xFF;
            color2=0xF0;   
            }
            else if(i < 180&& i >= 150)   
            {   
            color = 0x43D9;
            color1=0x43;
            color2=0xD9;   
             }
            else if(i < 210&& i >= 180)   
            {   
            color = 0x9528;
            color1=0x95;
            color2=0x28;   
            }
            else   
            {   
            color = 0x8210;
            color1=0x82;
            color2=0x10;   
            }   
            //buff = color;
            buf=color1;
            j++;
            buf=color2;
       } //准备好一列数据
    //上面只是赋值作用,应该与输出问题无关

       USART1_SendStr("L");//列有效

       for(k=0;k<640;k++)   
       {   
         //printf("%04X", buff);//打印一列的颜色,以\n结尾
         printf("%02X", buf);//打印颜色的高字节
         k++;
       printf("%02X", buf);//打印颜色的低字节
          delay_ms(20);//不加这个延时,或者只有10ms就会出现很严重的数据丢失,比如320个字符,丢失一半
       }
       UART_Put_Num(i);
       USART1_SendStr("\r\n");
   }
       return ;
}
}
         以下是我的串口发送函数:printf()已经重定向设置完毕了
         
int fputc(int ch, FILE *f)
{
   USART1->SR;
   USART_ClearFlag(USART1,USART_FLAG_TC); //发送完成,tc位自动置1
   USART_SendData(USART1, (uint8_t) ch);
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}      
   return ch;
}
//添加:--------发送一个字符------------------
int USART1_SendOneChar(uchar ch)
{
   USART1->SR;
   USART_ClearFlag(USART1,USART_FLAG_TC); //发送完成,tc位自动置1
   USART_SendData(USART1,(u8)ch);
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
   return (ch);
}


//------ 发送字符串--------------
void USART1_SendStr(uchar *str)
{
   while( (*str)!='\0' )
    {
       USART1_SendOneChar(*str);
       str++;

   }
}

       麻烦各位大佬看一看,小弟不胜感激!

15级的许同学 发表于 2019-5-12 09:45:50

admin 发表于 2019-5-11 08:57
你的这个应该是串口通信问题吧,有没有单独测试printf打印?快速的通过printf输出。你的重定向fputc函数 ...

admin大哥你好,应该不是printf()的问题,我单独测试了USART1_SendOneChar()函数来完成这个输出功能,,不加入延时函数的时候也会出现大量数据丢失

以下是我的主函数
int main()
{
      u16 i,j,k,color;
      SysTick_Init(72);
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组 分2组
      LED_Init();
         
      USART1_Init(115200);
         
         
      for(i=0;i<240;i++)               
      {      
               
                USART1_SendStr("L");//列有效                        
                for(k=0;k<320;k++)                        
                {      
                        color=0x9EF7;      
                        //printf("%04X", color);//打印一列的颜色,以\n结尾      
                        //已修改:单独发送字符
                        USART1_SendOneChar('9');
                        USART1_SendOneChar('E');
                        USART1_SendOneChar('F');
                        USART1_SendOneChar('7');
                                 
                }
                UART_Put_Num(i);      //这个用来输出当前i的计数值
                USART1_SendStr("\r\n");      
               
      }
}

以下是我的串口发送一个字符程序:
int USART1_SendOneChar(uchar ch){
   
      //USART1->SR;
      //USART_ClearFlag(USART1,USART_FLAG_TC);//发送完成,tc位自动置1

      USART_SendData(USART1,(u8)ch);      
      while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
       return (ch);
}
串口初始化函数中,为了排除是串口接收中断的可能,也已经注释掉USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
这个程序中,串口助手里收到数据,还是会有丢失,比如前一次是i=4的时候,下一次就变成了i=6了,中间i=5的数据不知道去哪里了

15级的许同学 发表于 2019-5-12 10:01:07

各位大哥好,我再次修改主函数,不加入延时函数时,还是出现很严重的数据丢失,麻烦大家帮忙看看,小弟不胜感激

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"

/*******************************************************************************
* 函 数 名         : main
* 函数功能   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
u16 i,j,k,color;
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组 分2组
LED_Init();

USART1_Init(115200);


for(i=0;i<240;i++)
{

USART1_SendStr("L");//列有效   
for(k=0;k<320;k++)   
{
   color=0x9EF7;
   //发送字符9
   USART_ClearFlag(USART1,USART_FLAG_TC);//发送完成,tc位自动置1
   USART_SendData(USART1,'9');
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
   //发送字符E

   USART_ClearFlag(USART1,USART_FLAG_TC);//发送完成,tc位自动置1
   USART_SendData(USART1,'E');
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
   
   
}
UART_Put_Num(i);
USART1_SendStr("\r\n");

}

}


15级的许同学 发表于 2019-5-12 10:40:31

谢谢各位大哥,问题解决了,是串口助手的原因,我用了SSCOM3.2接收数据,可以完全显示出来的
特别感谢3楼大哥给的思路方向,admin大哥的回答



Kiwi2021 发表于 2022-7-21 12:15:11

页: [1]
查看完整版本: 麻烦各位帮忙看下,关于串口发送数据的问题