优龙S3C44B0X 的IIC驱动问题

yourtse 2009-04-03 01:31:12
具体代码如下:
有时候读写的时候,特别是写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;
}
}
...全文
182 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yourtse 2009-04-13
  • 打赏
  • 举报
回复
首先谢谢各位的帮助。

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

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

这个问题还有待调查呢,努力ing
yourtse 2009-04-08
  • 打赏
  • 举报
回复
好的,谢谢。我再试试看吧。谢谢你的帮助。
zyzhang365 2009-04-08
  • 打赏
  • 举报
回复
建议你都加外部上拉,这可能是你问题的症结。
yourtse 2009-04-08
  • 打赏
  • 举报
回复
我说的上拉指的是端口配置时的内部上拉,即把SCL和SDA都允许内部上拉。

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

你解决问题了吗?
zyzhang365 2009-04-07
  • 打赏
  • 举报
回复
SCL/SDA上拉了吗
yourtse 2009-04-07
  • 打赏
  • 举报
回复
对于这个问题,有新的进展了,

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

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

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

今天继续努力哦~~~~
zyzhang365 2009-04-07
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 zyzhang365 的回复:]
I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的期间是不支持快速模式的。 可以先使用低速的模式试试。
[/Quote]
I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的器件是不支持快速模式的。 可以先使用低速的模式试试。
zyzhang365 2009-04-07
  • 打赏
  • 举报
回复
I2C是必须要加上拉电阻的,并且阻值要合适,最好不要使用快速模式(400K),有的期间是不支持快速模式的。 可以先使用低速的模式试试。
yourtse 2009-04-07
  • 打赏
  • 举报
回复
原先是没有上拉的,

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

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

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

你有什么进展没有?
llKK0616 2009-04-06
  • 打赏
  • 举报
回复
顶起来!
还有一个问题就是连接开发板与电脑的串口线不拔的话,电脑关闭后老是重启?
llKK0616 2009-04-03
  • 打赏
  • 举报
回复
应该是IIC中断没有执行,但我不知道为什么不执行。
llKK0616 2009-04-03
  • 打赏
  • 举报
回复
LZ我遇到跟你一样的问题,但我比你更糟,我正常运行的频率很低 ,这个问题困扰我几天了。
忘好心人帮忙解决。
zyzhang365 2009-04-03
  • 打赏
  • 举报
回复
如果是时好时坏,那一般是由异步事件(比如中断和别的进程等)造成的,这种问题需要好好分析。
也有可能是时序的问题。
个人认为这种问题不是很好解决,这也是嵌入式软件和普通软件的差别。
yourtse 2009-04-03
  • 打赏
  • 举报
回复
谢谢楼上的回家,下次试试看吧。

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

运行不稳定呢。

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

不解呢?还望各位帮忙呢。…………
zyzhang365 2009-04-03
  • 打赏
  • 举报
回复
没仔细看你的代码,前面看到一个帖子,S3C好像从设备的地址需要右移一位。

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

试试看吧。
yourtse 2009-04-03
  • 打赏
  • 举报
回复
谢谢楼上两位的回答,
以下为宏定义和 变量定义;

#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;

zyzhang365 2009-04-03
  • 打赏
  • 举报
回复
把它定义成 volatile int _iicDataCount试试。
zyzhang365 2009-04-03
  • 打赏
  • 举报
回复
_iicDataCount是怎么定义的?

21,604

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