掃盲教程:單片機IIC基礎通信

單片機IIC基礎通信

1 接口定義
2 程序實例

閱讀提示:本章主要講解過去電路使用較多的24C02- 24C512存儲器,對於現在 主流的STC15W系列單片機,通常都具有內部比較器與DataFlash存儲器,可 直接代換代換本章各個例程功能(詳見第7章)
1 接口定義

I2C總線是兩線式串行總線(連同GND爲3線),僅需要時鐘和數據兩根線就可 以進行數據傳輸,僅需要佔用單片機的2個IO引腳,使用時十分方便,I2C總線可 以在同一總線上並接多個器件,每個器件都有自己的器件地址(作爲對比:SPI 總線沒有器件地址,通過CPU提供片選線確定是否選中芯片),讀寫操作時需要 先發送器件地址,與該地址相符的器件得到確認後便執行相應的操作,而在同一 總線上的其它器件不做響應,稱之爲器件尋址。

單片機外圍使用I2C接口的器件比較多,最常見的是EEPROM存儲器(如:
24C02)與ADC轉換芯片(如:MCP3421) 。
24C02與單片機的連接電路如下圖所示。
在這裏插入圖片描述
2 程序實例
24C系列芯片既然作爲存儲器使用,我們最關心的就是如何將數據寫入芯片及 寫入成功的數據如何讀取出來。

例6.2 使用IAP15W4K58S4單片機的硬件仿真功能仿真觀察24C02芯片讀寫結果
(也可用24C01/04/08/16) 。本例無頁面限制,快速,適合連續讀寫多個字 節,本程序先向芯片寫入一組數據,然後讀出,若讀出的數據與寫入的數據相同 則表明實驗結果是正確的。

爲了簡化,我們直接移植成熟的程序代碼(配套例程中提供)。
① 除主程序MAIN.C外,其餘*.C與*.H文件全部複製到你自己的文件夾並將*.C文 件加入工程,如圖所示。
在這裏插入圖片描述
② 根據實際硬件連接修改引腳定義。在IIC.H中有如下語句,可設置爲任意IO口,注
意上拉。

sbit SCL=P3^7; // 串行時鐘(代碼包必須)

sbit SDA=P4^1; // 串行數據(代碼包必須)

③ 根據硬件修改從機地址。在24C01_02.H中有:#define SlaveADDR 0xA0 // 從機 地址格式爲:1010 ***0。其中的***對應器件引腳 A2A1A0,,用於設置器件地 址,當硬件上A2A1A0接GND時, ***=000。
④ 在要求嚴格的情況下,根據R/C時鐘頻率修改延時函數參數。myfun.c中的延時函 數delay1ms()和delay10ms()延時參數由第1章介紹的軟件計算得出。

⑤ 根據R/C時鐘頻率修改宏定義。IIC.H中的語句 “#define tt 26”的常數26對應
myfun.c中的延時函數void delay (unsigned char t)中的參數t,此常數值確定
5uS延時時間,延時可以更長,不能短,時鐘頻率爲22.1184MHz時t=26。
⑥ 這裏的例子使用的是24C02芯片,若換用24C04/08/16,爲了提高多字節數據跨頁 寫入速度,則需要對24C01_02.C中函數WrToRomPageB內部常數0x07改爲0x0f。

主程序代碼如下(注意是硬件仿真觀察實驗結果):

#include “STC15W4K.H” // 注意宏定義後面沒分號
#include “24C01_02.H”
#include “myfun.h” void main()
{
u8 i;
u8 test_data[20]={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,
0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x81,0x91,0xa1};
port_mode(); // 所有IO口設爲準雙向弱上拉方式。 WrToRomB(SlaveADDR, 5,test_data,20);
// 器件地址、存儲單元地址、數據指針、寫入字節數
for(i=0;i<20;i++)
{
test_data[ i ]=0;
}
RdFromROM(SlaveADDR, 5,test_data,20); // 連續讀取20個字節數據
while(1);
}
例6.5利用24C02記錄單片機上電次數(使用工作組方式)

頭文件代碼如下:

#define E2P_RECORD_ADDR 0x00 // 存儲單元地址

#define POWER_UP_MARK 0xAB // 第一次使用標記

struct POWER_UP

{
u32 times;

u8 flag;

};
// 主程序代碼如下:

#include “PowerUP.H”

#include “24C01_02.H”

#include “myfun.h”

struct POWER_UP Power_up;
void main()
{

RdFromROM(SlaveADDR,E2P_RECORD_ADDR,(u8*)&Power_up,sizeof(struct POWER_UP));

// 芯片硬件地址、存儲單元地址、數據組、寫入字節數

if (Power_up.flag != POWER_UP_MARK) // 存儲器第一次使用
{

}
else
{

}

Power_up.flag = POWER_UP_MARK; Power_up.times = 1;

Power_up.times++;
WrToRomB(SlaveADDR, E2P_RECORD_ADDR,(u8 *)&Power_up,sizeof(struct POWER_UP));

// 芯片硬件地址、存儲單元地址、數據組、寫入字節數 UART_init(); UART_Send_StrNum(“上電次數:”,Power_up.times);
// 串口輸出上電次數,波特率:9600 /22.1184MHZ
while(1);
}
結果如圖所示。
在這裏插入圖片描述

例6.6 利用24C02斷電瞬間存儲數據。斷電存儲就是在系統斷電瞬間保存RAM中的重要數據 到EEPROM,在下次系統上電時再讀出EEPROM中的數據並運行,斷電檢測電路原理如圖所 示。
在這裏插入圖片描述
利用單片機外中斷檢測交流電源的有無,交流供電正常時INT2每10mS進入一次中斷,在中斷
程序中重裝定時器T1初值讓定時器一直不產生溢出中斷,交流斷電時,定時器計數值不斷增 加直到溢出,溢出中斷程序中單片機立即保存數據到EEPROM 。定時器定時時間要求大於
10mS即可,比如取12或15mS,另外特別注意單片機外中斷引腳必須外接上拉電阻。
對於現在主流的STC15W系列單片機,通常都具有內部比較器與DataFlash存儲器,可直接 代換24C系列存儲器使用,斷電檢測電路更加簡單,如上圖單片機VCC與GND間接2只電阻即可。

發佈了92 篇原創文章 · 獲贊 161 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章