老古,我自己重新写了一个程序,我想在地址01处写入03,但是结果却是在地址50H开始处写了01,03,救救我吧,不然我死定了!
#include <reg51.h>
#include <string.h>
#include <intrins.h>
#define uint unsigned int
#define HIGH 1
#define LOW 0
#define FALSE 0
#define TRUE ~FALSE
#define uchar unsigned char
#define WRITE 0xa0
#define READ 0xa1
uchar databuff;
uchar str;
sbit SDA=P1^5;
sbit SCL=P1^4;
sbit bell=P2^5;
sbit led_yellow=P2^2;
sbit led_red=P2^1;
void delay(void);
void I_start(void);
void I_stop(void);
void I_init(void);
bit I_clock(void);
bit I_send(uchar I_data);
uchar I_receive(void);
void I_Ack(void);
bit E_address(uchar Address);
bit E_read_address(uchar Address);
void wait_5ms(void);
bit E_write_address(uchar Address);
void bellx(uchar bell_count);
void delay_us(uint delay_time);
void ddelay(uint delay_time); //延时delay_timeMS
void main(void)
{
bit temp;
databuff=0x03;
str=0;
temp=E_write_address(0x01);
if(temp) bellx(2);
else led_yellow=0;
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
temp=E_read_address(0x01);
if(temp) bellx(3);
else led_red=0;
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
ddelay(100);
if(str==databuff) bellx(5);
else
{
led_red=0;
led_yellow=0;
}
while(1);
}
/*功能:本函数实际上只有一条返回指令,在具体应用中
可视具体要求增加延时指令*/
void delay(void)
{
_nop_();
_nop_();
_nop_();
}
/*功能:提供I2C总线工作时序的起始位。*/
void I_start(void)
{
SCL=HIGH;
delay();
SDA=LOW;
delay();
SCL=LOW;
delay();
}
/*功能:提供I2C总线工作时序的停止位。*/
void I_stop(void)
{
SDA=LOW;
delay();
SCL=HIGH;
delay();
SDA=HIGH;
delay();
SCL=LOW;
delay();
}
/*功能:I2C总线初始化。在MAIN()函数中应首先调用本函数,然后再调用其它函数。*/
void I_init(void)
{
SCL=LOW;
I_stop();
}
/*功能:提供I2C总线的时钟信号,并返回在时钟电平位高期间SDA信号线
上状态。本函数可用于数据发送,也可用于数据接收*/
bit I_clock(void)
{
bit sample;
SCL=HIGH;
delay();
sample=SDA;
SCL=LOW;
delay();return(sample);
}
/*功能:向I2C总线发送8位数据,并请求一个应答信号ACK。如果收到
ACK应答则返回1(TRUE),否则返回0(FALSE)。*/
bit I_send(uchar I_data)
{
register uchar i;
/*发送8位数据*/
for(i=0;i<8;i++)
{
SDA=(bit)(I_data&0x80);
I_data=I_data<<1;
I_clock();
}
SDA=HIGH;
return (~I_clock());
}
/*功能:从I2C总线上接收8位数据信号,并将接收到8位数据作为一个字节
返回,不回送应答信号ACK。主函数在调用本函数之前应保证SDA信号线处于
浮置状态,即使8051的P1.7脚置1。*/
uchar I_receive(void)
{
uchar I_data=0;
register uchar i;
for(i=0;i<8;i++)
{
I_data*=2;
if(I_clock())
I_data++;
}
return(I_data);
}
/*功能:向I2C总线发送一个应答信号ACK,一般用于连续数据读取时。*/
void I_Ack(void)
{
SDA=LOW;
I_clock();
SDA=HIGH;
}
/*功能:向24c01写入器件地址和一个指定的字节地址。*/
bit E_address(uchar Address)
{
I_init();
I_start();
if(I_send(WRITE))
return(I_send(Address));
else
return(FALSE);
}
/*功能:从24c01中读取data_size个字节的数据并存放到databuff里,采用序列读操作方式
从片
内ADDRESS地址处连续读取数据。如果24c01不接收指定的地址在返回0*/
bit E_read_address(uchar Address)
{
I_init(); //从地址0开始读取数据
if(E_address(Address))
{
I_start();
if(I_send(READ))
{
str=(I_receive());
I_clock();
I_stop();
return(TRUE);
}
else
{
I_stop();
return(FALSE);
}
}
else
I_stop();
return(FALSE);
}
/*功能:提供5ms延时(时钟频率12MHZ)*/
void wait_5ms(void)
{
register int i;
for(i=0;i<1000;i++)
;
}
/*功能:将数据缓冲区databuff中的数据写入到24c01的以Address地址开始的data_size个
字节。
采用字节写操作方式,每次写入时都需要指定片内地址。如果24c01不接受指定的地址或某
个传送
的字节未收到应答信号ACK,在返回0(FALSE).*/
bit E_write_address(uchar Address)
{
if(E_address(Address)&&I_send(0x03))
{
I_stop();
wait_5ms();
return(TRUE);
}
else
return(FALSE);
}
void bellx(uchar bell_count)
{
uint count1;
do
{
for(count1=0x019b;count1>0;count1--)
{
bell=0;
delay_us(55);
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
bell=1;
delay_us(55);
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
ddelay(80);
bell_count--;
}
while(bell_count);
return ;
}
void delay_us(uint delay_time)
{
for(;delay_time>0;delay_time--)
{
_nop_();
_nop_();
}
return;
}
void ddelay(uint delay_time) //延时delay_timeMS
{
delay_time*=50;
for(;delay_time>0;delay_time--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
return;
}
发表时间:2001年10月16日15:45:00