OpenEdv-开源电子网

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

STM32FF407串口发送数据错误,调试时显示缓冲区数据是正确的,请大家帮帮忙看一下,不胜感激!

[复制链接]

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
发表于 2016-4-27 10:53:27 | 显示全部楼层 |阅读模式
1金钱
附代码如下:
void TData(uint8_t *_usBuf, uint8_t _usLen)   
{  
        uint8_t  Tx_Status, Txread, Txwrite, Txcounter;
        uint16_t  i;      
        
        Txread =p_uart.Tx_read;
        Txcounter =p_uart.Tx_counter;      
        
        //将待发送数据缓冲区写入UART发送数据缓冲区
        for(i=0; i<_usLen;i++)
        {
                 if(++Txread>= USART1_TX_BUF_SIZE)
                 {
                         Txread= 0;
                 }      
                 
                 if(++Txcounter>= USART1_TX_BUF_SIZE)  //判断发送缓冲区数据个数
                 {
                         Txcounter= 0;
                 }
                 
                 p_uart.pTxBuf[p_uart.Tx_write]= _usBuf;     
                 if(++p_uart.Tx_write>= USART1_TX_BUF_SIZE)     
                 {
                         p_uart.Tx_write= 0;
                 }
                 p_uart.Tx_counter++;                              
        }
        USART_ITConfig(USART1, USART_IT_TXE,ENABLE);  

if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)     
{
             USART_ClearITPendingBit(USART1,USART_IT_TXE);
             if(p_uart.Tx_read== p_uart.Tx_write)            //没有新数据
             {
                     USART_ITConfig(USART1,USART_IT_TXE, DISABLE);                    
                     USART_ITConfig(USART1,USART_IT_TC, ENABLE);   
             }
             else
             {
                     USART_SendData(USART1,p_uart.pTxBuf[p_uart.Tx_read]);
                     while(USART_GetFlagStatus(USART1,USART_FLAG_TXE == RESET));                    
                     if(++p_uart.Tx_read>= USART1_TX_BUF_SIZE)
                     {
                       p_uart.Tx_read = 0;
                     }
                     p_uart.Tx_counter--;
             }
}
        
else if(USART_GetITStatus(USART1, USART_IT_TC) !=RESET)
{
      USART_ClearITPendingBit(USART1,USART_IT_TC);    //清除发送完成标志位
      if(p_uart.Tx_read == p_uart.Tx_write)            //没有新数据
      {
        USART_ITConfig(USART1, USART_IT_TC,DISABLE);   //关闭发送完成中断
      }
      else
             {
                     USART_SendData(USART1,p_uart.pTxBuf[p_uart.Tx_read]);
                     while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);                     
                     if(++p_uart.Tx_read>= USART1_TX_BUF_SIZE)
                     {
                             p_uart.Tx_read= 0;
                     }
                     p_uart.Tx_counter--;
             }
}


最佳答案

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

谢谢大家了,问题出在这两个判断语句上。是我对中断发送数据原理理解的太不透彻了! [mw_shl_code=applescript,true] if(++Txread >= USART1_TX_BUF_SIZE) { Txread = 0; } if(++Txcounter >= USART1_TX_BUF_SIZE) //判断发送缓冲区数据个数 { Txcounter = 0; } [/mw_shl_ ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 10:53:28 | 显示全部楼层
谢谢大家了,问题出在这两个判断语句上。是我对中断发送数据原理理解的太不透彻了!
[mw_shl_code=applescript,true]  if(++Txread >= USART1_TX_BUF_SIZE)
                {
                        Txread = 0;
                }        

                if(++Txcounter >= USART1_TX_BUF_SIZE)  //判断发送缓冲区数据个数
                {
                        Txcounter = 0;
                } [/mw_shl_code]

回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 10:58:16 | 显示全部楼层
本人菜鸟一枚,刚刚接触STM32一个月的时间,有好多不懂的地方,还请大家多多指教!
回复

使用道具 举报

58

主题

6293

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11475
金钱
11475
注册时间
2014-4-1
在线时间
1297 小时
发表于 2016-4-27 11:00:15 | 显示全部楼层

错误长什么样?


回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 11:12:32 | 显示全部楼层
本帖最后由 DAY_AND_DAY 于 2016-4-27 11:19 编辑

这是main函数:

int main(void)
{
uint8_t *str;
           while(1)     
           {
                          str = "Welcome to STM321111";
                         TData(str, 20);
       }
}


调试时的缓冲区数据

调试时的缓冲区数据

串口调试时显示的数据

串口调试时显示的数据
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 11:17:15 | 显示全部楼层
本帖最后由 DAY_AND_DAY 于 2016-4-27 11:22 编辑

第一幅图是调试时,缓冲区的数据;
第二幅图是串口调试软件显示的数据。
望大侠能够多多指点!!!
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-4-27 11:33:22 | 显示全部楼层
如果你用的是发送中断
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
这句话就应该去掉。

还有上边那句
发送中断本来就是为了节省死等时间的
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 12:40:28 | 显示全部楼层
谢谢止天指点!
但问题该怎么解决呢?
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-4-27 13:35:50 | 显示全部楼层

直接删掉
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 13:44:55 | 显示全部楼层
我删掉了,但是问题依旧存在。
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 14:15:18 | 显示全部楼层

