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

2019-07-21 00:27发布

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

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


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
www88988
1楼-- · 2019-07-21 04:14
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);//???????,? ??        
                                                                        ////???:??????
                                                                        USART1_SendOneChar('9');
                                                                        USART1_SendOneChar('E');
                                                                        USART1_SendOneChar('F');
                                                                        USART1_SendOneChar('7');
                                                                                                         
                                        }
                                        //UART_Put_Num(i);        //????????i????
                                        USART1_SendStr(" ");  
          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)!='' )
    {
       USART1_SendOneChar(*str);
       str++;
     }
}



15级的许同学
2楼-- · 2019-07-21 05:03
 精彩回答 2  元偷偷看……
xlong_06
3楼-- · 2019-07-21 06:26
 精彩回答 2  元偷偷看……
15级的许同学
4楼-- · 2019-07-21 07:38
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寄存器、       
}
www88988
5楼-- · 2019-07-21 07:56
你那个 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 发送
串口发送数据只跟波特率有关,不需要延时,可以去了延时。改动后再用串口助手试试。
15级的许同学
6楼-- · 2019-07-21 11:32
本帖最后由 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);//打印一列的颜 {MOD},以 结尾        
                        //已修改:单独发送字符
                        USART1_SendOneChar('9');
                        USART1_SendOneChar('E');
                        USART1_SendOneChar('F');
                        USART1_SendOneChar('7');
                                
                }
                UART_Put_Num(i);        //这个用来输出当前i的计数值
                USART1_SendStr(" ");        
               
        }
}[/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

一周热门 更多>