原创 典点24Cxx读写程序

2010-4-21 16:37 5241 10 10 分类: 工程师职场

主程序里只要调用就可以用


 RW24XX(&alarm_hour,1,group_temp,0xa0, M2402);    //写入作息时间时


 RW24XX(&alarm_hour,1,group_temp,0xa1, M2402);    //读取作息时间时


// ****************************** //
// *** I2C Hardware Interface *** //
// ****************************** //


#define SDA2 BIT1
#define SCL2 BIT0


#define I2C_PORT2   PORTD
#define I2C_DIR2  DDRD
#define I2C_IN2  PIND


#define WrDevAddr  0xAE
#define RdDevAddr  0xAF
#define Write  0
#define Read  1
//#define WrDevAddr  0xA6
//#define RdDevAddr  0xA7
//相差2K
#define SaveNameStartAddr 0x100
#define SaveJobStartAddr 0x900


//对应芯片容量
//#pragma data: code
//const unsigned int M24Cxx[]={0x7F,0xFF,0x1FF,0x3FF,0x7FF,0xFFF,0x1FFF,0x3FFF,0x7FFF};   //M24_N[EEPROM_Type]
//#pragma data: data


#define _IICAPP_GLOBAL_


#define _IICAPP_GLOBAL_


#include "iom128v.h"
#include "macros.h"
#include "iicAppH.H"
#include "24c64.h"


unsigned int EEPROM_Type2 = M24256;


/*================================================================ 
 函 数 名: void Init_I2C(void)
 参    数:        
 功能描述:  This routine will setup the I2C Port
 返 回 值: 无 
 例    如:
================================================================*/ 
void Init_I2C2(void)
{
 SETBIT(I2C_DIR2,SCL2);             // Set SCL to output
 SETBIT(I2C_DIR2,SDA2 );           // Set SDA to output
 SETBIT(I2C_PORT2,SCL2);          // Set SCL high
 SETBIT(I2C_PORT2,SDA2 );          // Set SDA high
}



/*================================================================ 
 函 数     名: void I2CStart (void)
 参            数:        
 功能描述:  This routine will send the I2C Start Bit
 返 回    值 : 无 
 例           如 :
================================================================*/ 
void I2CStart2 (void)
{
 SETBIT(I2C_DIR2,SDA2);             // Set SDA to output 
 SETBIT(I2C_DIR2,SCL2);             // Set SCL to output 


 SETBIT(I2C_PORT2,SDA2);       // Set SDA High 
 SETBIT(I2C_PORT2,SCL2);       // Set SCL High 
 I2S_Clock_Delay();
 //SDA从高电平到低电平至少时间
 ///1.8V~2.5V  4us
 ///4.5V~5.5V  0.6us
 CLEARBIT(I2C_PORT2,SDA2);          // Clear SDA 
 CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL
 I2S_Clock_Delay();
 //SCL时钟低电平至少时间
 ///1.8V~2.5V  4.7us
 ///4.5V~5.5V  1.2us
 //SCL时钟高电平至少时间
 ///1.8V~2.5V  4us
 ///4.5V~5.5V  0.6us
}



/*================================================================ 
 函 数     名: void I2CStop (void)
 参            数:        
 功能描述:  This routine will send the I2C Stop Bit
 返 回    值 : 无 
 例           如 :
================================================================*/ 
void I2CStop2 (void)
{
 SETBIT(I2C_DIR2,SDA2);             // Set SDA to output 
 SETBIT(I2C_DIR2,SCL2);             // Set SCL to output 


 CLEARBIT(I2C_PORT2,SDA2);          // Clear SDA
 //nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop(); 
 SETBIT(I2C_PORT2,SCL2);          // Set SCL High
 I2S_Clock_Delay();
 SETBIT(I2C_PORT2,SDA2);          // Set SDA High 
 I2S_Clock_Delay();
 //CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL
 //nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();
 //nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();


}


