藍橋杯嵌入式——i2c
作者:張阿永 QQ:793805481
藍橋杯板子上有一個AT24C02芯片,是以IIC接口的EEPROM器件。EEPROM即電可擦除可編程只讀存儲器,是ROM的一種。它是隻讀存儲器,即掉電可繼續存儲數據,而同時又可以在高於普通電壓的作用下擦除和重寫,這就大大方便了單片機對其的開發,現在電腦上的ROM很多都是用的EEPROM。AT24C02的存儲容量爲2K bit,內容分成32頁,每頁8Byte,共256Byte,操作時有兩種尋址方式:芯片尋址和片內子地址尋址。我們不再過多的介紹,下面直接就介紹關於EEPROM的使用。
在比賽中,我們最常用的就是對EEPROM進行讀寫操作。首先,我們把賽點資源包裏邊的底層驅動參考代碼複製粘貼到我們的USER子目錄下,然後添加進工程。
賽點資源包提供的底層驅動代碼裏邊已經編寫了基本的初始化操作等函數,我們只需要再編寫一個讀和寫函數即可滿足基本使用。
void i2c_write(u8 add,u8 data)//寫 參數爲地址和要寫入的數據
{
I2CStart();//i2c.c裏邊已經定義 可以找到
I2CSendByte(0xa0);//i2c.c裏邊已經定義 可以找到
I2CWaitAck();//i2c.c裏邊已經定義 可以找到
I2CSendByte(add);//給地址
I2CWaitAck();
I2CSendByte(data);//給數據
I2CWaitAck();
I2CStop();//i2c.c裏邊已經定義 可以找到
}
向EEPROM裏邊寫入數據時,需要提供8位地址(如0x10)和8位數據(即傳入數據最大值爲:255),即每個地址對應一個8位的數據。
至於讀取函數,直接給入地址,即可返回該地址對應的數據。
u8 i2c_read(u8 add)//讀取函數
{
u8 temp;
I2CStart();
I2CSendByte(0xa0);//寫
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);//讀
I2CWaitAck();
temp=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return temp;
}
關於這兩個函數,需要理解記憶一下。如想更深的瞭解,需要弄清楚EEPROM的工作原理。下面,我們舉個例子來學習使用它。
實現:每次開機從地址處0x10讀取數據,按下B1後再將改變後的值寫回EEPROM。
//主函數
u8 temp=0;
int main(void)
{
……
i2c_init();
temp=i2c_Read(0x10);//開機後讀
while(1)
{
……//temp 在程序執行的過程中值可能會改變
}
}
//按鍵
……
static u16 key1_sum=0,key2_sum=0,key3_sum=0,key4_sum=0;
if(B1==0)//按下時 0
{
key1_sum++;
if(key1_sum==1) //短按有效
{
i2c_Write(0x10,temp);//按鍵按下後,再把temp的值寫入EEPROM
}
}
else { key1_sum=0; }
補充:
由於EEPROM每個地址處能存的數據最大爲255,所以當要存入是值大於255時,我們一般對要存入的數據進行處理後分別存放在幾個地址中。 當然,我們也可以直接通過編寫程序實現讀寫一個u32類型的數據,代碼如下:
void i2c_Write32(u8 add, int data)
{
//8位8位的寫入
i2c_Write(add,(u8)(data&0xff));//頭八位
Delay_Ms(2);
i2c_Write(add+1,(u8)(data>>8&0xff));//右移8位後保留最後8位
Delay_Ms(2);
i2c_Write(add+2,(u8)(data>>16&0xff));
Delay_Ms(2);
i2c_Write(add+3,(u8)(data>>24&0xff));
Delay_Ms(2);
}
int i2c_read32(u8 add)
{
int data;
data=(int)i2c_Read(add);
Delay_Ms(2);
data+=(int)i2c_Read(add+1)<<8;//左移8位後與前8位相加
Delay_Ms(2);
data+=(int)i2c_Read(add+2)<<16;
Delay_Ms(2);
data+=(int)i2c_Read(add+3)<<24;
Delay_Ms(2);
return data;
}