求助:单片机通讯时怎么会死机?

[复制链接]
4436|16
 楼主| liuyanlbg 发表于 2009-6-29 17:11 | 显示全部楼层 |阅读模式
我用的是PIC的单片机,用232进行通信;当外接串口的电压稳定时,通讯正常;当串口电压波动(如电脑串口断电)时,单片机就容易死机,请问这种情况该怎么去解决?各位大虾,高抬贵手,多给意见,谢谢!
用的芯片是MAX202E,电容是0.1UF的
mohanwei 发表于 2009-6-29 17:22 | 显示全部楼层

程序问题 多考虑一下通信出错的情况 针对性处理

工控秀才 发表于 2009-6-29 17:26 | 显示全部楼层

响应哪些指令

并做什么处理,可能误判指令了,然后等待什么数据.
cool_coder 发表于 2009-6-29 22:01 | 显示全部楼层

如果只发生在电压波动时,

也可能是硬件发生死锁了
xysl 发表于 2009-6-29 22:51 | 显示全部楼层

说实话,这应该是干扰

加上看门狗吧,只有这样。其它的基本上没法,除非电路重新布,减小干扰,再加上隔离应该好些。
lelee007 发表于 2009-6-30 03:36 | 显示全部楼层

硬件的录棒性不好

给串口加级隔离吧,哈哈
 楼主| liuyanlbg 发表于 2009-6-30 08:40 | 显示全部楼层

谢谢各位仁兄的建议

本人认为程序问题的可能性很小,因为只要不触动电脑电源,接发数据都很正常。一旦电源有变化,如关掉显示器电源,就会马上死机,而且这时串口上有很大的静电;把串口线改为屏蔽线,效果要好很多,但偶尔还是会有死机,应该属于干扰。
上面有仁兄提到采用隔离,不知道怎么隔离法,而且串口地,MAX202芯片的地和单片机的地是连在一起的,如果地隔离,怎么通信?能否说详细一点,谢谢!
born 发表于 2009-6-30 09:41 | 显示全部楼层

增加TVS

在 串口两根线和 地线之间 并两个 6.8V左右的TVS 二极管,


不行的话, 把通讯改成 电流环式,实现电源隔离,(此时波特率只能降低,不能过9600) 应该好使.
bjc125 发表于 2009-6-30 09:57 | 显示全部楼层

关注中

没想到好的办法 希望楼主解决后 分享下经验 呵呵
xysl 发表于 2009-7-7 22:57 | 显示全部楼层

串口隔离办法

单片面的TTL里加光藕,再接上232电平转换器上,如果还不知道,来信号,我给你发个原理图
XYSL23@hotmail.com
XYSL23@163.com
ocon 发表于 2009-7-8 14:33 | 显示全部楼层

PIC没这么脆弱,绝大多数情况下是软件的BUG所致,

PIC的串口在收到非法数据时内部的对应出错标志会被置1,此时暂停接收新数据,需要用软件进行查询和清零,DATASHEET里有详细说明。
ocon 发表于 2009-7-8 14:39 | 显示全部楼层

正确的串口接收中断处理函数

rx_handler(void)
{
    int b;
    if (OERR || FERR){
        SPEN=0;
        CREN = 0;
        b = RCREG;
        CREN = 1;
        SPEN=1;
    }
    else if (RCIF){
        get_data();
    }
}
peiyuan1 发表于 2009-7-9 09:14 | 显示全部楼层

把你的串口程序注释掉,再试验

把你的串口程序注释掉,再试验,如果还死机就代表硬件有问题,如果不死机就代表你的串口程序有问题。
sanmaoljh 发表于 2009-7-9 15:16 | 显示全部楼层

路过,看看大家的评论

peiyuan1 发表于 2009-7-9 16:25 | 显示全部楼层

98%的可能是软件有问题

完善的做法是:当出现错误通讯数据的时候,程序要能退出该通讯处理,并照常处理其他数据,当新的通讯数据再次到来的时候要能正确响应。

LZ目前情况应该是程序不能处理掉错误的通讯数据导致等待而不能动弹.
inter_zhou 发表于 2009-7-12 19:09 | 显示全部楼层

就算是硬件问题软件应该也可以解

通讯的协议里面
1,是否有严谨的TIME OUT 机制?
2,是否有严谨的校验机制?
3,发送数据异常时怎么处理?
4,接收数据异常怎么处理?
处理好这些应该就没有问题了!
wanghucumt 发表于 2010-8-12 14:40 | 显示全部楼层
本帖最后由 wanghucumt 于 2010-8-12 14:42 编辑

我也遇到过这个问题,16F877死在串口接收那里,后来接受中断部分改成这样就好了
if(RCIE && RCIF)    // 串口中断
{
     if (OERR || FERR)
    {
         SPEN=0;
         CREN = 0;
         rxdbuf = RCREG;
         rxdbuf = RCREG;
         CREN = 1;
         SPEN=1;
     }
     else
    {
         rxdbuf = RCREG;  //读取串口接收数据
         usart_flag = 1; //串口中断标志
     }
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

59

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部