OpenEdv-开源电子网

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

求教STM32串口收发太快导致死机问题。

[复制链接]

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
发表于 2016-1-2 20:25:11 | 显示全部楼层 |阅读模式
大家好,请问大家是否有跟我一样的情况。我必须在接收到上位机发送来的64个数据后,一次性返回64个数据。我是在中断函数里面,if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //        {
                Res =USART_ReceiveData(USART3);//接收数据
                .................此处有部分代码
               for(i=0;i<64;i++)
                {                                                                                                       

                        USART_SendData(USART3,USB_General);                                                                       
                }

         }

如果上位机数据发得很慢,数据收和发都完全正确,如果数据发得快的时候呢?就存在一个问题。STM32在收完数据准备一次性发送64个数据给上位机时,上位机又有数据发下来,这样STM32就死机了。那么问题来了,我该如何解决这问题又不影响数据收发呢?求解,谢谢!下面是新唐M0系列单片机,在接收里面发送64个数据,无论上位机发送数据多快都能正常响应的代码。
            for (u32Count=0; u32Count<u32WriteBytes; u32Count++)
            {
               u32delayno = 0;
                   while (UART0->FSR.TX_EMPTY !=1)                                                        /* Wait Tx empty and Time-out manner */
               {
                           u32delayno++;
                           if ( u32delayno >= 0x40000000 )                 
                              return E_DRVUART_ERR_TIMEOUT;                    
                                  
               }
                   UART0->DATA = pu8TxBuf[u32Count];                                                /* Send UART Data from buffer */
            }

希望对串口比较熟悉的朋友能一起讨论,帮帮我,谢谢了。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
发表于 2016-1-3 11:09:22 | 显示全部楼层
你这个应该是串口进入溢出错误了
回复 支持 0 反对 1

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2016-1-2 20:48:45 | 显示全部楼层
STM32的串口硬件是全双工的,你的代码部分应该有相应的修改,具体内容百度上大概翻了下有不少人讨论。我没有做过双工工作,没法给你更好的建议
回复 支持 反对

使用道具 举报

16

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1292
金钱
1292
注册时间
2014-12-20
在线时间
534 小时
发表于 2016-1-2 20:49:26 | 显示全部楼层
本帖最后由 BMN李 于 2016-1-2 20:53 编辑

中断里置标志,while里发送吧。还有DMA。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-2 21:38:28 | 显示全部楼层
本帖最后由 华南虎 于 2016-1-2 21:50 编辑
BMN李 发表于 2016-1-2 20:49
中断里置标志,while里发送吧。还有DMA。

你好。我用了                                                                for(i=0;i<64;i++)
                                                                {
                                                                     
                                                                        while(USART_GetITStatus(USART3,USART_IT_TXE)!=RESET);
                                                                        USART_SendData(USART3,USB_General);                                                                        
                                                                }
