以下程序本人仅在 6MHZ晶振,AT89CXX测试通过..至于其它晶振下未经测试,也不知道行不行.如果不行,请自行调整延时量.主要在于了解IIC总线的操作,这样不管是AT24C0X还是其它的IIC总线的芯片都可以很好的去应用.
#include <AT89X51.H>
sbit SDA=P2^5;//SDA
sbit SCL=P2^4;//SCL
sbit WP=P2^3;//WP
/*----------------------------------------------
6MHZ晶振,AT89CXX
----------------------------------------------*/
void delay20ms(void)
{ //延时20ms
int t=1240;
unsigned char i=11;
for(;i!=0;i--)
for(;t!=0;t--);
}
//--------------------
void MDDelay(void)
{
unsigned char i=0;
for(;i<=10;i++);
}
/*------------------------
开始信号
--------------------------*/
void Start(){
SDA=1;//数据线高电平
SCL=1;//时钟高电平
MDDelay();
SDA=0;//数据下跳作为开始信号
SCL=0;//时钟高电平
MDDelay();
}
/*-----------------------
停止信号
-----------------------*/
void Stop(){
SDA=0;//数据线高电平
SCL=1;//时钟高电平
MDDelay();
SDA=1;//数据线高电平
MDDelay();
}
/*-----------------------
发送应答
-----------------------*/
void Ack() {
SDA=0;
SCL=1;
MDDelay();
SCL=0;
}
/*-----------------------
发送不应答
-----------------------*/
void NoAck() {
SDA=1;
SCL=1;
MDDelay();
SCL=0;
}
/*-------------------------------------------------------
写一个byte
-------------------------------------------------------------*/
void WriteByte(unsigned char BufByte)
{
unsigned char i;
for(i=1;i<=8;i++){
SCL=1;
MDDelay();
SDA=(bit)(BufByte&0x80);//从高位开始写入,输出一位数据
SCL=0;
MDDelay();
BufByte<<=1;//左移一位
}
SCL=0;
}
/*--------------------------------------------------
写(page wirte) 24C04
--------------------------------------------------*/
void Write24c04(unsigned char *ArrayData,unsigned char RomAddress,unsigned char ArrayLen)
{
Start();//发送开始信号
WriteByte(0xA0);//"写"命令+片选地下信号(只有一个a2,a1,a0==0)
Ack();
WriteByte(RomAddress);//准备写入EEPROM地址信息
Ack();
for(;ArrayLen!=0;ArrayLen--)
{
WriteByte(*ArrayData);
Ack();
ArrayData++;//指针下移取下一个ArrayData数组的地址
}
Stop();//发送停止信号
}
/*----------------------------------
读一个byte
-------------------------------------*/
unsigned char Read8Bit()
{
unsigned char i,rbyte=0;
SDA=1;
for(i=1;i<=8;i++) {
SCL=1;
SCL=0;
rbyte<<=1;
if(SDA) rbyte|=0x01;
}
return(rbyte);
}
/*--------------------------------------------------
读24C004 (Randowm read 方式)
--------------------------------------------------*/
void Read24c04(unsigned char *ReadData,unsigned char RomAddress,unsigned char bytes)
{
unsigned char i;
for(i=0;i<bytes;i++){
Start();//发送开始信号
WriteByte(0xA0);//"写"命令+片选地下信号
Ack();
WriteByte(RomAddress+i);//写入片地址信息
Ack();
//--------------
Start();//重复发送开始信号,注:这里和写不同
WriteByte(0xA1);//(读)+片选地值(000)
Ack();
//---------
*(ReadData+i)=Read8Bit();//将读来的数据保存至ReadBuf数组中
NoAck();
Stop();
}
}
/*--------------------------
初始化port
---------------------------*/
void Rest()
{
WP=0;//置低电平,清除写保护
SDA=0;//数据总线置低电平
SCL=0;//时钟置低电平
}
void main()
{
unsigned char myd[9]={'1','2','3','4','5','6','7','8','\0'};
unsigned char myRead[9];
Rest();
Write24c04(&myd,0x00,9);
delay20ms();
delay20ms();
Read24c04(&myRead,0x00,9);
delay20ms();
delay20ms();
}