www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]上一節(jié)介紹的是 I2C 每一位信號(hào)的時(shí)序流程,而 I2C 通信在字節(jié)級(jí)的傳輸中,也有固定的時(shí)序要求。I2C 通信的起始信號(hào)(Start)后,首先要發(fā)送一個(gè)從機(jī)的地址,這個(gè)地址一共有 7位,緊跟著的第 8 位是數(shù)據(jù)方向位(R/W),“

上一節(jié)介紹的是 I2C 每一位信號(hào)的時(shí)序流程,而 I2C 通信在字節(jié)級(jí)的傳輸中,也有固定的時(shí)序要求。I2C 通信的起始信號(hào)(Start)后,首先要發(fā)送一個(gè)從機(jī)的地址,這個(gè)地址一共有 7位,緊跟著的第 8 位是數(shù)據(jù)方向位(R/W),“0”表示接下來(lái)要發(fā)送數(shù)據(jù)(寫(xiě)),‘“1”表示接下來(lái)是請(qǐng)求數(shù)據(jù)(讀)。

我們知道,打電話的時(shí)候,當(dāng)撥通電話,接聽(tīng)方撿起電話肯定要回一個(gè)“喂”,這就是告訴撥電話的人,這邊有人了。同理,這個(gè)第九位 ACK 實(shí)際上起到的就是這樣一個(gè)作用。當(dāng)我們發(fā)送完了這 7 位地址和 1 位方向后,如果發(fā)送的這個(gè)地址確實(shí)存在,那么這個(gè)地址的器件應(yīng)該回應(yīng)一個(gè) ACK(拉低 SDA 即輸出“0”),如果不存在,就沒(méi)“人”回應(yīng) ACK(SDA將保持高電平即“1”)。

那我們寫(xiě)一個(gè)簡(jiǎn)單的程序,訪問(wèn)一下我們板子上的 EEPROM 的地址,另外再寫(xiě)一個(gè)不存在的地址,看看它們是否能回一個(gè) ACK,來(lái)了解和確認(rèn)一下這個(gè)問(wèn)題。

我們板子上的 EEPROM 器件型號(hào)是 24C02,在 24C02 的數(shù)據(jù)手冊(cè) 3.6 節(jié)中可查到,24C02的 7 位地址中,其中高 4 位是固定的 0b1010,而低 3 位的地址取決于具體電路的設(shè)計(jì),由芯片上的 A2、A1、A0 這 3 個(gè)引腳的實(shí)際電平?jīng)Q定,來(lái)看一下我們的 24C02 的電路圖,它和24C01 的原理圖完全一樣,如圖 14-4 所示。


圖 14-4 24C02 原理圖


從圖 14-4 可以看出來(lái),我們的 A2、A1、A0 都是接的 GND,也就是說(shuō)都是 0,因此 24C02的 7 位地址實(shí)際上是二進(jìn)制的 0b1010000,也就是 0x50。我們用 I2C 的協(xié)議來(lái)尋址 0x50,另外再尋址一個(gè)不存在的地址 0x62,尋址完畢后,把返回的 ACK 顯示到我們的 1602 液晶上,大家對(duì)比一下。


/***************************Lcd1602.c 文件程序源代碼*****************************/

#include

#define LCD1602_DB P0

sbit LCD1602_RS = P1^0;

sbit LCD1602_RW = P1^1;

sbit LCD1602_E = P1^5;

/* 等待液晶準(zhǔn)備好 */

void LcdWaitReady(){

unsigned char sta;

LCD1602_DB = 0xFF;

LCD1602_RS = 0;

LCD1602_RW = 1;

do {

LCD1602_E = 1;

sta = LCD1602_DB; //讀取狀態(tài)字

LCD1602_E = 0;

} while (sta & 0x80); //bit7 等于 1 表示液晶正忙,重復(fù)檢測(cè)直到其等于 0 為止

}

/* 向 LCD1602 液晶寫(xiě)入一字節(jié)命令,cmd-待寫(xiě)入命令值 */

void LcdWriteCmd(unsigned char cmd){

LcdWaitReady();

LCD1602_RS = 0;

LCD1602_RW = 0;

LCD1602_DB = cmd;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 向 LCD1602 液晶寫(xiě)入一字節(jié)數(shù)據(jù),dat-待寫(xiě)入數(shù)據(jù)值 */

void LcdWriteDat(unsigned char dat){

LcdWaitReady();

LCD1602_RS = 1;

LCD1602_RW = 0;

LCD1602_DB = dat;

LCD1602_E = 1;

LCD1602_E = 0;

}

/* 設(shè)置顯示 RAM 起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */

void LcdSetCursor(unsigned char x, unsigned char y){

unsigned char addr;

if (y == 0){ //由輸入的屏幕坐標(biāo)計(jì)算顯示 RAM 的地址

addr = 0x00 + x; //第一行字符地址從 0x00 起始

}else{

addr = 0x40 + x; //第二行字符地址從 0x40 起始

}

LcdWriteCmd(addr | 0x80); //設(shè)置 RAM 地址

}

/* 在液晶上顯示字符串,(x,y)-對(duì)應(yīng)屏幕上的起始坐標(biāo),str-字符串指針 */

void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str){

LcdSetCursor(x, y);//設(shè)置起始地址

while (*str != '