?? 24c256zhuan.c
字號:
/*
剛剛調(diào)好了個24c256的操作,自己在程序里搞了個連續(xù)讀寫的函數(shù)!很煩那頁寫跨頁的問題,所以干脆做了個通用點的函數(shù),小于3字節(jié)的寫就用隨機寫,大于3字節(jié)的就用頁寫!共享拉!
真正供其他操作調(diào)用的函數(shù)是:
unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf);
其他的都是本文件內(nèi)自己調(diào)用的函數(shù)!! */
//*****************************************************調(diào)試函數(shù)
void DebugEepromService(void)
{
unchar debug_buf[255];
debug_buf[0]=0x91;
debug_buf[1]=0x92;
debug_buf[2]=0x93;
debug_buf[3]=0x94;
debug_buf[4]=0x95;
debug_buf[250]=0x05;
debug_buf[251]=0x06;
debug_buf[252]=0x07;
debug_buf[253]=0x08;
debug_buf[254]=0x09;
SeqWriteTo24c256(EEP1_ADDR,1,255,debug_buf);
SeqReadFrom24c256(EEP1_ADDR,1,255,debug_buf);
}
//*************************************************************
#define IIC_SDA_PB 0x20
#define IIC_SCL_PB 0x80
#define IIC_DEL_WAIT 0x10 //>4.7us(12.80us) for Fre=11.0592M
#define IIC_DEL_WRITE 0x2700 //>6ms(7266.54us=7.266ms) for Fre=11.0592M
#define EEP1_ADDR 0xa4
#define PAGE_CAP_BYTE 64 //24C256頁寫容量:64字節(jié)
/*
功能函數(shù)文件
2005-9-22 9:54 by xth
版本: v1.0
--------------------------------------------
Mcu: avr mega32 Frequency: 11.0592M
--------------------------------------------
功能概述:Eeprom操作文件
--------------------------------------------
*/
//=============================函數(shù)聲明
//----------IIC操作調(diào)用函數(shù)
void IicDelayService(unint delay_time);
void IicStartBitSend(void);
void IicStopBitSend(void);
void IicAckService(unchar ack_data);
unchar IicSendByteService(unchar tx_data);
unchar IicAccByteService(void);
//----------At24c256操作函數(shù)
unchar RandWriteByteTo24c256(unchar sla_add,unint addr_op,unchar data_op);
unchar WritePageTo24c256(unchar sla_add,unint addr_op,unchar *write_data_buf);
unchar SeqWriteTo24c256ByPage(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf);
unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf);
//=============================函數(shù)定義
void IicDelayService(unint delay_count)
{
unint count;
for(count=0;count<delay_count;count++)
asm("NOP");
}
void IicStartBitSend(void)
{
PORTB |= IIC_SCL_PB; //發(fā)送起始條件的時鐘信號
asm("NOP");
PORTB |= IIC_SDA_PB; //起始條件建立時間大于4.7us,延時
IicDelayService(IIC_DEL_WAIT);
PORTB &= ~IIC_SDA_PB;
IicDelayService(IIC_DEL_WAIT);
PORTB &= ~IIC_SCL_PB; //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
asm("NOP");
}
void IicStopBitSend(void)
{
PORTB &= ~IIC_SDA_PB;//發(fā)送結(jié)束條件的時鐘信號
IicDelayService(IIC_DEL_WAIT);
PORTB |= IIC_SCL_PB; //結(jié)束條件建立時間大于4μs
IicDelayService(IIC_DEL_WAIT);
PORTB |= IIC_SDA_PB;
asm("NOP");
}
void IicAckService(unchar ack_data)
{//作為主控器件應(yīng)答->發(fā)應(yīng)答或非應(yīng)答信號
if(ack_data==0) PORTB &= ~IIC_SDA_PB;
else PORTB |= IIC_SDA_PB;
IicDelayService(IIC_DEL_WAIT);
PORTB |= IIC_SCL_PB;
IicDelayService(IIC_DEL_WAIT);
PORTB &= ~IIC_SCL_PB;//清時鐘線,鉗住I2C總線以便繼續(xù)接收
asm("NOP");
}
unchar IicSendByteService(unchar tx_data)
{//將字節(jié)發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答并返回
unchar bit_count,ack_flag;
for(bit_count=0;bit_count<8;bit_count++)
{
if((tx_data<<bit_count)&0x80)
PORTB |= IIC_SDA_PB;
else
PORTB &= ~IIC_SDA_PB;
IicDelayService(IIC_DEL_WAIT);
PORTB |= IIC_SCL_PB; //置時鐘線為高,通知被控器開始接收數(shù)據(jù)位
IicDelayService(IIC_DEL_WAIT); //保證時鐘高電平周期大于4μs
PORTB &= ~IIC_SCL_PB;
}
IicDelayService(IIC_DEL_WAIT);
PORTB &= ~IIC_SDA_PB;
DDRB &= ~IIC_SDA_PB; //SDA置成輸入
asm("NOP");
PORTB |= IIC_SCL_PB;
IicDelayService(IIC_DEL_WAIT);
IicDelayService(IIC_DEL_WAIT);
if(PINB&IIC_SDA_PB) //判斷是否接收到應(yīng)答信號
ack_flag=NO;
else
ack_flag=YES; //有應(yīng)答信號
DDRB |= IIC_SDA_PB;
PORTB &= ~IIC_SCL_PB;
asm("NOP");
return(ack_flag);
}
unchar IicAccByteService(void)
{//接收從器件傳來的數(shù)據(jù),并判斷總線錯誤
unchar bit_count,get_data;
DDRB &= ~IIC_SDA_PB;
get_data=0;
for(bit_count=0;bit_count<8;bit_count++)
{
asm("NOP");
PORTB &= ~IIC_SCL_PB; //置時鐘線為低,準(zhǔn)備接收數(shù)據(jù)位
IicDelayService(IIC_DEL_WAIT); //時鐘低電平周期大于4.7μs;
PORTB |= IIC_SCL_PB; //置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
get_data<<=1;
if(PINB&IIC_SDA_PB)
get_data++;
asm("NOP");
asm("NOP");
}
PORTB &= ~IIC_SCL_PB;
DDRB |= IIC_SDA_PB;
asm("NOP");
return(get_data);
}
unchar RandWriteByteTo24c256(unchar sla_add,unint addr_op,unchar data_op)
{
unchar result_now,temp_data;
IicStartBitSend(); //起始條件
temp_data=sla_add; //從器件地址
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op>>8; //操作單元地址高8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op; //操作單元地址低8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=data_op; //操作數(shù)據(jù)
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
IicStopBitSend(); //停止條件
IicDelayService(IIC_DEL_WRITE);
result_now=YES;
return(result_now);
}
unchar SeqReadFrom24c256(unchar sla_add,unint addr_op,unchar read_size,unchar *read_buf)
{//addr “roll over” during read:from last byte of the last page, to the first byte of the first page
unchar result_now,temp_data,read_count;
IicStartBitSend(); //起始條件
temp_data=sla_add; //從器件地址
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op>>8; //操作單元地址高8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op; //操作單元地址低8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
IicStartBitSend();
temp_data=sla_add+1; //讀操作
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
for(read_count=0;read_count<read_size-1;read_count++)
{ //連續(xù)讀數(shù)據(jù)
*(read_buf+read_count)=IicAccByteService();
IicAckService(NO);
}
*(read_buf+read_count)=IicAccByteService();
IicAckService(YES);
IicStopBitSend();
result_now=YES;
return(result_now);
}
unchar WritePageTo24c256(unchar sla_add,unint addr_op,unchar *write_data_buf)
{//頁寫
unchar count,result_now,temp_data;
IicStartBitSend(); //起始條件
temp_data=sla_add; //從器件地址
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op>>8; //操作單元地址高8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
temp_data=addr_op; //操作單元地址低8位
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
for(count=0;count<PAGE_CAP_BYTE;count++)
{//連續(xù)寫
temp_data=*(write_data_buf+count);
result_now=IicSendByteService(temp_data);
if(result_now==NO) return(result_now);
}
IicStopBitSend(); //停止條件
IicDelayService(IIC_DEL_WRITE);
result_now=YES;
return(result_now);
}
unchar SeqWriteTo24c256ByPage(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf)
{//addr “roll over” during write:from last byte of the current page to first byte of the same page.
unint page_write,read_addr,temp_op_int;
unchar data_count,result_out,modify_count,count,write_data_buf[PAGE_CAP_BYTE];
result_out=YES;
data_count=0;
while(write_size>0)
{
page_write=addr_op/PAGE_CAP_BYTE; //得到當(dāng)前頁
read_addr=page_write*PAGE_CAP_BYTE;
SeqReadFrom24c256(sla_add,read_addr,PAGE_CAP_BYTE,write_data_buf);
temp_op_int=addr_op&(PAGE_CAP_BYTE-1); //得到在頁內(nèi)的起始字節(jié)地址
if(temp_op_int+write_size>=PAGE_CAP_BYTE)
{
modify_count=PAGE_CAP_BYTE;
addr_op=(page_write+1)*PAGE_CAP_BYTE; //寫下一頁的起始地址
}
else
modify_count=write_size;
count=temp_op_int;
write_size=write_size-modify_count+count; //寫下一頁的數(shù)據(jù)量
for(;count<modify_count;count++,data_count++)
write_data_buf[count]=*(write_buf+data_count);
result_out=WritePageTo24c256(sla_add,read_addr,write_data_buf);
}
return(result_out);
}
unchar SeqWriteTo24c256(unchar sla_add,unint addr_op,unchar write_size,unchar *write_buf)
{//連續(xù)寫(非頁寫)
unchar write_result;
if(write_size<3)
{//如果要寫入的數(shù)據(jù)小于3個,則用隨機寫實現(xiàn)
write_result=RandWriteByteTo24c256(sla_add,addr_op,*write_buf);
write_result=RandWriteByteTo24c256(sla_add,addr_op+1,*(write_buf+1));
}
else
write_result=SeqWriteTo24c256ByPage(sla_add,addr_op,write_size,write_buf);
return(write_result);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -