×
单片机 > 单片机程序设计 > 详情

单片机读写24C01的C51程序

发布时间:2020-06-10 发布时间:
|
/*--------------------------24C01的IIC 读写的c51程序--------------------- 

程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。 
Atmel 24C01 比较特殊,为简约型. 
51晶振为11.0592MHz 
---------------------------------------------------------------*/ 
#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(); 
}


2.这是一个读写24C系列EEPROM的程序,已经经过本人亲自测试,通过!!!!!

//************************************* 
//** M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256 
//** 21c01,24c02:1010A2A1A0R/W; 24C04:1010A2A1P0R/W; 24C08:1010A2P1P0R/W 
//** 24C16:1010P2P1P0R/W; //** 以上6种芯片的读写格式为:start-device addr-ack-first word addr-ack-second word addr-ack-data-ack-stop 
//** 进行读写的字节数,EEPROM首址,EEPROM控制字节, 
//** 以及EEPROM类型。此程序结构性良好,具有极好的容错性,程序机器码也不多:  
//** 以上5种芯片的读写格式为:start-device addr-ack-word addr-ack-data-ack-stop  
//** 24c32-24c512:1010A2A1A0R/W; 24C1024:1010A2A1P0R/W; 24c1024:1010A2A1P0R/W //** 通用的24C01-24C1024共11种EEPROM的字节读写操作程序, 

//**************************24C01读写的c51源程序*********************************** 
#i nclude  
#i nclude  
#i nclude  
#i nclude 

sbit SDA =P1^1; 
sbit SCL =P1^4; 
sbit WP =P1^7; 
sbit light =P1^0; 
sbit power =P1^6;

#define uchar unsigned char 
#define uint unsigned int

void iic_delay10ms(); 
void iic_delay(void); 
void iic_start(void); 
void iic_stop(void); 
void iic_ack(void); 
void read_byte(void); 
void send_byte(void); 
void initial(void); 
void ok(void); 
void error(void); 
void read_eeprom(void); 
void write_eeprom(void); 
void init(void);

uchar ack_flag,send_data,receive_data[32];  
uchar rw,type,device_addr,addr[3],num;

void main(void) 
{  
initial();  
power =0; 
light =0;

while(1) 
{  
ES =1; 
rw =0x55; 
WP =0; 
while(rw ==0x55); 
ES =0; 
switch(type) 

case 0x01: 
case 0x02: 
case 0x04: 
case 0x08: 
case 0x16:  
type =0x02; 
addr[1] |=0xa0; 
device_addr <<=1; 
addr[1] |=device_addr; 
break; 
default: 
type =0x03; 
addr[2] |=0xa0;  
device_addr <<=1; 
addr[2] |=device_addr;  
}  
if(rw ==0x01) //读EEPROM 

read_eeprom(); 

else if(rw ==0x00) //写EEPROM 

write_eeprom(); 

else //error command 
{  
error();  
ACC =0x01; 
SBUF =ACC; 
while(!TI); 
TI =0;  
}  

}

void read_eeprom(void) 

uchar i; 
WP =1; 
iic_start(); 
for(i=1;i<=type;i++) 

send_data =addr[type-i]; 
send_byte(); 
iic_ack(); 
if(ack_flag ==0x01) 
break; 

