打印

2440 IIC SCL偶尔死锁为L求助

[复制链接]
2864|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
scyszj|  楼主 | 2007-10-14 13:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在调ARM2440时,IIC发送正常,但当作为从机接收数据(中断)时,大概1/200的机会会出现时钟线死锁为低,不能恢复.正常情况是会产生中断,但这里中断标志产了(IICCON第4位),但SRCPND与INTPND相应位为0,不能正常进入中断程序,导致不能清0IICCON第4位,从而使SCL常为低,总线不能工作正常.死锁时:IICCON=241,IICSTAT=48,SRCPND与INTPND相应位为0(27位).请问各位大侠该如何处理?

相关帖子

沙发
hotpower| | 2007-10-14 13:54 | 只看该作者

主机时钟可能太快

使用特权

评论回复
板凳
scyszj|  楼主 | 2007-10-14 15:05 | 只看该作者

从10K-50K都设过,没有用

主机时钟从10K-50K(SCL)都设过,还是有这样的问题.

使用特权

评论回复
地板
scyszj|  楼主 | 2007-10-14 15:09 | 只看该作者

正常接收时,波形很漂亮

正常接收时波形很漂亮,应不会有干扰,同一个主机向另一块挂在相同IIC BUS上的(ATMEGA48)发送就能正常接收.

使用特权

评论回复
5
mohanwei| | 2007-10-14 15:34 | 只看该作者

主程序里开始读写的时候加个定时器,超时就重新初始化

I2C模块。

使用特权

评论回复
6
scyszj|  楼主 | 2007-10-14 15:36 | 只看该作者

现在是这样想的

不过这个问题很奇怪,在8位机中都不会出现的.
void __irq iic_isr(void)
{   
    U8 iic_status;
    U8 tmp=0;
    
    rINTMSK |= BIT_IIC;
    
    tmp=rIICDS;                        //必须读
    iic_status=rIICSTAT;
    
    rSRCPND |= BIT_IIC;              //Clear pending bit
    rINTPND |= BIT_IIC;
    rIICCON |=(1<<5);
    iic_clr_pending();

    if(iic_mode==4){
        if((iic_status & 0x8)!=0){goto isr_erro;}            //总线竞争失败
        if((iic_status & 0x4)!=0){
            if(iic_rx_data_pro==iic_rx_data_proed){        //如果上次接收到的数据已处理,应答并准备接收数据
                iic_rx_data_pro=iic_rx_go;                    //地址匹配成功
                iic_rx_data_count=0;
                rIICCON |=(1<<7);
            }
            goto isr_end;
        }
        
        if(iic_rx_data_pro==iic_rx_go){
            if(iic_rx_data_count<iic_rx_data_pkg_size){    //收到完整字节后中断
                iic_rx_data[iic_rx_data_count]=tmp;
                if(iic_rx_data_count<(iic_rx_data_pkg_size-1)){
                    rIICCON |=(1<<7);            //下一字节结收完成后回应ACK
                }                
                else{
                    if(check_crc16_data(iic_rx_data,iic_rx_data_pkg_size)!=0){//不应答第8个,主机就知道发送数据错误,要重发数据
                        rIICCON &=~(1<<7);        //校验不成功,第7字节回应NACK
                        goto isr_erro;
                    }
                    else{
                        rIICCON |=(1<<7);        //第7字节结收完成后回应ACK
                        iic_rx_data_pro=iic_rx_ok;
                    }
                }
                iic_rx_data_count++;
            }
            else{
                rIICCON &=~(1<<7);                //第8字节结收完成后回应NACK
                iic_rx_data_pro=iic_rx_ok;        //接收到第8字节,置完成接收标志,数据未处理完前不再应答
            }
        }
        else{
            rIICCON &=~(1<<7);
        }
    }

isr_end:
    rINTMSK &= ~BIT_IIC;
    return;
    
isr_erro:
    iic_erro=0x1;
    //rINTMSK &= ~BIT_IIC;
}
中断中的代码

使用特权

评论回复
7
hotpower| | 2007-10-14 23:54 | 只看该作者

看来是从机isr()的问题了

俺觉得状态判断太少了...估计那里没考虑周到使从机不能再次进入中断.
这样导致了SCL死锁.

使用特权

评论回复
8
scyszj|  楼主 | 2007-10-15 09:06 | 只看该作者

接收的全部代码在此了

IICCON=241,IICSTAT=48,SRCPND与INTPND相应位为0(27位).请问各位大侠该如何处理?
这是关键,IIC表明收到数据,而中断没有植标志,故不能产生中断

使用特权

评论回复
9
scyszj|  楼主 | 2007-10-15 23:10 | 只看该作者

解决了

是由于TIMER4会出现200Hz中断引起的,但为什么会引起就不清楚,因为TIMER4 ISR中并没有长时间的操作和清IIC的中断标致命令.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

20

帖子

0

粉丝