I2C只要完全按照时序来 一般没什么问题, 下面是个PIC上的程序,调试成功的。/****************************************************/
/*杭州晶控电子有限公司 */
/*http://www.hificat.com */
/*EEPROM读写演示程序 */
/*目标器件:PIC16F877A */
/*晶振:4.0MHZ */
/*编译环境:MPLAB V7.51 */
/****************************************************/
/****************************************************************************
包含头文件
****************************************************************************/
#include
/****************************************************************************
数据定义
****************************************************************************/
#define address 0xa
#define nop() asm("nop")
#define OP_READ 0xa1 // 器件地址以及读取操作
#define OP_WRITE 0xa0 // 器件地址以及写入操作
/****************************************************************************
端口定义
****************************************************************************/
#define SCL RB4
#define SDA RB5
#define SCLIO TRISB4
#define SDAIO TRISB5
/****************************************************************************
共阴LED段码表
****************************************************************************/
const char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
/****************************************************************************
函数功能:延时子程序
入口参数:
出口参数:
****************************************************************************/
void delay()
{
int i;
for(i=0;i<100;i++)
{;}
}
/****************************************************************************
函数功能:开始信号
入口参数:
出口参数:
****************************************************************************/
void start()
{
SDA=1;
nop();
SCL=1;
nop();nop();nop();nop();nop();
SDA=0;
nop();nop();nop();nop();nop();
SCL=0;
nop();nop();
}
/****************************************************************************
函数功能:停止信号
入口参数:
出口参数:
****************************************************************************/
void stop()
{
SDA=0;
nop();
SCL=1;
nop();nop();nop();nop();nop();
SDA=1;
nop();nop();nop();nop();
}
/****************************************************************************
函数功能:读取数据
入口参数:
出口参数:read_data
****************************************************************************/
unsigned char shin()
{
unsigned char i,read_data;
for(i=0;i<8;i++)
{ nop();nop();nop();
SCL=1;
nop();nop();
read_data<<=1;
if(SDA == 1)
read_data=read_data+1;
nop();
SCL=0;
}
return(read_data);
}
/****************************************************************************
函数功能:向EEPROM写数据
入口参数:write_data
出口参数:ack_bit
****************************************************************************/
bit shout(unsigned char write_data)
{
unsigned char i;
unsigned char ack_bit;
for(i = 0; i < 8; i++)
{
if(write_data&0x80)
SDA=1;
else
SDA=0;
nop();
SCL = 1;
nop();nop();nop();nop();nop();
SCL = 0;
nop();
write_data <<= 1;
}
nop();nop();
SDA = 1;
nop();nop();
SCL = 1;
nop();nop();nop();
ack_bit = SDA; // 读取应答
SCL = 0;
nop();nop();
return ack_bit; // 返回AT24Cxx应答位
}
/****************************************************************************
函数功能:向指定地址写数据
入口参数:addr,write_data
出口参数:
****************************************************************************/
void write_byte(unsigned char addr, unsigned char write_data)
{
start();
shout(OP_WRITE);
shout(addr);
SDAIO = 0; //在写入数据前SDA应设置为输出
shout(write_data);
stop();
delay();
}
/****************************************************************************
函数功能:向指定地址读数据
入口参数:random_addr
出口参数:read_data
****************************************************************************/
unsigned char read_random(unsigned char random_addr)
{ unsigned char read_data;
start();
shout(OP_WRITE);
shout(random_addr);
start();
shout(OP_READ);
SDAIO = 1; //读取数据前SDA应设置为输入
read_data = shin();
stop();
return(read_data);
}
/****************************************************************************
函数功能:显示子程序
入口参数:k
出口参数:
****************************************************************************/
void display(unsigned char k)
{
TRISA=0X00; //设置A口全为输出
PORTC=table[k/1000]; //显示千位
PORTA=0xEF;
delay();
PORTC=table[k/100%10]; //显示百位
PORTA=0xDF;
delay();
PORTC=table[k/10%10]; //显示十位
PORTA=0xFB;
delay();
PORTC=table[k%10]; //显示个位
PORTA=0xF7;
delay();
}
/****************************************************************************
函数功能:主程序
入口参数:
出口参数:
****************************************************************************/
void main()
{
unsigned char eepromdata;
TRISB=0X00;
OPTION&=~(1<<7); //设置RB口内部上拉电阻有效
TRISC=0X00;
PORTB=0X00;
PORTC=0xff;
TRISA=0X00;
eepromdata=0;
write_byte(0x01,0x55); //向0x01地址写入0x55(85)的数据
delay();
write_byte(0x02,0xaa); //向0x02地址写入0xAA(170)的数据
delay();
eepromdata=read_random(0x02); // 读取其中一个地址内的数据来验证
while(1)
{
display(eepromdata);
}
}
复制代码