/*================================================================ 
 函 数     名: unsigned char I2CRecAck(void)
 参            数:        
 功能描述:  This routine returns a 0 if the I2C device sends an acknowledge
 返 回    值 : 无 
 例           如 :
================================================================*/ 
unsigned char I2CRecAck2(void)
{
 unsigned char Ackn = 0;          // Temp RAM for Ackn flag


 CLEARBIT(I2C_DIR2,SDA2);             // Set SDA to input 
 CLEARBIT(I2C_PORT2,SCL2);
 I2S_Clock_Delay();
 SETBIT(I2C_PORT2,SCL2);          // Clock the ACK bit
 //nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();


 if ( CHECKBIT( I2C_IN2,SDA2 ) ) Ackn = 1;      // Check the ACK bit on SDA 
 CLEARBIT(I2C_PORT2,SCL2);            // Clear the clock
 nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();
 return Ackn;             // Return our ACK bit

/*================================================================ 
 函 数     名: void I2CAck(void)
 参            数:        
 功能描述:  I2C应答
 返 回    值 : 无 
 例           如 :
================================================================*/ 
void I2CAck2(void)
{
 SETBIT(I2C_DIR2,SDA2);             // Set SDA to output 
 SETBIT(I2C_DIR2,SCL2);             // Set SCL to output 


 //nop();
 CLEARBIT(I2C_PORT2,SDA2);          // Clear SDA
 CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL 
 SETBIT(I2C_PORT2,SCL2);          // Set SCL High
 I2S_Clock_Delay();
 CLEARBIT(I2C_PORT2,SCL2);
}
/*================================================================ 
 函 数     名: void I2CNoAck(void)
 参            数:        
 功能描述:  I2C不应答
 返 回    值 : 无 
 例           如 :
================================================================*/ 
void I2CNoAck2(void)
{
 SETBIT(I2C_PORT2,SDA2);          // Set SDA High
 CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL 
 SETBIT(I2C_PORT2,SCL2);          // Set SCL High
 I2S_Clock_Delay();
 CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL


}


/*================================================================ 
 函 数     名: void I2CSendByte(unsigned char byte)
 参            数:        
 功能描述:  This routine will write a byte to the I2C device
 返 回    值 : 无 
 例           如 :
================================================================*/ 
void I2CSendByte2(unsigned char byte)
{
 unsigned char i;


 SETBIT(I2C_DIR2,SDA2);             // Set SDA to output 
 SETBIT(I2C_DIR2,SCL2);             // Set SCL to output 


 for (i = 0; i < 8; i++)         // Loop for our 8 bits
 {    
  if((byte & 0x80) == 0x80) SETBIT(I2C_PORT2, SDA2); // Set I2C SDA PIN
  else CLEARBIT(I2C_PORT2,SDA2);        // Clear I2C SDA PIN


  CLEARBIT(I2C_PORT2,SCL2);
  SETBIT(I2C_PORT2,SCL2);          // Set SCL High, Clock data
  I2S_Clock_Delay();
  CLEARBIT(I2C_PORT2,SCL2);          // Clear SCL 不能换位置
  byte = byte << 1;            // Shift data in buffer right one
 }
 I2S_Clock_Delay();
 
}


/*================================================================ 
 函 数     名: unsigned char I2CReceiveByte(void)
 参            数:        
 功能描述:  This routine will read a byte from the I2C device
 返 回    值 : 无 
 例           如 :
================================================================*/ 
unsigned char I2CReceiveByte2(void)

 unsigned char i,buff = 0;
 
 SETBIT(I2C_DIR2,SDA2);             // Set SDA to output 
 CLEARBIT(I2C_DIR2,SDA2);              // Set SDA to input
 for (i = 0; i < 8; i++)
 {  
  buff = buff << 1; 
  CLEARBIT(I2C_PORT2,SCL2);               // Clear SCL
  I2S_Clock_Delay();
  SETBIT(I2C_PORT2,SCL2);               // Set SCL High,Clock bit out
  //nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();nop();               // Read data on SDA pin
  if (CHECKBIT(I2C_IN2,SDA2))
  buff = buff | 0x01; 
  CLEARBIT(I2C_PORT2,SCL2);               // Clear SCL
 }
 return buff;              // Return our I2C byte
}


 


