OpenEdv-开源电子网

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

STM32F407使用RS485中断方式通信问题

[复制链接]

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
发表于 2015-5-20 14:37:15 | 显示全部楼层 |阅读模式
5金钱
    前段时间在用RS485进行modbus通信时(中断接收和发送),客户反应控制器会不定期死机,后来在现场跟踪程序后发现,程序会忽然进入RS485的中断处理例程,查看USART的寄存器,发现是在便能了接收中断,但没有接收中断标识位的情况下进入的(因为进入中断,但没有相应的中断标识位,所以程序会一直在中断例程中,最后表现为控制器死机),在这种情况下,如果打一个断点,然后再运行程序,又能正常运行~
    RS485中断例程代码如下:
static u32 RS485_ErrCounter = 0;//非正常进入RS485中断例程的次数
void RS485A_InterruptHook(void)
{
    if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET){//判断是否是接收中断
        GVL_isRS485Err = FALSE;
        /* Read one byte from the receive data register */
        RS485A_DelRead();
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);//清除接收中断标识位(其实不清除也不影响)
    }else    if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET)//判断是否是发送中断
    {
        if(RS485A_Send!=RS485A_WCnt){//判断是否发送完成所有字节
             USART_SendData(USART3, (u16)RS485A_WBuf[RS485A_Send++]);//发送数据
             if(RS485A_Send>=RS485A_W_LEN)//循环队列
                  RS485A_Send=0;
        }else{
            if(RS485A_Over){
                USART_ITConfig(USART3, USART_IT_TXE, DISABLE);//关闭发送中断
                RS485A_485_RX; //切换为接收
                RS485A_Over = 0;
            }else{
               delay(0xFFFF);//延时一下,以保证最后一个字节正常发出
                RS485A_Over = 1;
            }
        }
    }else{//非正常进入中断例程(触发了中断,但不是接收也不是发送,也不是错误~)
        RS485_ErrCounter++;
    }
}

之前这个RS485中断例程一直在用,也没听说有问题,但最近的控制器程序比较复杂,负荷较重,才出现这种情况,但找不出原因~麻烦大家帮忙看看
   
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2015-5-8
在线时间
0 小时
发表于 2015-5-20 16:35:33 | 显示全部楼层
建议你在else逻辑最后清除发送中断标志位再试试看;
回复

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2012-3-11
在线时间
49 小时
发表于 2015-5-20 20:10:58 | 显示全部楼层
modbus帧数据长度判断了嘛,好像3.5个字符长,建议你数据不要在中断里面处理,否则要是通信非常频繁的话,主程序就受影响了
这辈子只会两件事:这也不会,那也不会!
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
 楼主| 发表于 2015-5-22 10:03:44 | 显示全部楼层
回复【2楼】backroad:
---------------------------------
嗯,加了清除发送中断,还好像没有改观,后来把发送改为DMA方式,接收还是中断方式,还是会在使能接收中断,但没有接收中断标识位的情况下进入中断例程,感觉应该是在发送完成后,切换为接收时出了问题~
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
 楼主| 发表于 2015-5-22 10:04:44 | 显示全部楼层
回复【3楼】hkys_lxh:
---------------------------------
嗯嗯,中断里只做最简单的事,485中断里只是把接收到的数据放到了接收buf里,没干别的
回复

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
354
金钱
354
注册时间
2012-3-11
在线时间
49 小时
发表于 2015-5-22 22:31:40 | 显示全部楼层
问题解决了没,判断一下字长,若长度大于3就任何有一帧数据,否则没有,试试看
这辈子只会两件事:这也不会,那也不会!
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
 楼主| 发表于 2015-5-25 11:22:37 | 显示全部楼层
回复【6楼】hkys_lxh:
---------------------------------
还没解决,后来是改了DMA发,DMA收,暂时解决现场问题,但没根本解决问题~
回复

使用道具 举报

5

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2015-5-8
在线时间
0 小时
发表于 2015-5-26 10:37:12 | 显示全部楼层
回复【4楼】有一天:
---------------------------------
如果清除了标志位,还有这个情况,那么出现这个问题的原因很可能是出现了中断嵌套,我看了下代码,猜测问题出在USART_ITConfig函数。

可能调用这个函数调用后,会进入一个高优先级的中断,当前中断现场被保存,重新进入中断排序队列(注意,在与USART_ITConfig相关的中断执行完后,并不是返回执行当前中断执行程序),这会出现比较复杂的逻辑,后果也可能难以控制。

所以建议要避免中断嵌套情况的出现,将USART_ITConfig的调用放到主程序中进行。

你可以按这个思路修改一下看看。
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
 楼主| 发表于 2015-5-27 14:43:45 | 显示全部楼层
回复【8楼】backroad:
---------------------------------
好的,谢谢,已经改了485中断的抢占优先级为最高,下周去现场试试
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-5-13
在线时间
7 小时
 楼主| 发表于 2015-8-15 11:41:14 | 显示全部楼层
这个问题终于解决了,在无端进入485中断时,其实是有一个溢出中断标识位的,但因为在打开USART设备,观察寄存器时,读了DR,这个标识位被自动清除了,从而导致从表面上看,不是发也不是收,并且也没有别的中断标识位的情况下,进入的中断处理例程,解决方法:

在中断处理例程中增加对接收溢出中断的判断,
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET || USART_GetITStatus(USART1, USART_IT_ORE_RX)!=RESET)
{
             。。。
         }
谢谢各位,谢谢,结贴了。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 03:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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