我删掉了,但是问题依旧存在。
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-27 14:15:49 | 显示全部楼层
DAY_AND_DAY 发表于 2016-4-27 13:44
我删掉了,但是问题依旧存在。

会不会是波特率的问题???
回复

使用道具 举报

2

主题

686

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
10569
金钱
10569
注册时间
2014-6-12
在线时间
1022 小时
发表于 2016-4-27 17:19:09 | 显示全部楼层
要想别人帮你还是把工程贴出来,这种片段别人没法帮。
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-28 08:57:03 | 显示全部楼层
xuyaqi 发表于 2016-4-27 17:19
要想别人帮你还是把工程贴出来,这种片段别人没法帮。

我就是想实现最简单的利用串口USART1发送字符串功能,其它的不外乎就是一些GPIO、USART、NVIC的配置了吧。
回复

使用道具 举报

307

主题

1427

帖子

12

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
7875
金钱
7875
注册时间
2015-10-15
在线时间
2874 小时
发表于 2016-4-28 12:11:49 | 显示全部楼层
你这个代码,总是感觉读起来很古怪。你这个里面多次使用中断判断, 中断服务函数呢?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-28 13:30:35 | 显示全部楼层
openedvadmin 发表于 2016-4-28 12:11
你这个代码,总是感觉读起来很古怪。你这个里面多次使用中断判断, 中断服务函数呢?

  不好意思,少些了一个“}”;
  USART_ITConfig(USART1, USART_IT_TXE,ENABLE);  这句话之后的函数就是中断处理函数。
回复

使用道具 举报

307

主题

1427

帖子

12

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
7875
金钱
7875
注册时间
2015-10-15
在线时间
2874 小时
发表于 2016-4-28 14:52:48 | 显示全部楼层
DAY_AND_DAY 发表于 2016-4-28 05:30
不好意思,少些了一个“}”;
  USART_ITConfig(USART1, USART_IT_TXE,ENABLE);  这句话之后的函数就 ...

那你最好编辑了重新贴一下代码。。。使用帖代码的按钮。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-28 15:12:35 | 显示全部楼层
openedvadmin 发表于 2016-4-28 14:52
那你最好编辑了重新贴一下代码。。。使用帖代码的按钮。

[mw_shl_code=c,true]int main(void)
{
          uint8_t *str;
            while(1)     
            {
                 str = "Welcome to STM321111";
                TData(str, 20);
          }
}
[/mw_shl_code]

[mw_shl_code=c,true]void TData(uint8_t *_usBuf, uint8_t _usLen)      //将数据存入缓冲区
{  
        uint8_t  Tx_Status, Txread, Txwrite, Txcounter;
        uint16_t  i;        
       
        Txread = p_uart.Tx_read;
        Txcounter = p_uart.Tx_counter;       
       
        //将待发送数据缓冲区写入UART发送数据缓冲区
        for(i=0; i<_usLen; i++)
        {
                if(++Txread >= USART1_TX_BUF_SIZE)
                {
                        Txread = 0;
                }       
               
                if(++Txcounter >= USART1_TX_BUF_SIZE)  //判断发送缓冲区数据个数
                {
                        Txcounter = 0;
                }
               
                p_uart.pTxBuf[p_uart.Tx_write] = _usBuf;     
                if(++p_uart.Tx_write >= USART1_TX_BUF_SIZE)     
                {
                        p_uart.Tx_write = 0;
                }
                p_uart.Tx_counter++;                               
        }
        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);   
}
[/mw_shl_code]

[mw_shl_code=c,true]if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)   //发送寄存器空中断处理函数
{
                USART_ClearITPendingBit(USART1, USART_IT_TXE);
                if(p_uart.Tx_read == p_uart.Tx_write)            //没有新数据
                {
                        USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                         
                        USART_ITConfig(USART1, USART_IT_TC, ENABLE);   
                }
                else
                {
                        USART_SendData(USART1, p_uart.pTxBuf[p_uart.Tx_read]);
                        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE == RESET));                       
                        if(++p_uart.Tx_read >= USART1_TX_BUF_SIZE)
                        {
                          p_uart.Tx_read = 0;
                        }
                        p_uart.Tx_counter--;
                }
}
       
else if(USART_GetITStatus(USART1, USART_IT_TC) !=RESET)   //发送完成中断处理函数
{
          USART_ClearITPendingBit(USART1, USART_IT_TC);    //清除发送完成标志位
          if(p_uart.Tx_read == p_uart.Tx_write)            //没有新数据
          {
            USART_ITConfig(USART1, USART_IT_TC, DISABLE);   //关闭发送完成中断
          }
          else
            {
                        USART_SendData(USART1, p_uart.pTxBuf[p_uart.Tx_read]);
                        while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);                       
                        if(++p_uart.Tx_read >= USART1_TX_BUF_SIZE)
                        {
                                p_uart.Tx_read = 0;
                        }
                        p_uart.Tx_counter--;
                }
}
[/mw_shl_code]

回复

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2016-4-27
在线时间
18 小时
 楼主| 发表于 2016-4-28 15:13:30 | 显示全部楼层
openedvadmin 发表于 2016-4-28 14:52
那你最好编辑了重新贴一下代码。。。使用帖代码的按钮。

嗯,这样看着顺眼多了!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 03:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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