据说是AT24C01-AT24C256通用源程序,但按照我的经验,这个源程序仅适合AT24C04-AT24C256。
- /*Sample:
- /*main(){ ...
- /* ReadMem(l,x,y); /*读。l为本次访问的器件号,在宏定义时分配不同芯片的不同
- 器件号,
- x为本次欲读出的字节数;y为本次读数的起始地址*/
- /* ...
- /* WriteMem(l,x,y); /*写。l为本次访问的器件号,在宏定义时分配不同芯片不同
- 的器件号,
- x为本次欲写入的字节数;y为本次写数的起始地址,
- 注:当心页写入的地址规律,即页地址在同一页内滚动;否则会出现页溢出*/
- /*}*/
- #define Wait_1us {_nop_();_nop_();}
- #define Wait_2us {Wait_1us;Wait_1us;}
- #define Sla_Wr 0xa0 /*0000 0 0 0 0*/
- #define Sla_Rd 0xa1 /*0000 0 0 0 1*/
- #define AT24C01 0x01
- #define AT24C01A 0x02
- #define AT24C02 0x03
- #define AT24C04 0x04
- #define AT24C08 0x05
- #define AT24C16 0x06
- #define AT24C32 0x07
- #define AT24C64 0x08
- #define AT24C128 0x09
- #define AT24C256 0x0a
- #define AT24C512 0x0b
- #define Mem_Size AT24C256 // 01/01A/02/04/08/16/32/64/128/256/512
- #define Chip_1 0x00 //本器件的器件地址,可以第一8个不同地址的芯片使之能用同一段程序进行读写
- sbit bSda =P3^7;
- sbit bScl =P3^6;
- bit bScan_Err;
- unsigned char idata cShare_Buf[8]={0,1,2,3,4,5,6,7}; //I2c read and write buffer
- void Start_I2c(void);
- void End_I2c(void);
- unsigned char Scan_I2c();
- void Send_I2c(unsigned char cData);
- void Send_Ack(void);
- void Send_Not_Ack(void);
- void Write_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int
- cStart_Address);
- void Read_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int
- cStart_Address);
- /************Name:ScanI2c***********
- Function:read 1byte from 24C01/512
- NO.:1
- Run time:79us 1=4+2us 0=5+1us f=111kbps/83.3Kbps
- **********Function Start************/
- void Start_I2c(void)
- {
- unsigned char /*idata*/ i;
- bSda=bScl=1;
- for(i=0;i<2;i++); //wait 7us
- bSda=0;
- for(i=0;i<2;i++); //wait 7us
- bScl=0;
- }
- /**********Function End*************/
- /************Name:ScanI2c***********
- Function:read 1byte from 24C01/512
- NO.:1
- Run time:79us 1=4+2us 0=5+1us f=111kbps/83.3Kbps
- **********Function Start************/
- void End_I2c(void)
- {
- unsigned char /*idata*/ i;
- bSda=0;
- bScl=1;
- for(i=0;i<2;i++); //wait 7us
- bSda=1;
- }
- /**********Function End*************/
- /************Name:ScanI2c***********
- Function:read 1byte from 24C01/512
- NO.:1
- Run time:79us 1=3/5us 0=1/5us f=250/100kbps
- **********Function Start************/
- unsigned char Scan_I2c()
- {
- unsigned char /*idata*/ i,j;//IIC data
- bSda=1;
- j=0;
- for(i=0;i<8;i++)
- {
- bScl=1;
- j<<=1;
- Wait_2us;
- j|=bSda;
- //Scan 0 Scan 1
- bScl=0;
- Wait_2us;
- Wait_2us;
- }
- return j;
- }
- /**********Function End*************/
- /************Name:SendI2c***********
- Function:Send 1byte to 24C01/512
- NO.:2
- Run time:82us 1=1/3us 0=3us f=250/100kbps
- **********Function Start************/
- void Send_I2c(unsigned char cData)
- {
- unsigned char /*idata*/ i;
- for(i=0;i<8;i++)
- {
- bSda=(bit)(cData&0x80);
- bScl=1;
- cData<<=1;
- Wait_2us;
- Wait_2us;
- bScl=0;
- Wait_2us;
- }
- bSda=bScl=1; //检测ACK
- for(i=0;(bSda==1)&&(bScan_Err==0);i++)
- {
- if(i==30)
- bScan_Err=1; //如果101us没有响应就错误
- }
- bScl=0;
- }
- /**********Function End************/
- /************Name:SendAck***********
- Function:Send ack
- NO.:3
- Run time:10us+4us
- **********Function Start************/
- void Send_Ack(void)
- {
- unsigned char /*idata*/ i;
- bSda=0;
- bScl=1;
- for(i=0;i<2;i++); //wait 8us
- bScl=0;
- bSda=1;
- }
- /**********Function End*************/
- /************Name:SendNotAck***********
- Function:send not ack
- NO.:4
- Run time:10us+4us
- **********Function Start************/
- void Send_Not_Ack(void)
- {
- unsigned char /*idata*/ i;
- bScl=bSda=1;
- for(i=0;i<2;i++); //wait 8us
- bScl=0;
- }
- /**********Function End*************/
- /************Name:WriteMem***********
- Function:write data to 24C01/512
- NO.:5
- Run time:80us(1byte)*cData_Size+
- **********Function Start************/
- void Write_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address)
- {
- unsigned char /*idata*/ i,cAddress[2]; //0-L;1-H
- bScan_Err=0;
- cAddress[0]=cStart_Address;
- cStart_Address>>=8;
- cAddress[1]=cStart_Address;
- i=Sla_Wr;
- i|=cChips_Address;
- if(cMem_Size==AT24C256)
- i&=0xf7;
- Start_I2c();
- Send_I2c(i); //SLA:1010 xxx0
- if(cMem_Size==AT24C256) //1-16用1个字节地址,32-512用2个字节地址,匹配地址AT24C32、64
- Send_I2c(cAddress[1]); //先发送高字节地址
- Send_I2c(cAddress[0]); //如果是双字节地址则为低地址否则为高地址
- for(i=0;(bScan_Err==0)&&(i!=cData_Size);i++)
- Send_I2c(cShare_Buf[i]); //写一个字节数据
- End_I2c();
- }
- /**********Function End*************/
- /************Name:ReadMem***********
- Function:Read data from 24C01/512
- NO.:6
- Run time:80us(1byte)*cData_Size+
- **********Function Start************/
- void Read_Mem(unsigned char cMem_Size,cChips_Address,cData_Size,unsigned int cStart_Address)
- {
- unsigned char /*idata*/ i,cAddress[2];
- bScan_Err=0;
- cAddress[0]=cStart_Address; //将16位地址分解为高低字节
- cStart_Address>>=8;
- cAddress[1]=cStart_Address;
- i=Sla_Wr;
- i|=cChips_Address;
- if(cMem_Size==AT24C256)
- i&=0xf7;
- Start_I2c();
- Send_I2c(i);//SLA:1010 xxx0
- if(cMem_Size==AT24C256) //1-16用1个字节地址,32-512用2个字节地址,匹配地址AT24C32、64
- Send_I2c(cAddress[1]); //先发送高字节地址
- Send_I2c(cAddress[0]); //address and write
- i|=0x01; //Read
- Start_I2c();
- Send_I2c(i); //address and read
- for(i=0;(bScan_Err==0)&&(i!=cData_Size);i++)
- {
- cShare_Buf[i]=Scan_I2c(); //读入第一个字节
- if(i==(cData_Size-1))
- Send_Not_Ack();
- else
- Send_Ack();
- }
- End_I2c();
- }
- /**********Function End*************/