元件是好的,我用匯編寫過一個,運行是ok的.
查了兩天沒找到問題.
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit SCL=P1^6;
sbit SDA=P1^7;
/*
* 1,函數介紹:延時8us(以12M晶振為準)
* 輸入參數: 無
* 輸出參數: 無
* 返回值: 無
*/
void delay8us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/*
* 2,函數介紹:延時n_msec ms(以12M晶振為準)
* 輸入參數: n_msec,最大256
* 輸出參數: 無
* 返回值: 無
*/
void delay_ms(uchar n_msec)
{
uchar i;
do
{
i=245;
while(--i);
i=245;
while(--i);
}
while(--n_msec);
}
/*
* 3,函數介紹:I2C起動總線函數
* 輸入參數: 無
* 輸出參數: 無
* 返回值: 無
*/
void i2c_start(void)
{
SDA=1;
SCL=1;
delay8us();
SDA=0;
SCL=0;
}
/*
* 4,函數介紹:I2C結束函數
* 輸入參數: 無
* 輸出參數: 無
* 返回值: 無
*/
void i2c_stop(void)
{
SDA=0; /*發送結束條件的數據信號*/
SCL=1;
delay8us();
SDA=1;
SCL=1;
}
/*
* 5,函數介紹:I2C寫一個字節str
* 輸入參數: str
* 輸出參數: 返回應答位
* 返回值: 為0 成功
*/
bit i2c_write_byte(uchar str)
{
uchar bitnum;
uchar temp;
bit ack;
temp=str;
for(bitnum=0;bitnum<8;bitnum++)
{
SCL=0;
SDA=temp&0x80;
SCL=1;
delay8us();
temp=temp<<1;
}
SCL=0;
SDA=1;
delay8us();
SCL=1;
ack=SDA;
return(ack); /*判斷是否接收到應答,1表示沒有應答*/
}
/*AT24C02eeprom系列函數
,函數介紹:(以12M晶振為準)*/
void delay8us(void);/*延時子程序*/
void delay_ms(uchar);/*延時子程序*/
void i2c_start(void);
void i2c_stop(void);
bit i2c_write_byte(uchar str);
/*
* 1,函數介紹:發送應答
* 輸入參數: 址
* 輸出參數:
* 返回值:
*/
void send_ack(void)
{
SCL=0;
delay8us();
SDA=0;
delay8us();
SCL=1;
SDA=1;
}
/*
* 2,函數介紹:發送不應答
* 輸入參數:
* 輸出參數:
* 返回值:
*/
void send_no_ack(void)
{
SCL=0;
delay8us();
SDA=1;
delay8us();
SCL=1;
SDA=1;
}
/*
* 3,函數介紹:I2C讀一個字節str
* 輸入參數: str
* 輸出參數: 返回讀得的字節
* 返回值:
*/
uchar i2c_read_byte()
{
bit bdata onebit=0;
uchar bitnum;
uchar read_abyte=0;
for(bitnum=0;bitnum<8;bitnum++)
{
read_abyte<<=1;
SCL=0;
SDA=1;
delay8us();
SCL=1;
delay8us();
onebit=SDA;
if(onebit==1)
read_abyte++;
}
return(read_abyte);
}
/*
* 4,函數介紹:EEPROM頁讀n個字節從起始到結束
* 輸入參數: part_add:器件地址
ram_add:片內字節地址,
write_num:欲寫個數
data_add:欲寫數據地址
* 輸出參數:
* 返回值:
*/
void eeprom_read_page(part_add,ram_add,read_num,data_add)
uchar part_add;
uchar ram_add;
uchar read_num;
uchar *data_add;
{
uchar i;
i2c_start();
i2c_write_byte(part_add);
i2c_write_byte(ram_add);
i2c_start();
i=part_add|0x01;
i2c_write_byte(i);
for(i=0;i
*(data_add+i)=i2c_read_byte();
if(i!=read_num-1)send_ack();
else send_no_ack();
}
i2c_stop();
}
/*
* 5,函數介紹:EEPROM發送頁寫n個字節從起始到結束
* 輸入參數: part_add:器件地址
ram_add:片內字節地址,
write_num:欲寫個數
data_add:欲寫數據地址
* 輸出參數:
* 返回值:
*/
void eeprom_write_page(part_add,ram_add,write_num,data_add)
uchar part_add;
uchar ram_add;
uchar write_num;
uchar *data_add;
{
uchar i;
bit ack;
i2c_start();
ack=i2c_write_byte(part_add);
if(ack==1)FRONT_LED=0;
i2c_write_byte(ram_add);
REAR_LED=0;
for(i=0;i
i2c_write_byte(*(data_add+i));
delay_ms(1);
}
i2c_stop();
delay_ms(20);
_nop_();
_nop_();
}