在问I2C读24C02

china315   2008-7-13 12:57 楼主
在万利板子上
用I2C例程5(经万利修改),单步不可以运行,到 
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
这一步就等待,
连续运行时,有时候好,有时候坏,坏的时候也是到这个地方等待
 翻遍了以前所以的帖子,n天前也碰到过,没解决。现在从新碰到这个问题
以前帖子里也有人碰到类似的问题,但是都没有好的解决方法

回复评论 (19)

补充

修改 系统时钟,72M改为64M,连续运行时就正常了,但单步运行还是不行。
低速APB为RCC_HCLK_Div2;
点赞  2008-7-13 13:05

?没人回答

                                 没有人遇到过吗
点赞  2008-7-13 15:55

我运到的情况和你不一样

我的是读操作调用后,在发:
I2C_GenerateSTART(I2C1, ENABLE);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
就出不来了
点赞  2008-7-13 19:39

可惜没时间陪大家玩STM32的I2C~~~说实话俺是TWI"砖家"


相关链接:http://www.google.cn/search?complete=1&hl=zh-CN&newwindow=1&q=twi+i2c+smbus+hotpower&meta=&aq=f
点赞  2008-7-13 19:43

HotPower大叔

我的情况是:(程序用得查询方式,不是你推荐的状态机中断)

写----读----:运行正常

写----读---写/读:死机。

我自己觉得是没有能正确的结束I2C时序。

在我另外一个帖子中有说明,你看看。

谢谢

相关链接:https://bbs.eeworld.com.cn/club/bbs/bbsView.asp?boardid=49
点赞  2008-7-13 20:05

回id001

                                 你说的情况我遇到过,那是n天,我也发过贴问过,不过没说详细,没人回答,当时刚开始,不熟悉编程环境及固件库,我就放下那个问题,调试了其他外设,现在回过头来弄i2c,怎么都不正常,而且程序很神经病。每次出现的错误都不太一样。用示波器看,发现SDA,SCL都是低电平。
点赞  2008-7-13 20:17

ESTM32:


我自己觉得是没有能正确的结束I2C时序。

第一次读的数据结果正确,可能是在读取最后一个字节时候,STM32没有能发送正确的NAK信号,使24C02那边没有释放SDA、SCL。

我调整
        I2C_AcknowledgeConfig(I2C1, DISABLE);
的位置,搞来搞去,结果一样。


你觉得呢?
点赞  2008-7-13 20:25

郁闷中******

我用的是例程里的程序,没有做任何修改,也看来手册里的时序,和程序的顺序也能对得上,就是不能单步运行,而且系统时钟需要降低才行。
我感觉也是24C02没有释放总线,用示波器看都是低电平。但是问题怎么解决呢!例程都通不过,不要说自己编程了,郁闷中***********
点赞  2008-7-13 20:33

我两个不要再这瞎折腾了~~


把楼盖高了,太多了大侠都难的看~~~~~~~~

(*^__^*) 嘻嘻……
点赞  2008-7-13 20:37

自己思考

                                 从此就此问题不再发问!
点赞  2008-7-13 20:44

肯定是I2C时序不对~~~

先复习一下I2C总线忽悠记~~~
相关链接:http://www.hotpower.org/2008/07/12/%e7%83%ad%e7%83%88%e5%ba%86%e7%a5%9dhotpower%e7%9a%84%e6%
点赞  2008-7-13 22:18

我的i2c也遇到问题

我的i2c也很长时间没调出来。我的读没什么问题,但写遇到的问题很奇怪。只能写一段时间,之后就不能写了。我用示波器抓过波形,结合程序看了,发现问题是出在 程序产生一个开始,但实际上在pin脚上没能生成一个开始。我查看了此时的寄存器,显示的是busy位为1,其它都为0。不知有没有人遇到过这种情况。

另外,例程中的发stop条件的位置好象不对,跟datasheet上说的有出入。
点赞  2008-7-13 22:52

我的I2C调试也经过几番周折,说几点教训

1、地址千万别错
2、写入要Delay
3、低速调通了再提高速度
4、实在还不通,PM给我索要sample
点赞  2008-7-14 23:15

楼上给个sample吧

                                 基于万利EK-STM32F的,读写24C02,用的库文件版本是2.0.1的么?还是老库?
点赞  2008-7-15 10:36

太过依赖 STM2的库函数了。

太过依赖 STM2的库函数了,
为何不自己写?

发 偶在 ATMEL  AT91SAM7S256 ARM 上的TWI
和 NXP  LPC2138  ARM上的I2C 程序部分。

//*----------------------------------------------------------------------------
//* fn    AT91F_TWI_Write
//* rief Send n bytes to a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_Write(const AT91PS_TWI pTwi ,int address, char *data2send, int size)
{
    unsigned int status;
    // Set the TWI Master Mode Register  SLAVE "器件地址" |"2字节内部器件地址" & "主机写"
    pTwi->TWI_MMR = ( AT91C_EEPROM_I2C_ADDRESS | AT91C_TWI_IADRSZ_2_BYTE ) & ~AT91C_TWI_MREAD;        
    // Set TWI Internal Address Register TWI内部地址寄存器
    pTwi->TWI_IADR = address;
    status = pTwi->TWI_SR;        //TWI状态寄存器
    pTwi->TWI_THR = *(data2send++);    
    pTwi->TWI_CR = AT91C_TWI_START;        
    while (size-- >1){
        // Wait THR Holding register to be empty
        while (!(pTwi->TWI_SR & AT91C_TWI_TXRDY));    
        // Send first byte
        pTwi->TWI_THR = *(data2send++);        
    }
    
    pTwi->TWI_CR = AT91C_TWI_STOP;        
    status = pTwi->TWI_SR;
    // Wait transfer is finished
    while (!(pTwi->TWI_SR & AT91C_TWI_TXCOMP));        
    
    return AT91C_EEPROM_WRITE_OK;
    
}//END
点赞  2008-7-15 11:36

NXP LPC2138 ARM上的I2C 程序部分。

//==========================================================================
//
//==========================================================================
void SendAByte(uint8 data)
{
    LPC_BASE_I2C0->I2C_DAT =data; 
    LPC_BASE_I2C0->I2C_CONSET = I2C_AA;  //  I2C_CONSET( 读/置位)
    LPC_BASE_I2C0->I2C_CONCLR = I2C_STAC|I2C_SIC; 

    while (!(LPC_BASE_I2C0->I2C_CONSET & I2C_SI));    
}
点赞  2008-7-15 11:37

做个记号

没法子,我已经改成GPIO模拟I2C了,也是死在这一句
while(!I2C_CheckEvent(I2C1, I2C_EVENT_*_*_* ))
点赞  2008-8-16 21:10

放心用吧

#include "stm32f10x_lib.h"

void I2C_AcknowledgePolling(u8 sla);
void I2C_SequentialRead_AT24C01_02(u8 sla,u8 suba,u8 *pHead,u8 len);
void I2C_PageWrite_AT24C01_02(u8 sla,u8 suba,u8 *pHead,u8 len);

void I2C_AcknowledgePolling(u8 sla){
    I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
    do{
        I2C1->CR1 |= CR1_START_Set;
        I2C1->DR   = sla;
    }while(!(I2C_ReadRegister(I2C1,I2C_Register_SR1)&0x0002));

    I2C_ClearFlag(I2C1,I2C_FLAG_AF);
}
void I2C_SequentialRead_AT24C01_02(u8 sla,u8 suba,u8 *pHead,u8 len){
    u8 i;

    I2C_AcknowledgePolling(sla);
    
    I2C1->CR1 |= CR1_START_Set;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
   
    I2C1->DR = sla;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

    I2C1->DR = suba;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
               
    I2C1->CR1 |= CR1_START_Set;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  

    I2C1->DR = sla+1;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));    
    I2C1->CR1 |= CR1_ACK_Set;

    if(len>1){
        for(i=0;i<len-1;i++){
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED));
            *pHead ++= I2C1->DR;
            
            I2C1->CR1 |= CR1_ACK_Set;
        }
    }
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED));
    *pHead = I2C1->DR;
    I2C1->CR1 &= CR1_ACK_Reset;
    
    I2C1->CR1 |= CR1_STOP_Set;
}
void I2C_PageWrite_AT24C01_02(u8 sla,u8 suba,u8 *pHead,u8 len){
    u8 wLen,addr;
    
    wLen=len;
    addr=suba;
    ScrollPage:I2C_AcknowledgePolling(sla);
    
               I2C1->CR1 |= CR1_START_Set;
               while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));  
  
               I2C1->DR = sla;
               while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

               I2C1->DR = addr;
               while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
                              
               I2C1->DR = *pHead++;
               while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
               
               addr++;
               wLen--;
        
    while(wLen){
        if((addr%8)!=0){
            I2C1->DR = *pHead++;
            while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
            
            addr++;
            wLen--;
        }
        else{
            I2C1->CR1 |= CR1_STOP_Set;
            goto ScrollPage;
        }
    }
    I2C1->CR1 |= CR1_STOP_Set;
}
点赞  2008-8-18 10:10

在问I2C读24C02

                                 降低IIC的速度,在每一步执行完后加足够的延时程序,先调通,我只是在调试的时候加啦足够的延时,是在读写24完后,连续读写是可以的,单步没试。一定可以的,试试看
点赞  2008-8-19 14:00
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复