temp=RW2401(p2,8,0x01,0xa1);
if(!temp)
{
led_yellow=1;
led_red=0;
}
temp1=strncmp(p1,p2,8);
if(temp1==0)
{
led_yellow=0;
led_red=0;
}
else
{
led_yellow=1;
led_red=1;
}
while(1);
}
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;
}
#include "reg51.h"
#include "intrins.h"
sbit SCL= P1^5;
sbit SDA= P1^4;
delay()
{
unsigned int i=1200;
while(i--);
}
/*----------------------------------------------------------------------------
调用方式:write_8bit(unsigned char ch) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------
*/
void write_8bit(unsigned char ch)
{
unsigned char i=8;
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
while (i--)
{
SDA=(bit)(ch&0x80);
_nop_();_nop_();_nop_();_nop_();_nop_();
ch<<=1;
SCL=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
/*------------------------------------------------------------------------------
调用方式:void ACK(void) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------
*/
void ACK(void)
{
unsigned char time_1;
SDA=1;
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=1;
time_1=5;
while(SDA) {if (!time_1) break;} //ACK
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
unsigned char ReadIIC_24C01(unsigned char address)
{
unsigned char ddata=0;
unsigned char i=8;
SCL=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
SDA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit( (address<<1) | 0x01); //写页地址和操作方式
ACK();
while (i--)
{
SDA=1;
ddata<<=1;
SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;
if (SDA) ddata|=0x01;
}
SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=1; //STOP
delay();
return ddata;
}
void WriteIIC_24C01(unsigned char address,unsigned char ddata)
{
SCL=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
SDA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit( (address<<1) & 0xfe); //写页地址和操作方式,对于24C32-
24C256,page不起作用
ACK();
write_8bit(ddata); //发送数据
ACK();
SDA=0;
_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=1; //STOP
delay();
}
上面这个函数的
while(SDA) {if (!time_1) break;} //ACK
语句好象是死循环啊?
我做了一块板子用P34做SCL,P35做SDA,WP接到P33。可是忘记加上拉电阻了,运行上面的程序,结果在上面提到的while语句卡死了。
我想问一个问题:P3口不是有内部上拉电阻了吗,24C01不接再接上拉电阻行不行啊?
哪位老大来回答一下啊,老板急着催我呢!
晕死了!
这句啥意思啊,我的程序到这里就死循环了啊