?? at24c512.h
字號:
/*
AT24C512驅動頭文件:
注:本頭文件默認單片機頻率為8M,I2C傳輸速率為400K,如果改變單片機頻率,
需要將i2cdelay()函數 BIT率寄存器TWBR的值進行修改
AT24C512最大傳輸速率:1 MHz (5V), 400 kHz (2.7V), 100 kHz (1.8V)
AT24C512擁有128-byte的頁面緩存空間
AT24C512讀寫安全時間間隔為5 ms
使用此頭文件前,首先必須在main()函數中調用I2cinit()以初始化通信接口
發送:
1.選擇需要寫入的器件號icnumber,范圍1--4,格式:icnumber=1;
(AT24C512允許4片并行使用,空間可以擴展到512*4=1024 BIT位)
2.選擇寫入data首地址,范圍0x0000--0xffff,格式:address=0x0000;
3.輸入需要發送的字節數total,范圍1--128,格式:total=12;
注:前面3步可以直接調用
i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);
4.給發送緩存Send_buffer[]賦值,最多128個8位變量
5.調用Send_i2c_data();函數來完成對data數據的發送
接收:
1.選擇需要讀取的器件號icnumber,范圍1--4,格式:icnumber=1;
2.選擇接收data首地址,范圍0x0000--0xffff,格式:address=0x0000;
3.輸入需要接收的字節數total,范圍1--128,格式:total=12;
注:前面3步可以直接調用
i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);
4.調用Read_i2c_data();函數來完成對data數據的接收,
接收數據將存入Receive_buffer[];
編寫:李科 2006-02-25
修改:李科 2006-10-16 */
/******************************定義變量區**************************************/
char Send_buffer[128]; //(主控mcu/通信模塊中設置的)發送緩沖區
char Load_point=0; //中斷內,發送數據存儲位置
char SendI2c_data=0; //需要發送I2c數據
char newpoint=0; //已經發送個數標志位
char Receive_buffer[128]; //(主控mcu/通信模塊中設置的)接收緩沖區
char Get_point=0; //中斷內,接收數據存儲位置
char ReceiveI2c_data=0; //接收到的I2c數據
char Error_flag=0; //出錯標志位
char icnumber=0; //ic地址號碼A1 A0
unsigned int address=0; //數據儲存地址
unsigned int laddress=0; //數據儲存地址低8位數據
char addresstime=0; //地址高低位發送判斷
char total=0; //需要發送接收的數據數量
char total1=0; //第一次需要發送的數據數量
char total2=0; //第二次需要發送的數據數量
char mt=1; //master 發送接收切換標志
/******************************函數聲明區**************************************/
void twi_isr(void); //判斷TWI狀態子程序
void I2cinit(void); //初始化I2C
void Send_i2c_data(void); //I2C發送函數
void Read_i2c_data(void); //I2C讀取函數
void I2CReset(void); //I2C復位函數
void i2cdelay(char x); //延時間函數
void i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal);//變量賦值
/****************************I2c事件中斷***************************************/
/*為進入主機模式,必須發送START信號。緊接著的地址包格式決定進入MT或MR模式
如果發送 SLA+W 進入MT 模式;如果發送SLA+R 則進入MR 模式。
在MT模式下再次發送START信號,再發送SLA+R可以進入MR模式 */
#pragma interrupt_handler twi_isr:18
void twi_isr(void) //判斷TWI狀態子程序
{
if((TWSR&0xf8)==0x08) //讀取TWI狀態:START已發送
{
TWDR=(0b10100000+icnumber);//主機選擇發送器件號碼
TWCR=0X85;//啟動發送(TWINT置位,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else if((TWSR&0XF8)==0x10)//重復START信號發送,轉換為主機接收模式
{
TWDR=(0b10100001+icnumber); //主機向器件指定器件接收數據;
TWCR=0X85;//啟動發送(TWINT置位,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else if((TWSR&0XF8)==0x18)//讀取TWI狀態:SLA+W 已發送;且接收到ACK
{
newpoint=0; //復位發送個數變量
Error_flag=0; //錯誤標志清0
TWDR=(address>>8); //發送起始地址高8位
addresstime=1; //起始地址高8位已經發送,標志位置1
TWCR=0X85;//啟動發送(TWINT置位,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else if(((TWSR&0XF8)==0x28)&&(addresstime==1))//接收到ACK,發送低8位地址
{
TWDR=address; //發送起始地址低8位
addresstime=0; //起始地址低8位已經發送,標志位清0
TWCR=0X85;//啟動發送(TWINT置位,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else if(((TWSR&0XF8)==0x28)&&(addresstime==0))//讀取TWI狀態:頁地址已發送;接收到ACK;
{
if(mt==1) //主機發送模式
{
SendI2c_data=Send_buffer[Load_point];//載入數據
TWDR=SendI2c_data; //發送數據
if(newpoint<total) //判斷是否已經發送了total個數據
{
newpoint++; //發送個數變量自加1
Load_point++; //儲存空間位置自加1
TWCR=0X85; //啟動發送(TWINT置位,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else
{
Error_flag=0x28; //發送結束標識
TWCR=0X95;//啟動停止位發送(TWINT置1,TWSTO置1,TWI使能標志TWEN置1,中斷允許TWIE置1)
}
}
else if(mt==0) //準備轉換成主機接收模式:發送重復START信號
{
TWCR=0XA5;//重復START信號發送(TWINT置位,START信號發送,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
}
else if((TWSR&0XF8)==0x38)//SLA+W 或數據的仲裁失敗;釋放總線
{
TWCR=0XA5;//TWINT置位,START信號發送,TWI使能標志TWEN置位,中斷允許TWIE置位
}
else if((TWSR&0XF8)==0x40)//進入主機接收模式,清除start標志
{
Get_point=0; //儲存緩沖區指針歸0
TWCR=0xc5;//進行應答(TWINT置1,應答允許,TWI使能標志TWEN置位,中斷允許TWIE置位)
}
else if((TWSR&0XF8)==0x50)//主機接收模式接收數據
{
Error_flag=0x00;
ReceiveI2c_data=TWDR; //賦值接收到的I2c數據
Receive_buffer[Get_point]=ReceiveI2c_data;//將收到的數據存入接收緩存區
Get_point++; //儲存空間位置自加1
if(Get_point<total) //判斷是否已經接收了total個數據
{TWCR=0xc5;}//進行應答(TWINT置位,TWI使能應答,TWI使能標志TWEN置位,中斷允許TWIE置位)
else //已經接收了total個數據
{
Get_point=0; //儲存緩沖區指針歸0
Error_flag=0x50;
TWCR=0x00;//啟動停止位發送(TWINT置0,TWSTO置0,TWI使能標志TWEN置0,中斷允許TWIE置0)
}
}
else //錯誤處理。重新啟動
{
Error_flag=0; //置位錯誤標志
TWCR=0x00; //清0
}
}
/*********************************初始化I2C************************************/
void I2cinit(void)
{
TWCR=0x00;
TWBR=0x02; //設置BIT率400k (單片機晶振為8M)
TWSR=0x00; //設置分頻1
TWAR=0x01; //允許識別TWI 總線廣播(高7位為從機地址)
TWCR=0x45; //TWI使能應答,TWI使能標志TWEN置位,中斷允許TWIE置位
}
/*****************************I2C變量賦值函數**********************************/
void i2control(char i2cicnumber,unsigned int i2caddress,char i2ctotal)
{
icnumber=i2cicnumber;
address=i2caddress;
total=i2ctotal;
laddress=((address<<8)>>8); //將低8位地址賦給laddress
}
/*******************************I2C發送函數************************************/
void Send_i2c_data(void) //I2C發送函數1
{
SEI(); //允許中斷
I2CReset(); //i2c復位
Error_flag=0x00;
Load_point=0; //復位緩存地址
mt=1; //打開MCU發送標志
icnumber--; //IC器件地址校正
icnumber<<=1; //IC器件地址校正
if((laddress+total)>256) //如果發送地址超過了256,則分2次發送
{
total2=(laddress+total)-256;//計算第二次發送的數據個數
total1=total-total2; //計算第一次發送的數據個數
total=total1; //準備第一次發送個數
TWCR=0XA5;//開始發送(TWINT置位,start發送,TWI使能標志TWEN置位,中斷允許TWIE置位)
while(Error_flag!=0x28) //等待發送完成
{;}
i2cdelay(30); //200us X 30
address+=total1; //第二次發送首地址更新
total=total2; //準備第二次發送個數
TWCR=0XA5;//開始發送(TWINT置位,start發送,TWI使能標志TWEN置位,中斷允許TWIE置位)
while(Error_flag!=0x28) //等待發送完成
{;}
i2cdelay(30); //200us X 30
}
else //如果發送地址沒有超過256,則按照常規發送
{
TWCR=0XA5;//開始發送(TWINT置位,start發送,TWI使能標志TWEN置位,中斷允許TWIE置位)
while(Error_flag!=0x28) //等待發送完成
{;}
i2cdelay(30); //200us X 30
}
}
/*************************讀取接收到的I2C數據**********************************/
void Read_i2c_data(void)
{
SEI(); //允許中斷
I2CReset(); //i2c復位
Error_flag=0x00;
mt=0; //打開MCU接收標志
icnumber--; //IC器件地址校正
icnumber<<=1; //IC器件地址校正
TWCR=0XA5;//開始發送(TWINT置位,start發送,TWI使能標志TWEN置位,中斷允許TWIE置位)
while(Error_flag!=0x50) //等待接收完成
{;}
i2cdelay(30);
}
/*************************I2C軟件延時函數**************************************/
void i2cdelay(char x) //200us延時
{
char i=0,j=0;
for(i=0;i<x;i++)
{
for(j=0;j<200;j++)
{;}
}
}
/******************************I2C復位函數*************************************/
void I2CReset(void)
{
TWCR=0x45; //TWI使能應答,TWI使能標志TWEN置位,中斷允許TWIE置位
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -