stm32的串口5接485,115200波特率导致死机,9600却没事,求助!!

2019-12-27 18:59发布

本帖最后由 guxingganyue 于 2012-11-22 09:34 编辑

如题,我用stm32f103VET6的串口5和485通信,串口每次向485发送150字节,上位机每个1秒发一条命令,串口收到后就向485发送150字节

目前的现象是115200波特率的话,单片机会死机(lcd屏幕不刷新了),但是定时器中断还能触发(led灯在闪烁),26秒后内部狗复位,一切恢复正常

上位机继续发命令,不到3分钟的时间单片机死了

但是我用9600的波特率通信,1秒发一次命令,测试了1个晚上机器也没有死机

1、单片机和上位机间的连线不是很长,就2米左右,485芯片为:max3485,贵的那种
2、stm32外接8M晶振,系统跑72M

下面是485的连接图:请高手指教

注:把那个120欧姆的电阻去掉与否现象一样

111.png (38.89 KB, 下载次数: 0) 下载附件 2012-11-22 09:32 上传

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
37条回答
guxingganyue
1楼-- · 2019-12-28 17:42
 精彩回答 2  元偷偷看……
guxingganyue
2楼-- · 2019-12-28 18:47
本帖最后由 guxingganyue 于 2012-11-22 12:00 编辑

电脑发送:X2000S1234567Y,其中X Y是协议的头,尾。2000S是固定不变的,1234567是一个机器的7位ID号
串口接收完毕,且判断是本机的ID后把变量Transfer_485_Date_flag置位,while(1)中发现标志置位后就清除标志位,且向电脑发送150字节的数据

我的系统中有4个中断:定时器1中断(25ms中断一次),外部中断,串口4接收中断,串口5接收中断。

其中,外部中断和串口4接收中断几乎是不发生的,只有在特定的时间才发生,如00时00分,其他的情况下这个两个中断不会被触发
只有定时中断是一直开着的,串口5接收中断只有电脑发命令时才触发



下面是串口中断接收函数:
  1. void UART5_IRQHandler(void)
  2. {
  3.   u8 res=0;
  4.   static u8 RX_Count=0;
  5.   static u8 UART_RX_BUF[14]={0};   //接收缓冲,如收到:X2000S1234567Y
  6.   
  7.   if(UART5->SR & (1<<5))               //接收到数据
  8.   {
  9.     res=UART5->DR;
  10.     if(res=='X')       //数据头,2012-11-16
  11.     {
  12.       RX_Count=0;
  13.       UART_RX_BUF[RX_Count]=res;//收数据头,2012-11-18
  14.       RX_Count++;
  15.     }
  16.     else if(res =='Y')//数据尾,2012-11-18
  17.     {
  18.       UART_RX_BUF[RX_Count]=res;//收数据尾,2012-11-18
  19.       RX_Count++;
  20.       if((UART_RX_BUF[0]=='X')&&(RX_Count==14))//判数据头和数据长度
  21.       {
  22.         if((UART_RX_BUF[1]=='2')&&(UART_RX_BUF[2]=='0')&&(UART_RX_BUF[3]=='0')
  23.          &&(UART_RX_BUF[4]=='0')&&(UART_RX_BUF[5]=='S')
  24.          &&(UART_RX_BUF[6]==Menu_B2_ID_Code[0])&&(UART_RX_BUF[7]==Menu_B2_ID_Code[1])
  25.          &&(UART_RX_BUF[8]==Menu_B2_ID_Code[2])&&(UART_RX_BUF[9]==Menu_B2_ID_Code[3])
  26.          &&(UART_RX_BUF[10]==Menu_B2_ID_Code[4])&&(UART_RX_BUF[11]==Menu_B2_ID_Code[5])
  27.          &&(UART_RX_BUF[12]==Menu_B2_ID_Code[6]))
  28.         {
  29.           Transfer_485_Date_flag=1;
  30.         }
  31.       }
  32.     }
  33.     else if(RX_Count<14)
  34.     {
  35.       UART_RX_BUF[RX_Count]=res;
  36.       RX_Count++;
  37.     }
  38.   }
  39. }
复制代码
dadatou
3楼-- · 2019-12-28 19:58
1.硬件没有问题,STM32串口115200波特率长时间工作的飘过,另,从原理上看,485电路也没有问题.
2.可能串口接收中断里做的事情太多.9600时,有足够的时间处理,115200时,可能处理不过来.建议接收中断里面,只将接收到的数据放到缓冲区,不做其他处理,
3.屏不显示,但定时器还在工作,说明单片没有死机,可能程序卡在某处,或者一直在中断里面出不来.请检查程序的容错能力.
4.485在收发切换时,最好有一小段延时,因为当接收完成后需要发送数据时,如果立刻切换到发送状态并发送,可能导致第一个字节对方收不到.
5.问题描述不够详细,最好贴上代码,大家帮你分析.
zzfei90
4楼-- · 2019-12-28 23:02
把你程序贴出来看看吧,主循环和中断都弄出来看看,帮你找找问题
guxingganyue
5楼-- · 2019-12-29 04:57
dadatou 发表于 2012-11-22 10:13
1.硬件没有问题,STM32串口115200波特率长时间工作的飘过,另,从原理上看,485电路也没有问题.
2.可能串口接收 ...

嗯,485接收中断中的语句并不多,但定时器中断中的语句还是比较多的

下面是485串口发送函数:
  1. void UART5_SendString_A(char *Data)
  2. {
  3.   Enable_Tx;
  4.   delay_nms(1);//485延时,测试发现这个延时有没有效果一样,2012-11-18
  5.   char *pBuf = Data;   
  6.   while (*pBuf)
  7.   {
  8.     while (!(UART5->SR & 0x0040));
  9.     UART5->DR = ((*pBuf++) & (uint16_t)0x01FF);
  10.   }
  11.   delay_nms(1);//485延时,不延时的话最后一个字节是发不出去的,2012-11-18
  12.   Enable_Rx;
  13. }
复制代码
guxingganyue
6楼-- · 2019-12-29 09:57
 精彩回答 2  元偷偷看……

一周热门 更多>