if(ack_flag ==0x00) 
{  
iic_start(); 
addr[type-1] |=0x01; 
send_data =addr[type-1]; 
send_byte(); 
iic_ack(); 
if(ack_flag ==0x00) 
{  
for(i=0;i { 
read_byte(); 
SBUF =send_data; 
while(!TI); 
TI =0; 
SDA =0; 
SCL =1; 
iic_delay(); 
SCL =0; 

iic_stop(); 
rw =0x55; 

else 

error(); 
ACC =0x03; 
SBUF =ACC; 
while(!TI); 
TI =0; 


else 
{  
error();  
ACC =0x02; 
SBUF =ACC; 
while(!TI); 
TI =0;  

}

//如果你对本程序或者24C01读写还有什么疑问,欢迎到的论坛去交流。

void write_eeprom(void) 

uchar i;  
WP =0; 
iic_start(); 
for(i=1;i<=type;i++) 

send_data =addr[type-i]; 
send_byte(); 
iic_ack(); 
if(ack_flag ==0x01) 
break; 

if(ack_flag ==0x00) 

for(i=0;i { 
send_data =receive_data[i]; 
send_byte(); 
iic_ack(); 
iic_delay10ms();  

iic_stop(); 
rw =0x55; 

else 

error(); 
ACC =0x04; 
SBUF =ACC; 
while(!TI); 
TI =0; 

}


void read_byte(void) 

uchar i,temp=0x80; 
send_data =0x00; 
SCL =0; 
for(i=0;i<8;i++) 
{  
SDA =1; 
SCL =1; 
if(SDA) 
send_data |=temp; 
temp/=2;  
SCL =0; 
iic_delay(); 
}  
}

void send_byte(void) 

uchar i,temp=0x80; 
for(i=0;i<8;i++) 

if((send_data&temp)==temp) 

SDA =1; //sda=1 

else 

SDA =0; //sda=0 

temp /=2; 
iic_delay(); 
SCL =1; 
iic_delay(); 
SCL =0; 
iic_delay(); 

}

void iic_start(void) 

SDA =1; 
SCL =1; 
WP =0; 
iic_delay(); 
SDA =0; 
iic_delay(); 
SCL =0; 
}

void iic_stop(void) 

SDA =0; 
SCL =1; 
iic_delay(); 
SDA =1; 
//WP =1; 
}

void iic_ack(void) 

ack_flag =0x00; //ack_flag等于0x00时有应答 
SDA =1;  
iic_delay(); 
SCL =1; 
iic_delay(); 
if(SDA) 

ack_flag =0x01; 

SCL =0; 
}

void iic_delay(void) 
{  
_nop_(); 
_nop_(); 
_nop_(); 
_nop_(); 
}

void iic_delay10ms(void) 

#pragma ASM 
MOV r6,#200 
MOV r7,#10 
delay: 
nop 
nop 
nop 
djnz r6,delay 
MOV r6,#200 
djnz r7,delay 
#pragma ENDASM  
}

void initial(void) 
{  
TMOD =0x21; 
TH1 =0xfd; 
TL1 =0xfd; 
TH0 =0xfd; 
TL0 =0xfd; 
SCON =0x50; 
TR1 =1; 
EA =1; 
ES =1; 
ET0 =1;  
PT0 =1; 
}

void ok(void) 

ACC =0x55; 
SBUF =ACC; 
while(!TI); 
TI =0; 
ACC =0xaa; 
SBUF =ACC; 
while(!TI); 
TI =0;  
}

void error(void) 

ACC =0xaa; 
SBUF =ACC; 
while(!TI); 
TI =0; 
ACC =0x55; 
SBUF =ACC; 
while(!TI); 
TI =0; 
rw =0x55;  

void es_int(void)interrupt 4 
{  
uchar i; 
RI =0; 
type =SBUF; //型号 
while(!RI); 
RI =0; 
device_addr =SBUF; //器件地址 
for(i=0;i<3;i++) 

while(!RI); 
RI =0; 
addr[2-i] =SBUF; //地址高、中、低位字节 
}  
while(!RI); 
RI =0; 
num =SBUF; //要操作的字节数 
while(!RI); 
RI =0; 
rw =SBUF; 
if(rw ==1) //接收到要读的命令 

ok(); 

else //接收到要写的命令 
{  
for(i=0;i { 
while(!RI); 
RI =0; 
receive_data[i]=SBUF; 
}  
ok(); 

//else 
//{ 
// error(); 
//}  
}

关键字:单片机  读写24C01  C51程序

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计