现在不会死机了,但是我是打算发64个数据上去的,结果上面只收到了3-5个数据。也就是说我发送的64个有60个数据左右没发上去了。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-2 21:51:53 | 显示全部楼层
华南虎 发表于 2016-1-2 21:38
你好。我用了                                                                for(i=0;i

嘎嘎。加了上面的语句也依然在数据发得比较快时会死机。另外要所有数据都能传上去,必须在发送函数后面适当延时一会才能全部发上去。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1839
金钱
1839
注册时间
2014-6-27
在线时间
982 小时
发表于 2016-1-2 22:14:55 | 显示全部楼层
如果你用全双工的方式,你应该用2个单片机的串口来调试,接收用中断,发送随意,理论收发不会影响,用串口助手不一定能这么调试。还有,你确定你接收64个字节数据时间间隔要要么快么?应用中很多场合可以折衷处理的。
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1684
金钱
1684
注册时间
2014-2-25
在线时间
230 小时
发表于 2016-1-3 08:36:24 | 显示全部楼层
有没有办法让上位机跟单片机通讯起来。就是上位机收到单片机数据的时候再发
回复 支持 反对

使用道具 举报

8

主题

124

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2015-8-1
在线时间
7 小时
发表于 2016-1-3 11:11:39 | 显示全部楼层
你不应该在接收中断里发数据。这样,你的中断服务函数还没结束时,又来了新的数据,产生不了中断,新的数据也无法被读取,后续数据再到来导致数据溢出。

最好和上位机沟通下,上位机收到一个指定字节的数据或指定个数的数据后,再发送下一批数据。
有软件开发经验,从0硬件基础学习STM32开发。
回复 支持 反对

使用道具 举报

16

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1292
金钱
1292
注册时间
2014-12-20
在线时间
534 小时
发表于 2016-1-3 12:42:40 | 显示全部楼层
本帖最后由 BMN李 于 2016-1-3 12:48 编辑

[mw_shl_code=c,true]//定义2倍长,防止下一次数据将上一次数据覆盖
#defint UART_CNT_MAX        (64 * 2)
uint8_t uart_buf[UART_CNT_MAX] = { 0, 0 };
uint8_t uart_cnt = 0;

//64个数据接收完成标志
uint8_t uart_finish_flag = 0;
uint8_t uart_buf_tmp[UART_CNT_MAX] = { 0, 0 };

void USART3_IRQHandler(void)
{
        if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
        {
                //接收数据
                uart_buf[uart_cnt ++] = USART_ReceiveData(USART3);
               
                if(uart_cnt == 64)
                {
                        //转存数据
                        memcpy(uart_buf_tmp, uart_buf, 64);
                        uart_finish_flag = 1;
                }
                else if(uart_cnt == 64 * 2)
                {
                        //转存数据
                        memcpy(uart_buf_tmp + 64, uart_buf + 64, 64);
                        uart_finish_flag = 2;
                }
               
                if(uart_cnt >= UART_CNT_MAX) uart_cnt = 0;
        }
}

void main(void)
{
        uint8_t i = 0;
        
        while(1)
        {
                if(uart_finish_flag == 1)
                {
                        for(i = 0;i < 64;i ++)
                        {                                                                                                        
                                USART_SendData(USART3, uart_buf_tmp);     
                        }
                        uart_finish_flag = 0;
                }
                else if(uart_finish_flag == 2)
                {
                        for(i = 0;i < 64;i ++)
                        {                                                                                                        
                                USART_SendData(USART3, uart_buf_tmp[64 + i]);     
                        }
                        uart_finish_flag = 0;
                }
        }
}[/mw_shl_code]
不知道效果如何,未测试。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-4 10:21:19 | 显示全部楼层
1201yuge 发表于 2016-1-3 08:36
有没有办法让上位机跟单片机通讯起来。就是上位机收到单片机数据的时候再发

不可以的,我们这边做的是智能调光,上位机是手动在操作,速度很快。如果等单片机回复后再发,延时会很厉害。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-4 10:23:46 | 显示全部楼层
TinyBoy 发表于 2016-1-2 22:14
如果你用全双工的方式,你应该用2个单片机的串口来调试,接收用中断,发送随意,理论收发不会影响,用串口 ...

嗯嗯。我是必须在收到上位机64个数据后,再把处理完的数据发回去。如果发送不放在这里面,有可能会存在上面发了几次64位的数据我才返回一串。我之前用新唐M0的单片机,貌似放在接收里面是可以的。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

16

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1292
金钱
1292
注册时间
2014-12-20
在线时间
534 小时
发表于 2016-1-4 11:30:46 | 显示全部楼层
华南虎 发表于 2016-1-4 10:23
嗯嗯。我是必须在收到上位机64个数据后,再把处理完的数据发回去。如果发送不放在这里面,有可能会存在上 ...

波特率大小、系统时钟大小、什么时候清中断等,这些都会有影响的。
回复 支持 反对

使用道具 举报

2

主题

239

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2015-6-5
在线时间
110 小时
发表于 2016-1-4 11:43:42 | 显示全部楼层
嚴格說起來 問題是出在上位機無規律性的發送數據 導致這問題阿

你應該要把上位機發送最小時間間隔給訂出來
總不可能上位機就一直發送不給下位機傳輸時間

這樣也不用傳了阿= = 資料處理也沒意義

另外你用哪一片?有些系列FIFO沒有很大
回复 支持 反对

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1839
金钱
1839
注册时间
2014-6-27
在线时间
982 小时
发表于 2016-1-4 11:45:42 | 显示全部楼层
华南虎 发表于 2016-1-4 10:23
嗯嗯。我是必须在收到上位机64个数据后,再把处理完的数据发回去。如果发送不放在这里面,有可能会存在上 ...

你既然接收到后要回复,说明发送端有等待你回复的机制,既然你发送端数据变化很快,你单片机接收到以后可以只回复一个应答数据就行了,告诉主机我接到正确数据了,这样可以提高通信速度。或者单片机不回复数据,主机有新数据固定发几次就不发了,反正有没有从机,主机都要发送数据的。
回复 支持 反对

使用道具 举报

29

主题

311

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1530
金钱
1530
注册时间
2012-9-4
在线时间
262 小时
发表于 2016-1-4 14:44:35 | 显示全部楼层
发送函数放中断外面,别在中断里面发,9楼正解啊。。。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-14 16:19:30 | 显示全部楼层
Rocks 发表于 2016-1-4 11:43
嚴格說起來 問題是出在上位機無規律性的發送數據 導致這問題阿

你應該要把上位機發送最小時間間隔給訂出 ...

嗯嗯。我现在有些数据直接不回给上面了。只有一些重要的才回复。不过我有一个问题直搞不明白。之前用新唐的M0单片机。上面发快下面也都没事。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-14 16:20:20 | 显示全部楼层
TinyBoy 发表于 2016-1-4 11:45
你既然接收到后要回复,说明发送端有等待你回复的机制,既然你发送端数据变化很快,你单片机接收到以后可 ...

嗯。我现在通讯协议修改了。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

47

主题

212

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
292
金钱
292
注册时间
2016-1-2
在线时间
80 小时
发表于 2016-1-14 22:38:47 | 显示全部楼层
华南虎 发表于 2016-1-2 21:38
你好。我用了                                                                for(i=0;i

找到解决方案没?
没有的话我等下分享这个解决办法
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-19 10:28:17 | 显示全部楼层
2938690046 发表于 2016-1-14 22:38
找到解决方案没?
没有的话我等下分享这个解决办法

嗯嗯。希望您可以分享下解决方法。我现在是牺牲好多有用数据的情况下勉强解决的。
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

47

主题

212

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
292
金钱
292
注册时间
2016-1-2
在线时间
80 小时
发表于 2016-1-21 04:23:02 | 显示全部楼层
华南虎 发表于 2016-1-19 10:28
嗯嗯。希望您可以分享下解决方法。我现在是牺牲好多有用数据的情况下勉强解决的。

抱歉  当初和你说完后就准备分享来的,可是当时网络不好,网页刷不出来。就忘记这个事了
这就分享
回复 支持 反对

使用道具 举报

47

主题

212

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
292
金钱
292
注册时间
2016-1-2
在线时间
80 小时
发表于 2016-1-21 04:25:49 | 显示全部楼层
又仔细看下,我只能分享下 如何做到最稳定发送
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-25 17:38:47 | 显示全部楼层
2938690046 发表于 2016-1-21 04:25
又仔细看下,我只能分享下 如何做到最稳定发送

嗯嗯。谢谢!
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

9

主题

111

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2013-5-28
在线时间
24 小时
 楼主| 发表于 2016-1-25 17:40:08 | 显示全部楼层
2938690046 发表于 2016-1-21 04:23
抱歉  当初和你说完后就准备分享来的,可是当时网络不好,网页刷不出来。就忘记这个事了
这就分享

流口水等待中ing
学习单片机编程贵在坚持,无论多难的问题都有不轻易放弃的原则,坚持着去解决它,相信你总会找到解决方法的。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 20:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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