一个24c01/02的c51语言驱动程序
#include <reg51.h>
#include <intrins.h>
#include <51port.c>
#define uchar unsigned char
#define uint unsigned int
sbit p3_4=0xb4;
sbit p3_5=0xb5;
#define sda p34
#define scl p35
/*ganerater start status*/
void iic_start(void){
sda=1;
scl=1;
_nop_();_nop_();
sda=0;
_nop_();_nop_();
scl=0;
_nop_();
}
/*ganerater stop status*/
void iic_stop(void){
scl=0;
sda=0;
_nop_();_nop_();
scl=1;
_nop_();_nop_();
sda=1;
_nop_();
}
/*chack no ack*/
void iic_send_noack(void){
sda=1;
_nop_();
scl=1;
_nop_();_nop_();
scl=0;
_nop_();
}
/*send ack*/
void iic_send_ack(void){
sda=0;
_nop_();
scl=1;
_nop_();_nop_();
scl=0;
_nop_();
sda=1;
}
/*ack check*/
bit iic_check_ack(void){
bit flag=0;
sda=1;
_nop_();_nop_();
scl=1;
_nop_();_nop_();
_nop_();_nop_();
if(sda==0)
flag=1;
else
flag=0;
scl=0;
_nop_();
return flag;
}
/*byte send*/
void iic_byte_out(uchar trans){
uchar i=8,j=0;
j=trans;
while(i--){
scl=0;
if(((j&0x80)!=0))
sda=1;
else
sda=0;
j=j < <1;
scl=1;
_nop_();_nop_();
}
scl=0;
_nop_();
sda=1;
}
/*byte recev*/
uchar iic_byte_in(void){
uchar i=8,buff;
while(i--){
sda=1;
buff=buff < <1;
scl=1;
_nop_();_nop_();
if(sda)
buff++;
scl=0;
_nop_();_nop_();
}
return buff;
}
/*waiting for device write cycle*/
bit waiting_w(uchar addr){
uchar comm=0xa0,i;
uchar delay_coun=100;
bit flag=0;
addr=(addr < <1)&0x0f;
comm|=addr;
for(i=0; i <delay_coun; i++){
iic_start();
iic_byte_out(comm);
if(iic_check_ack()){
flag=1;
break;
}
}
iic_stop();
return flag;
}
/*multibytes write*/
/*the slav is device address,stor_add is eeprom internal storage add-
ress, *p is first address with will transfar data block,and num is tr-
ansfar data bytes counter.*/
bit iic_block_w(uchar slav, uchar stor_add, uchar *p, uchar num){
uchar page_coun=0, commen=0xa0;
uchar page_length=8;
bit flag=1;
commen|=((slav < <1)&0x0e);
if(num <=8){
page_coun=1;
page_length=num;
num=0;
}
else if((num%8)==0){
page_coun=num/8;
page_length=8;
num=0;
}
else{
page_coun=num/8;
page_length=8;
num%=8;
}
while(page_coun--){
iic_start();
iic_byte_out(commen);
if(iic_check_ack()){
iic_byte_out(stor_add);
if(iic_check_ack()){
while(page_length--){
iic_byte_out(*p);
p++;
if(!(iic_check_ack())){
flag=0;
break;
}
}
if(!flag)
break;
}
}
iic_stop();
if((page_coun==0)&&(num!=0)){
page_coun++;
page_length=num;
num=0;
}
else
page_length=8;
stor_add+=8;
if(!(waiting_w(slav))){
flag=0;
break;
}
}
iic_stop();
return flag;
}
/*many bytes read*/
bit iic_block_r(uchar slav, uchar stor_add, uchar *p, uchar num){
uchar commen=0xa0,i;
bit flag=1;
commen|=((slav < <1)&0x0e);
iic_start();
iic_byte_out(commen);
if(iic_check_ack()){
iic_byte_out(stor_add);
if(iic_check_ack()){
commen|=0x01;
iic_start();
iic_byte_out(commen);
if(iic_check_ack()){
for(i=0; i <(num-1); i++){
*p=iic_byte_in();
iic_send_ack();
p++;
}
*p=iic_byte_in();
iic_send_noack();
iic_stop();
}
else
flag=0;
}
else
flag=0;
}
else
flag=0;
return flag;
}
多字节写函数采用了任意字节page write方式,所以多字节写函数长一点。
实际上只要slav参数可携带24c04/08/16的a8,a9,a10位信息,即可对24c04/08/16读写。本人有著作权,请勿转载。
发表时间:2003年7月28日15:48:08