打印
[Cortex-M0技术交流]

m0516读写24c02错误

[复制链接]
2833|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangch_sh|  楼主 | 2013-6-17 16:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用m0516读写24c02,写进去0x55,读出来是0.不知何故?
#include "SmartM_M0.h"
#define DEBUGMSG printf
#define EEPROM_SLA              0xA0
#define EEPROM_WR               0x00
#define EEPROM_RD               0x01
#define I2C_CLOCK               13

#define PAGE_SIZE               8
/*****************************************
*函数名称:Timed_Write_Cycle
*输    入:无
*输    出:无
*功    能:同步的写周期
******************************************/
void Timed_Write_Cycle(void)                  
{
    while (I2STATUS != 0x18)
    {
        //启动
        I2CON |= STA;                          
        I2CON |= SI;
        while ((I2CON & SI) != SI);
        I2CON &= ((~STA) & (~SI));
  //设备地址
        I2DAT = EEPROM_SLA | EEPROM_WR;
        I2CON |= SI;
        while ((I2CON & SI) != SI);
    }
    if (I2STATUS != 0x18)                       //检查应答
    {
     DEBUGMSG("Not ACK returned!");
}
    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);
}
/*****************************************
*函数名称:I2CInit
*输    入:无
*输    出:无
*功    能:I2C初始化
******************************************/
VOID I2CInit(VOID)
{
    P3_PMD &= ~(Px4_PMD | Px5_PMD);
P3_PMD |= (Px4_OD | Px5_OD);                //使能I2C0引脚
    P3_MFP &= ~(P34_T0_I2CSDA | P35_T1_I2CSCL);
P3_MFP |= (I2CSDA | I2CSCL);        //选择P3.4,P3.5作为I2C0功能引脚   
   
APBCLK |= I2C0_CLKEN;                       //使能I2C0时钟
    I2CLK = I2C_CLOCK;                                                         
    I2CON |= ENSI;                              //使能I2C
}
/*****************************************
*函数名称:AT24C0XWrite
*输    入:unAddr   写地址
          pucData  写数据
    unLength 写长度
*输    出:TRUE/FALSE
*功    能:AT24C0X写数据
******************************************/
BOOL AT24C0XWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
    UINT32 i;
    I2CON |= STA;              //启动
    I2CON |= SI;                        
    while ((I2CON & SI) != SI);        
    I2CON &= ((~STA)&(~SI));            
    if (I2STATUS != 0x08)            
    {
        DEBUGMSG("I2CStart fail,I2STATUS %02X\r\n",I2STATUS);
        
  return FALSE;
    }

    //进入读写控制操作
    I2DAT = EEPROM_SLA | EEPROM_WR;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x18)              
    {
     DEBUGMSG("I2C write control fail\r\n");
      
     return FALSE;
    }
    //写地址
    I2DAT = unAddr;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x28)              
    {
        DEBUGMSG("I2C write addr fail\r\n");
     return FALSE;
    }

//写数据
for(i=0; i<unLength; i++)
{
     I2DAT = *(pucData+i);
     I2CON |= SI;
     while ((I2CON & SI) != SI);
     if (I2STATUS != 0x28)              
     {
         DEBUGMSG("I2C write data fail\r\n");
      return FALSE;
     }
}

    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);               
//DEBUGMSG("I2C stop ok\r\n");
    Timed_Write_Cycle();               
                                             
return TRUE;            
}
/*****************************************
*函数名称:AT24C0XRead
*输    入:unAddr   读地址
          pucData  读数据
    unLength 读长度
*输    出:TRUE/FALSE
*功    能:AT24C0X读数据
******************************************/
BOOL AT24C0XRead(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
UINT32 i;
    I2CON |= STA;                 //启动
    I2CON |= SI;                        
    while ((I2CON & SI) != SI);         
    I2CON &= ((~STA)&(~SI));            
    if (I2STATUS != 0x08)            
    {
        DEBUGMSG("I2CStart fail,I2STATUS %02X\r\n",I2STATUS);
        
  return FALSE;
    }

    //进入读写控制操作  
    I2DAT = EEPROM_SLA | EEPROM_WR;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x18)              
    {
     DEBUGMSG("I2C write control fail\r\n");
      
     return FALSE;
    }
//写入读地址
    I2DAT = unAddr;
    I2CON |= SI;
    while ((I2CON & SI) != SI);
    if (I2STATUS != 0x28)              
    {
        DEBUGMSG("I2C write addr fail\r\n");
     return FALSE;
    }

    // 重新启动
    I2CON |= STA;         
    I2CON |= SI;                                
    while ((I2CON & SI) != SI);                 
    I2CON &= ((~STA)&(~SI));                    
    if (I2STATUS != 0x10)                       
    {
        DEBUGMSG("I2C repeated start fail\r\n");
  return FALSE;
    }
    //进入读操作  
    I2DAT = EEPROM_SLA | EEPROM_RD;
    I2CON |= SI;
    while ((I2CON & SI) != SI);     
    if (I2STATUS != 0x40)              
    {
        DEBUGMSG("I2C write control fail\r\n");
        while (1);
    }
//读取数据
I2CON |= AA;
for(i=0; i<unLength; i++)
{
  
     I2CON |= SI;
     while ((I2CON & SI) != SI);

     if (I2STATUS != 0x50)              
     {
         DEBUGMSG("I2C read fail\r\n");
         return FALSE;
     }

  *(pucData+i) = I2DAT;
}
    //发送NACK到AT24C02,执行断开连接操作
    I2CON &= (~AA);
    I2CON |= SI;
    while ((I2CON & SI) != SI);
        
    //停止
    I2CON |= STO;
    I2CON |= SI;
    while (I2CON & STO);                     
DEBUGMSG("I2C read ok\r\n");
return TRUE;
}
VOID AT24C02ContinousWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
{
    UINT32 i,m,n;

UINT32 unCurWirteCount=0;
   
//if(unLength <= 32)
m = PAGE_SIZE-(unAddr % PAGE_SIZE);   //与当前每页32个字节已剩下多少个字节


if(unLength <= m)
{
    AT24C0XWrite(unAddr,pucData,unLength);
}
else
{
    AT24C0XWrite(unAddr,pucData,m);
   
    unLength -=m;
    unCurWirteCount+=m;
   
    m = unLength/PAGE_SIZE;
    n = unLength%PAGE_SIZE;
   
    for(i=0; i<m; i++)
    {
        AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,PAGE_SIZE);
     
     unCurWirteCount += PAGE_SIZE;
    }
   
    AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,n);   
}
   
}
/*****************************************
*函数名称:main
*输    入:无
*输    出:无
*功    能:函数主体
******************************************/
INT32 main(VOID)
{
  UINT8 i,buf[32];
     Un_Lock_Reg();        //ISP下载时保护FLASH存储器
  PWRCON |= XTL12M_EN;      //默认时钟源为外部晶振
  while((CLKSTATUS & XTL12M_STB) == 0);   //等待12MHz时钟稳定

  CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //设置外部晶振为系统时钟
  UartInit(12000000,9600);     //波特率设置为9600bps
  I2CInit();
  DEBUGMSG("I2C Test\r\n");
  while(1)
  {
     for(i=0; i<sizeof(buf); i++)   //初始化写缓冲区
    {
        buf[i]=0x55;
    }
       DEBUGMSG("\r\nAT24C0XWrite Test\r\n");

    AT24C0XWrite(0,buf,sizeof(buf));  //执行写操作  
    Delayms(500);
    //==================================================

       DEBUGMSG("AT24C0XRead Test\r\n");
     for(i=0; i<sizeof(buf); i++)   //初始化读缓冲区
    {
        buf[i]=0x00;
    }
    AT24C0XRead(0,buf,sizeof(buf));    //执行读操作
    for(i=0; i<10; i++)
    {
     DEBUGMSG("%02X ",buf[i]);     //打印读取的数值
   
    }
    Delayms(500);
  }
}
代码如上。请高手指教,谢谢!

相关帖子

沙发
wangch_sh|  楼主 | 2013-6-17 17:51 | 只看该作者
单步调试,发现if (I2STATUS != 0x08)这一句I2STATUS != 0x08,结果出错了。我把I2CON &= ((~STA)&(~SI));注释掉,I2STATUS = 0x08,可是if (I2STATUS != 0x18)   这句有出错了。郁闷!

使用特权

评论回复
板凳
wangch_sh|  楼主 | 2013-6-18 08:11 | 只看该作者
高手支招啊!

使用特权

评论回复
地板
缥缈九哥| | 2013-6-18 10:56 | 只看该作者
我只是想说,BSP包。我用的是对的。

使用特权

评论回复
5
wangch_sh|  楼主 | 2013-6-18 14:51 | 只看该作者
难道硬件有问题?或者24c02和at24c02的时序不一样?

使用特权

评论回复
6
缥缈九哥| | 2013-6-19 15:31 | 只看该作者
你上拉电阻装了吗?装了多大?

使用特权

评论回复
7
wangch_sh|  楼主 | 2013-6-19 16:01 | 只看该作者
装了,10K。

使用特权

评论回复
8
缥缈九哥| | 2013-6-19 23:36 | 只看该作者
谁告诉你用10K的?快换成1K或者小于4.7K的再说。

使用特权

评论回复
9
wangch_sh|  楼主 | 2013-6-20 09:35 | 只看该作者
好,我试试。

使用特权

评论回复
10
缥缈九哥| | 2013-6-21 10:26 | 只看该作者
试成功了吗?10K的IIC上拉,还是太大了。

使用特权

评论回复
11
wangch_sh|  楼主 | 2013-6-21 14:12 | 只看该作者
没有,换成4.7K还不行。

使用特权

评论回复
12
benscottsih| | 2018-6-21 09:11 | 只看该作者
楼主问题决绝了吗?我也遇到同样的问题?

使用特权

评论回复
13
benscottsih| | 2018-6-22 20:06 | 只看该作者
自己顶一下

使用特权

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

本版积分规则

个人签名:为江山踏坏了乌骓马,为社稷拉断了宝雕弓。

318

主题

2814

帖子

5

粉丝