OpenEdv-开源电子网

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

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

[复制链接]

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
发表于 2019-5-10 14:28:14 | 显示全部楼层 |阅读模式
5金钱
          各位大哥好,小弟我用的是stm32f103:通过串口发数据,在不加入延时函数,串口调试助手接收到的数据会有丢失

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


最佳答案

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

这是我的测试结果 ((4 * 320)+3)*240 = 307920 一点也不少啊 //下面是子函数 void test(void) { u16 i,k;//color; for(i=0;i
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-10 14:28:15 | 显示全部楼层
15级的许同学 发表于 2019-5-12 09:36
5楼大哥你好,我按照你说的单独测试了串口输出:
  以下是主函数实验程序:[mw_shl_code=cpp,true]int m ...


这是我的测试结果  ((4 * 320)+3)*240 = 307920 一点也不少啊

//下面是子函数
void test(void)
{
  u16 i,k;//color;
         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");  
          IWDG_Feed();  // 喂狗(没开启看门狗可以去掉)                               
        }
}

void USART1_SendOneChar(u8 ch)
{      
                USART_SendData(USART1,ch);        
                while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
        }

void USART1_SendStr(u8 *str)
{
     while( (*str)!='\0' )
    {
       USART1_SendOneChar(*str);
       str++;
     }
}



回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
 楼主| 发表于 2019-5-10 14:28:36 | 显示全部楼层
本帖最后由 15级的许同学 于 2019-5-10 14:29 编辑

[mw_shl_code=cpp,true]void OV7670_CreatColor()
{
   uint16_t i,j,k = 0;
   uint16_t color = 0; //列缓存区
   uint16_t buff[320];
   u8 buf[640];
   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[j] = color;
            buf[j]=color1;
            j++;
            buf[j]=color2;
       } //准备好一列数据
      //上面只是赋值作用,应该与输出问题无关

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

       for(k=0;k<640;k++)   
       {   
         //printf("%04X", buff[k]);//打印一列的颜色,以\n结尾
         printf("%02X", buf[k]);//打印颜色的高字节  
         k++;
         printf("%02X", buf[k]);//打印颜色的低字节
          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++;

     }
} [/mw_shl_code]
回复

使用道具 举报

1

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2011-12-1
在线时间
110 小时
发表于 2019-5-10 15:38:04 | 显示全部楼层
是你的接收端接收速度慢,或者你发送的波特率低,数据都没有传完你又开始传数据了,数据肯定丢!
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
 楼主| 发表于 2019-5-11 08:48:26 | 显示全部楼层
xlong_06 发表于 2019-5-10 15:38
是你的接收端接收速度慢,或者你发送的波特率低,数据都没有传完你又开始传数据了,数据肯定丢!

3楼大哥你好,我设置波特率是115200,接收端是串口调试助手,不是自己编写的上位机,也设置了波特率115200。是接受端接收数据不及时的问题吗?。。。。
以下是我的串口初始化函数:调用的是USART1_Init(115200);

/*******************************************************************************
* 函 数 名         : USART1_Init
* 函数功能                   : USART1初始化函数
* 输    入         : bound:波特率
* 输    出         : 无
*******************************************************************************/
void USART1_Init(u32 bound)
{
   //GPIO端口设置
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);         //打开时钟

       
        /*  配置GPIO的模式和IO口 */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX                           //串口输出PA9
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;            //复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);  /* 初始化串口输入IO */
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX                         //串口输入PA10
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;                  //模拟输入
        GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
       

   //USART1 初始化设置
        USART_InitStructure.USART_BaudRate = bound;//波特率设置
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        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); //初始化串口1
       
        USART_Cmd(USART1, ENABLE);  //使能串口1
       
        USART_ClearFlag(USART1, USART_FLAG_TC);
               
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断

        //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、       
}
回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-11 09:46:31 | 显示全部楼层
你那个 USART1_SendOneChar(uchar ch) 函数可这么写
USART1_SendOneChar(uchar ch)
{
   USART_SendData(USART1, ch);
   while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
}
因为没有做中断处理所以初始化时去了
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断
这句话
发送数据别用printf函数,就用你的USART1_SendOneChar 发送
串口发送数据只跟波特率有关,不需要延时,可以去了延时。改动后再用串口助手试试。
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
 楼主| 发表于 2019-5-12 09:36:17 | 显示全部楼层
本帖最后由 15级的许同学 于 2019-5-12 10:13 编辑
www88988 发表于 2019-5-11 09:46
你那个 USART1_SendOneChar(uchar ch) 函数可这么写
USART1_SendOneChar(uchar ch)
{

5楼大哥你好,我按照你说的单独测试了串口输出:
  以下是主函数实验程序:[mw_shl_code=cpp,true]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");        
               
        }
}[/mw_shl_code]



以下是串口发送一个字符程序:(已修改)
[mw_shl_code=applescript,true]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);
}[/mw_shl_code]

串口初始化函数中,也已经注释掉USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
串口助手里收到数据,还是会有丢失,比如前一次是i=4的时候,下一次就变成了i=6了,中间i=5的数据不知道去哪里了。

以下是串口助手收到的部分情况。
QQ图片20190512095731.png

回复

使用道具 举报

0

主题

79

帖子

0

精华

高级会员

Rank: 4

积分
727
金钱
727
注册时间
2016-5-27
在线时间
91 小时
发表于 2019-5-12 10:41:15 | 显示全部楼层
1.jpg
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-4-22
在线时间
10 小时
 楼主| 发表于 2019-5-12 10:42:37 | 显示全部楼层
本帖最后由 15级的许同学 于 2019-5-12 10:44 编辑

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

回复

使用道具 举报

17

主题

587

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4467
金钱
4467
注册时间
2013-6-27
在线时间
565 小时
发表于 2019-5-12 11:46:14 | 显示全部楼层
GLOBAL void USART1Send(char send_data)
{
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);// 发送寄存器是否为空
    USART_SendData(USART1,send_data);
}

这个写法可以参看下
让我们的思维驾驭在电的速度之上!
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2019-6-2
在线时间
4 小时
发表于 2019-6-2 22:12:39 | 显示全部楼层
www88988:你好!借贴向您请教以下:我用printf函数发送数据到上位机,老是出现通讯是好是坏的现象,是咋会事?同一个程序,昨天用的好好的,今天就不行了,但是上位机发送数据到下位机没有问题,问题就是下位机发送数据到上位机是好是坏?谢谢!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-17 05:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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