搜索
bottom↓
回复: 15

哪位用过AT24C1024

[复制链接]

出0入0汤圆

发表于 2011-8-29 08:54:52 | 显示全部楼层 |阅读模式
我现在编写的AT24C1024程序,不知道什么原因,只能读写一半空间,我在编程时也加了页的控制,就是不能读写页设置1时空间,请大家给以指点,早出原因。非常感谢!

出0入0汤圆

发表于 2011-8-29 10:45:11 | 显示全部楼层
会不会是时序问题?回复【楼主位】lyq123456
-----------------------------------------------------------------------

回复【楼主位】lyq123456
-----------------------------------------------------------------------
会不会是时序问题?

出0入0汤圆

发表于 2011-8-29 11:23:35 | 显示全部楼层
上图、上代码。

出0入0汤圆

发表于 2011-8-29 11:33:24 | 显示全部楼层
I can help you:
This chip has 2 different I2C addresses:

Like this ...
#define AT91C_EEPROM_I2C_ADDRESS_1          ( ( 0xA0 << 15 ) | AT91C_TWI_IADRSZ_2_BYTE )   //the first 64Kbyte
#define AT91C_EEPROM_I2C_ADDRESS_2          ( ( 0xA2 << 15 ) | AT91C_TWI_IADRSZ_2_BYTE )   //the second 64Kbyte


So the read application is like this:
S16 at24_write ( U32 a_adr, U8 a_val )
{
    int mode_adr;
   
    i2c_ok = 0;
   
#ifdef AT24_ERROR
    return;
#endif
   
    if ( a_adr & 0xFFFF0000 )
    {
        mode_adr = AT91C_EEPROM_I2C_ADDRESS_2;
        a_adr &= 0x0000FFFF;        
    }
    else
    {
        mode_adr = AT91C_EEPROM_I2C_ADDRESS_1;
    }
   
    if ( AT91F_TWI_WriteByte ( mypTWI, mode_adr, a_adr, (S8*)&a_val, 1 ) < 1000 )        
    i2c_ok = 1;
   
    return i2c_ok;
}

出0入0汤圆

 楼主| 发表于 2011-8-29 13:08:41 | 显示全部楼层
回复【3楼】sgweilong
-----------------------------------------------------------------------

能加一下QQ吗,帮我解决一下,849438298,非常感谢

出0入0汤圆

 楼主| 发表于 2011-8-29 14:31:31 | 显示全部楼层
void EEPROM_ByteWrite(unsigned long addr, unsigned char dat)
{
unsigned char SMB_SINGLEBYTE_OUT;              // Global holder for single byte writes.
        while (SMB_BUSY);                   // Wait for SMBus to be free.
        SMB_BUSY = 1;                       // Claim SMBus (set to busy)

        // Set SMBus ISR parameters
        TARGET = EEPROM_ADDR;               // Set target slave address
        SMB_RW = WRITE;                     // Mark next transfer as a write
        SMB_SENDWORDADDR = 1;               // Send Word Address after Slave Address
        SMB_RANDOMREAD = 0;                 // Do not send a START signal after the word address
        SMB_ACKPOLL = 1;                    // Enable Acknowledge Polling (The ISR
                                                   // will automatically restart the
                                                   // transfer if the slave does not
                                                   // acknoledge its address.
        // Specify the Outgoing Data
        WORD_ADDR_order=0;       
        //ADDR_D0=0;
        //ADDR_D0=addr&0x01;
    //ADDR_D0 |=(addr>>16)&0x01;
                              // if(addr>0xffff)
        if(addr & 0xffff0000)
          {
            SMB_RW |= 0x02;
           }
           else {SMB_RW |= 0x00;}                                                   //     ADDR_D0=0x02;
                                                           // else ADDR_D0=0x00;
        WORD_ADDR_H = (addr>>8)&0xff;              // Set the target address in the
                                                   // EEPROM's internal memory space
        WORD_ADDR_L = addr&0xff;

        SMB_SINGLEBYTE_OUT = dat;           // Store <dat> (local variable) in a
                                                   // global variable so the ISR can read
                                                   // it after this function exits
        pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;// The outgoing data pointer points to the <dat> variable
        SMB_DATA_LEN = 1;                   // Specify to ISR that the next transfer
                                                          // will contain one data byte  
        STA = 1;                                                        // Initiate SMBus Transfer
}

//-----------------------------------------------------------------------------
// EEPROM_WriteArray ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1) unsigned char dest_addr - beginning address to write to in the EEPROM
//                        range is full range of character: 0 to 255
//
//   2) unsigned char* src_addr - pointer to the array of data to be written
//                        range is full range of character: 0 to 255
//
//   3) unsigned char len - length of the array to be written to the EEPROM
//                        range is full range of character: 0 to 255
//
// Writes <len> data bytes to the EEPROM slave specified by the <EEPROM_ADDR>
// constant.
//
void EEPROM_WriteArray(unsigned long dest_addr, unsigned char* src_addr,
                                           unsigned char len)
                       
{
        unsigned char i;
////        unsigned char* pData = (unsigned char*) src_addr;
        unsigned char* pData;
    pData = src_addr;
        WP = 0;                                // allows normal write operations
        PCA0CPH4 = 0x00;                // 喂狗
        for( i = 0; i < len; i++ )
        {
          EEPROM_ByteWrite(dest_addr++, *pData++);
        }
//        WP = 1;                                // write operations to the memory are inhibited
}

//-----------------------------------------------------------------------------
// EEPROM_ReadArray ()
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1) unsigned char* dest_addr - pointer to the array that will be filled
//                                 with the data from the EEPROM
//                        range is full range of character: 0 to 255
//
//   2) unsigned char src_addr - beginning address to read data from the EEPROM
//                        range is full range of character: 0 to 255
//
//   3) unsigned char len - length of the array to be read from the EEPROM
//                        range is full range of character: 0 to 255
//
// Reads up to 256 data bytes from the EEPROM slave specified by the
// <EEPROM_ADDR> constant.
//
void EEPROM_ReadArray (unsigned char* dest_addr, unsigned long src_addr,
                       unsigned char len)
{
   while (SMB_BUSY);                   // Wait for SMBus to be free.
   SMB_BUSY = 1;                       // Claim SMBus (set to busy)
   // Set SMBus ISR parameters
   TARGET = EEPROM_ADDR;               // Set target slave address
   SMB_RW = WRITE;                     // A random read starts as a write
                                       // then changes to a read after
                                       // the repeated start is sent. The
                                       // ISR handles this switchover if
                                       // the <SMB_RANDOMREAD> bit is set.
   SMB_SENDWORDADDR = 1;               // Send Word Address after Slave Address
   SMB_RANDOMREAD = 1;                 // Send a START after the word address
   SMB_ACKPOLL = 1;                    // Enable Acknowledge Polling

   // Specify the Incoming Data
   WORD_ADDR_order=0;
   if(src_addr & 0xffff0000)
    {
          SMB_RW |= 0x02;
        }
        else {SMB_RW |= 0x00;}
   //ADDR_D0=0;
   //ADDR_D0=src_addr&0x01;
  // ADDR_D0 |=(src_addr>>16)&0x01;
                                        //  if(src_addr>0xffff)
                                                                    //   ADDR_D0=0x02;
                                                                    //else ADDR_D0=0x00;
   WORD_ADDR_H = (src_addr>>8)&0xff;          // Set the target address in the
                                       // EEPROM's internal memory space
   WORD_ADDR_L = src_addr&0xff;

   // Set the the incoming data pointer
   pSMB_DATA_IN = (unsigned char*) dest_addr;
   SMB_DATA_LEN = len; // Specify to ISR that the next transfer will contain <len> data bytes
   STA = 1;                                                        // Initiate SMBus Transfer
   while(SMB_BUSY);                 // Wait until data is read

}

出0入0汤圆

 楼主| 发表于 2011-8-29 14:32:19 | 显示全部楼层
void SMBus_ISR (void) interrupt 7
{
   bit FAIL = 0;                       // Used by the ISR to flag failed
                                       // transfers
   static char i;                      // Used by the ISR to count the
                                       // number of data bytes sent or
                                       // received
   static bit SEND_START = 0;          // Send a start
   switch (SMB0CN & 0xF0)              // Status vector
   {
      // Master Transmitter/Receiver: START condition transmitted.
      case SMB_MTSTA:
             PCA0CPH4 = 0x00;              // watchdog
         SMB0DAT = TARGET;             // Load address of the target slave
         SMB0DAT &= 0xFC;              // Clear the LSB of the address for the R/W bit
         
                  //SMB0DAT |=0x00;
              SMB0DAT |= SMB_RW;  //(SMB_RW|ADDR_D0);            // Load R/W bit
               

         
                 
         STA = 0;                      // Manually clear START bit
         i = 0;                        // Reset data byte counter
         break;
      // Master Transmitter: Data byte (or Slave Address) transmitted
      case SMB_MTDB:
         if (ACK)                      // Slave Address or Data Byte
         {                             // Acknowledged?
            if (SEND_START)
            {
               STA = 1;
               SEND_START = 0;
               break;
            }
            if(SMB_SENDWORDADDR)       // Are we sending the word address?
            {
                                if(WORD_ADDR_order==0)
                                {
                                        SMB0DAT = WORD_ADDR_H;    // Send first word address
                                        WORD_ADDR_order=1;
                                        break;
                                }
                                if(WORD_ADDR_order==1)
                                {
                                   SMB_SENDWORDADDR = 0;   // Clear flag
                                   SMB0DAT = WORD_ADDR_L;    // Send word address
                                   if (SMB_RANDOMREAD)
                                   {
                                      SEND_START = 1;      // Send a START after the next ACK cycle
                                      SMB_RW = READ;
                                   }
                                   break;
                                }
            }
//=================================================================================
            if (SMB_RW==WRITE)         // Is this transfer a WRITE?
            {
               if (i < SMB_DATA_LEN)   // Is there data to send?
               {
                  SMB0DAT = *pSMB_DATA_OUT;        // send data byte
                  pSMB_DATA_OUT++;                        // increment data out pointer
                  i++;                                                // increment number of bytes sent
               }
               else
               {
                 STO = 1;              // Set STO to terminte transfer
                 SMB_BUSY = 0;         // Clear software busy flag
               }
            }
            else {}                    // If this transfer is a READ,
                                       // then take no action. Slave
                                       // address was transmitted. A
                                       // separate 'case' is defined
                                       // for data byte recieved.
         }
         else                          // If slave NACK,
         {
            if(SMB_ACKPOLL)
            {
               STA = 1;                // Restart transfer
            }
            else
            {
               FAIL = 1;               // Indicate failed transfer
            }                          // and handle at end of ISR
         }
         break;
      // Master Receiver: byte received
      case SMB_MRDB:
         if ( i < SMB_DATA_LEN )       // Is there any data remaining?
         {
            *pSMB_DATA_IN = SMB0DAT;   // Store received byte
            pSMB_DATA_IN++;            // Increment data in pointer
            i++;                       // Increment number of bytes received
            ACK = 1;                   // Set ACK bit (may be cleared later in the code)
         }
         if (i == SMB_DATA_LEN)        // This is the last byte
         {
            SMB_BUSY = 0;              // Free SMBus interface
            ACK = 0;                   // Send NACK to indicate last byte of this transfer
            STO = 1;                   // Send STOP to terminate transfer
         }
         break;
      default:
         FAIL = 1;                     // Indicate failed transfer and handle at end of ISR
         break;
   }
   if (FAIL)                           // If the transfer failed,
   {
      SMB0CF &= ~0x80;                 // Reset communication
      SMB0CF |= 0x80;
      STA = 0;
      STO = 0;
      ACK = 0;
      SMB_BUSY = 0;                    // Free SMBus
      FAIL = 0;
   }
   SI = 0;

出0入0汤圆

 楼主| 发表于 2011-8-29 14:49:29 | 显示全部楼层
回复【3楼】sgweilong
-----------------------------------------------------------------------

你怎么左移位15位,不是16位吗?

出0入0汤圆

发表于 2011-8-29 15:35:00 | 显示全部楼层
回复【7楼】lyq123456
-----------------------------------------------------------------------

I use ARM7, the structure is some different from normal 51 MCU. The RD and WR bit is added by MCU itself.

出0入0汤圆

 楼主| 发表于 2011-8-29 16:01:02 | 显示全部楼层
我现在只能读一页数据,另一页读不出,不知道什么原因

出0入0汤圆

发表于 2011-8-29 17:02:27 | 显示全部楼层
Should can.

For read, no "page" at all. For write, it will have a 256-byte page write limitation.
If you can read half 64Kbyte, the other half is the same, only the chip address is different.

1pc at1024 = 2pcs at512.

出0入0汤圆

 楼主| 发表于 2011-8-30 08:14:25 | 显示全部楼层
我认为在A0、A2的有问题;
但是我是按要求写的。怎么只能读A1的数据,不能读A3时的数据,不知什么原因。

出0入0汤圆

发表于 2011-8-30 11:32:32 | 显示全部楼层
检查下你那片子,是否是真的?

或者说就像我们现在的U盘,是被1024了?

出0入0汤圆

 楼主| 发表于 2011-8-30 14:23:30 | 显示全部楼层
芯片上标识是   
ATMLH016
2GB 2
9H3615B
不知道这个是不是1024的
现在只能读64K的地址

出0入0汤圆

 楼主| 发表于 2011-8-30 16:44:46 | 显示全部楼层
调试了几天,都是能读存64KB数据,另一半还是读存不出来。改为AT24C1024W芯片事事

出20入0汤圆

发表于 2017-4-22 15:27:59 | 显示全部楼层
一片1024相当于挂了两片512;访问的时候第一片地址为“0xa0”第二片为“0xa2”,要切换地址才行
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 06:00

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表