/**************24XX读写主函数*****************************************
 DataBuff      为读写数据输入/输出缓冲区的首址
 ByteQuantity  为要读写数据的字节数量
 Address       为EEPROM的片内地址
 ControlByte   为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,
               表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;
 EEPROM_Type    为枚举变量,需为M2401至M24256中的一种,分别对应24C01至24C256;
 函数返回值:   位变量,1=次操作失效,0=操作成功;写入时检测不对.
 ErrorCount    为允许最大次数,若出现ErrorCount次操作失效后,则函数中止操作,并返回1
 SDA和SCL由用户自定义,这里暂定义为P0^0和P0^1;
 其余的用户不用管,只要把只子程序放在你的程序中并调用它就可以了;
 jiao注:器件型号,页大小。
   24C01C  16 字节
  24C02C  16 字节
  24LC04B  16 字节
  24LC08B  16 字节
  24LC16B    16 字节
  24LC32A  32 字节
  24LC64  32 字节
  24C128页写容量:64字节
  24C256页写容量:64字节
EEPROM的片内地址分布:
CAT24WC01/02/04/08/16 
24WC01/24WC02   (1)(0)(1)(0)(A2)(A1)(A0)(R/W)
24WC04     (1)(0)(1)(0)(A2)(A1)(a8)(R/W)
24WC08     (1)(0)(1)(0)(A2)(a9)(a8)(R/W)
24WC16     (1)(0)(1)(0)(a10)(a9)(a8)(R/W)
24WC32/64    (1)(0)(1)(0)(A2)(A1)(A0)(R/W)
24WC128     (1)(0)(1)(0)(X)(X)(X)(R/W)
24WC256     (1)(0)(1)(0)(0)(A1)(A0)(R/W)


1. A0 A1 和A2 对应器件的管脚1 2 和3
2. a8 a9 和a10 对应存储阵列地址字地址
3. X表示1和0任意.


这些输入脚用于多个器件级联时设置器件地址当这些脚悬空时默认值为0 24WC01 除外
当使用24WC01 或24WC02 时最大可级联8 个器件如果只有一个24WC02 被总线寻址这三个地
址输入脚A0 A1 A2 可悬空或连接到Vss 如果只有一个24WC01 被总线寻址这三个地址输入
脚A0 A1 A2 必须连接到Vss
当使用24WC04 时最多可连接4 个器件该器件仅使用A1 A2 地址管脚A0 管脚未用可以连
接到Vss 或悬空如果只有一个24WC04 被总线寻址A1 和A2 地址管脚可悬空或连接到Vss
当使用24WC08 时最多可连接2 个器件且仅使用地址管脚A2 A0 A1 管脚未用可以连接到
Vss 或悬空如果只有一个24WC08 被总线寻址A2 管脚可悬空或连接到Vss
当使用24WC16 时最多只可连接1 个器件所有地址管脚A0 A1 A2 都未用管脚可以连接到
Vss 或悬空
*******************************************************************************/
unsigned char  RW24XX2(unsigned char *DataBuff, unsigned int ByteQuantity, unsigned int Address,unsigned char ControlByte)
{
 unsigned char j,i=ErrorCount;
 unsigned char errorflag="1";


 CLI();
 while(i--)
 {
  I2CStart2();
  I2CSendByte2(ControlByte&0xfe);
  if(I2CRecAck2()== 1) continue;
  if(EEPROM_Type2>M2416)
  {
   I2CSendByte2((unsigned char)(Address>>8));
   if(I2CRecAck2()== 1) continue;
  }
  I2CSendByte2((unsigned char)Address);
  if(I2CRecAck2()==1) continue;
  if((ControlByte&0x01)== 0)
  {
   j=ByteQuantity;
   errorflag=0;                      //********clr errorflag
   while(j--)
   {
    I2CSendByte2(*DataBuff++);
    if(I2CRecAck2()== 0) continue;
    errorflag=1;
    //Delay_E(1000);
    break;
   }
   if(errorflag==1) continue;
   break;
  }
  else
  {
   I2CStart2();
   I2CSendByte2(ControlByte);
   if(I2CRecAck2()== 1) continue;
   while(--ByteQuantity)
   {
    *DataBuff++=I2CReceiveByte2();
    I2CAck2();
   }
   *DataBuff=I2CReceiveByte2();    //read last byte data
   I2CNoAck2();
   errorflag=0;
   break;
  }
 }
 I2CStop2();
 SEI();
 if((ControlByte&0x01)== 0)
 {
  for (i=0; i<80; i++)
  {
   I2S_Clock_Delay();//一定要.要不然在写后马上又读会不成功
  }
 
 }
 return(errorflag);
}


//自己用这代码读写过24C02.24C64.24C256

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /2 下一条