3602|18

60

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

优龙S3C44B0X 的IIC驱动问题 [复制链接]

具体代码如下:
有时候读写的时候,特别是写EEPROM的时候出现死机,即 while(_iicDataCount!=-1);在这一句处循环,无法退出。
但是又不确定,有时候又是好的,请问不知道哪里错了,望高手不吝赐教!!

谢谢!
========================
========================
void Iic_initial(void)
{
        pISR_IIC                 = (UINT32) IicInt;                /* EEPROM 中断入口         */

        // enable IRQ IIC
        rINTMSK                 &= (~BIT_IIC) ;
       
        // initialize IIC module
        rPCONF                 |= 0xa;                //PF0:IICSCL, PF1:IICSDA
    rPUPF                 |= 0x3;                //pull-up disable
   
    //Enable ACK generation, IICCLK=MCLK/16, Enable interrupt,IIC-Bus transmit clock prescaler (15+1)
    //66000000hz/16/(15+1) = 257Khz        (257812.5)
    rIICCON                = (1<<7) | (0<<6)| (1<<5) | (0xf);
   
    rIICADD                = 0x10;           // S3C44B0X slave address

    rIICSTAT        = 0x10;                // 1=Enable Rx/Tx
}

void Wr24C040(UINT32 slvAddr,UINT32 addr,UINT8 data)
{
    _iicMode=WRITE_DATA;
    _iicPt=0;
    _iicData[0]=(UINT8)addr;
    _iicData[1]=data;
    _iicDataCount=2;
   
    rIICDS=slvAddr;//0xa0
    rIICSTAT=0xf0; //MasTx,Start
    //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1);

    _iicMode=POLLACK;

    while(1)
    {
            rIICDS=slvAddr;
            _iicStatus=0x100;
            rIICSTAT=0xf0; //MasTx,Start
            rIICCON=0xaf;  //resumes IIC operation.
           
            while(_iicStatus == 0x100)
            {
                    ;
            }
           
            if(!(_iicStatus & 0x1))
                break; // when ACK is received
    }
    rIICSTAT=0xd0;  //stop MasTx condition
    rIICCON=0xaf;   //resumes IIC operation.
    Delay(1);            //wait until stop condtion is in effect.

    //write is completed.
}
       

SINT32 Rd24C040(UINT32 slvAddr,UINT32 addr,UINT8 *data)
{
    UINT32 timeout;
   
    _iicMode=SETRDADDR;
   
    _iicPt=0;
    _iicData[0]=(UINT8)addr;
    _iicDataCount=1;

    rIICDS=slvAddr;
    rIICSTAT=0xf0; //MasTx,Start  
    //Clearing the pending bit isn't needed because the pending bit has been cleared.
   
    timeout = 0xffff ;
    while(_iicDataCount!=-1)
    {
            if (timeout--  == 0)
            {
                    return -1 ;
            }
    }

    _iicMode=READ_DATA;

    _iicPt=0;
    _iicDataCount=1;
   
    rIICDS=slvAddr;
    rIICSTAT=0xb0; //MasRx,Start
    rIICCON=0xaf;  //resumes IIC operation.  
     
    timeout = 0xffff ;
    while(_iicDataCount!=-1)
    {
            if (timeout--  == 0)
            {
                    return -1 ;
            }
    }

    *data=_iicData[1];
   
    return 0 ;
}



void __irq IicInt(void)
{
    UINT32 iicSt,i;
   
    rI_ISPC=BIT_IIC;

    iicSt=rIICSTAT;
   
    if(iicSt&0x8){} // when bus arbitration is failed.
    if(iicSt&0x4){} // when a slave address is matched with IICADD
    if(iicSt&0x2){} // when a slave address is 0000000b
    if(iicSt&0x1){} // when ACK isn't received

    switch(_iicMode)
    {
        case POLLACK:
            _iicStatus=iicSt;
            break;

        case READ_DATA:
            if((_iicDataCount--)==0)
            {
                    _iicData[_iicPt++]=rIICDS;
                
                    rIICSTAT=0x90;  //stop MasRx condition                 --> IIC-bus STOP signal generation
                    rIICCON=0xaf;   //resumes IIC operation.        --> Clear pending condition
                    Delay(1);                //wait until stop condtion is in effect.
                                                    //too long time...
                    //The pending bit will not be set after issuing stop condition.
                    break;   
            }             
            _iicData[_iicPt++]=rIICDS;
                                //The last data has to be read with no ack.
            if((_iicDataCount)==0)
            {
                        rIICCON=0x2f;        //resumes IIC operation with NOACK.  
                }
            else
            {
                        rIICCON=0xaf;        //resumes IIC operation with ACK
                }
            break;

        case WRITE_DATA:
            if((_iicDataCount--)==0)
            {
                    rIICSTAT=0xd0;        //stop MasTx condition                 --> IIC-bus STOP signal generation
                    rIICCON=0xaf;        //resumes IIC operation.        --> Clear pending condition
                    Delay(1);                //wait until stop condtion is in effect.
                    //The pending bit will not be set after issuing stop condition.
                    break;   
            }
            rIICDS=_iicData[_iicPt++];  //_iicData[0] has dummy.
            
            for(i=0;i<10;i++);            //for setup time until rising edge of IICSCL
            
            rIICCON=0xaf;            //resumes IIC operation.
            break;

        case SETRDADDR:
            //printf("[S%d]",_iicDataCount);
            if((_iicDataCount--)==0)
            {
                        break;  //IIC operation is stopped because of IICCON[4]   
            }
            
            rIICDS=_iicData[_iicPt++];
            
            for(i=0;i<10;i++);  //for setup time until rising edge of IICSCL
            
            rIICCON=0xaf;            //resumes IIC operation.
            break;

        default:
            break;          
    }
}

最新回复

首先谢谢各位的帮助。 我的问题大致解决了,好像是 EEPROM芯片的电压设置的不对,用了5V,因为CPU端是3.3V,后来也改成3.3v, 就没有出现死机了。 不过后来又发现一个问题,就是把CPU和EEPROM的连接线延长至1米多,就又容易死机了,很快。 这个问题还有待调查呢,努力ing   详情 回复 发表于 2009-4-13 08:22
点赞 关注

回复
举报

68

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
_iicDataCount是怎么定义的?
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
把它定义成  volatile int _iicDataCount试试。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢楼上两位的回答,
以下为宏定义和 变量定义;

#define WRITE_DATA            (1)
#define POLLACK             (2)
#define READ_DATA            (3)
#define SETRDADDR           (4)

#define IICBUFSIZE 0x20

UINT8 _iicData[IICBUFSIZE];
volatile SINT32 _iicDataCount;
volatile SINT32 _iicStatus;
volatile SINT32 _iicMode;
SINT32 _iicPt;

 
 
 

回复

91

帖子

0

TA的资源

一粒金砂(初级)

5
 
没仔细看你的代码,前面看到一个帖子,S3C好像从设备的地址需要右移一位。

rIICDS=slvAddr;//应该使用0xa0 >> 1;

试试看吧。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

6
 
谢谢楼上的回家,下次试试看吧。

感觉奇怪的是,很多时候程序跑得很正常,就是偶尔出现错误;有时候出现的概率又比较大。所以肯定代码有问题,

运行不稳定呢。

但是基本的控制都是符合EEPROM的是需要求的呢。

不解呢?还望各位帮忙呢。…………
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

7
 
如果是时好时坏,那一般是由异步事件(比如中断和别的进程等)造成的,这种问题需要好好分析。
也有可能是时序的问题。
个人认为这种问题不是很好解决,这也是嵌入式软件和普通软件的差别。
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

8
 
LZ我遇到跟你一样的问题,但我比你更糟,我正常运行的频率很低 ,这个问题困扰我几天了。
忘好心人帮忙解决。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

9
 
应该是IIC中断没有执行,但我不知道为什么不执行。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

10
 
顶起来!
还有一个问题就是连接开发板与电脑的串口线不拔的话,电脑关闭后老是重启?
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

11
 
对于这个问题,有新的进展了,

IIKK0616,如果你看到帖子,可以尝试下。

我用示波器看了SCL和SDA的波形,
发现SCL并没有传说中的方波,而是一个三角波,很显然tw-hold的宽度不符合spec的要求。

因为我的eeprom和cpu距离挺远的,大概有1米多把,后来把eeprom直接连接到主板上,同样的程序,
发现波形有明显改善,而且出现死机的概率也大为减小,所有这得在硬件上做做文章。

今天继续努力哦~~~~
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

12
 
SCL/SDA上拉了吗
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

13
 
原先是没有上拉的,

今天上拉了,问题依旧,不过把SCL的频率降下来,情况或许会好些。

发现 SCL的上升沿需要 2us的时间,是不是太长了。

加入SCL的频率是400khz,那么周期也不过是2.5us ;

你有什么进展没有?
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

14
 
I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的期间是不支持快速模式的。 可以先使用低速的模式试试。
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

15
 
引用 13 楼 zyzhang365 的回复:
I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的期间是不支持快速模式的。 可以先使用低速的模式试试。

I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的器件是不支持快速模式的。 可以先使用低速的模式试试。
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(初级)

16
 
我说的上拉指的是端口配置时的内部上拉,即把SCL和SDA都允许内部上拉。

外部SDA是有上拉的,阻值为10K,SCL是不要上拉的吧?

你解决问题了吗?
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

17
 
建议你都加外部上拉,这可能是你问题的症结。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

18
 
好的,谢谢。我再试试看吧。谢谢你的帮助。
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

19
 
首先谢谢各位的帮助。

我的问题大致解决了,好像是 EEPROM芯片的电压设置的不对,用了5V,因为CPU端是3.3V,后来也改成3.3v,
就没有出现死机了。

不过后来又发现一个问题,就是把CPU和EEPROM的连接线延长至1米多,就又容易死机了,很快。

这个问题还有待调查呢,努力ing
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表