小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

PIC單片機(jī)之I2C總線

 共同成長(zhǎng)888 2020-06-24

大家好,通過(guò)前一期的學(xué)習(xí),我們已經(jīng)對(duì)ICD2 仿真燒寫(xiě)器和增強(qiáng)型PIC 實(shí)驗(yàn)板的使用方法及學(xué)習(xí)方式有所了解與熟悉,學(xué)會(huì)了如何用單片機(jī)來(lái)控制發(fā)光管、繼電器、蜂鳴器、按鍵、數(shù)碼管、RS232 串口、步進(jìn)電機(jī)、溫度傳感器等資源,體會(huì)到了學(xué)習(xí)板的易用性與易學(xué)性,看了前幾期實(shí)例,當(dāng)你實(shí)驗(yàn)成功后一定很興奮,很有成就感吧!現(xiàn)在我們就趁熱打鐵,再向上跨一步,一起來(lái)學(xué)習(xí)一下I2C 總線的工作原理及使用方法,這樣我們可以將一些我們要保存的數(shù)據(jù)存儲(chǔ)到I2C總線的非易失存儲(chǔ)器中,實(shí)現(xiàn)斷電保持的功能,比如:你設(shè)置了一個(gè)密碼,但不至于這個(gè)設(shè)備斷過(guò)電以后就要重新設(shè)置過(guò),我們可以將密碼數(shù)據(jù)寫(xiě)在非易失存儲(chǔ)器里面,還有如汽車(chē)的量程表的讀數(shù)是不斷累計(jì)的,可以通過(guò)不斷訪問(wèn)I2C 存儲(chǔ)器實(shí)現(xiàn)。

一、I2C總線特點(diǎn)

I2C 總線是主從結(jié)構(gòu),單片機(jī)是主器件,存儲(chǔ)器是從器件。一條總線可以帶多個(gè)從器件( 也可以有多主結(jié)構(gòu)),I2C 總線的SDA 和SCL 是雙向的,開(kāi)路門(mén)結(jié)構(gòu),通過(guò)上拉電阻接正電源。進(jìn)行數(shù)據(jù)傳輸時(shí),SDA 線上的數(shù)據(jù)必須在時(shí)鐘的高電平周期保持穩(wěn)定。數(shù)據(jù)線的高或低電平狀態(tài)只有在SCL 線的時(shí)鐘信號(hào)是低電平時(shí)才能改變,如圖1 所示。

圖1 數(shù)據(jù)位的有效性規(guī)定

圖1 數(shù)據(jù)位的有效性規(guī)定

在SCL 線是高電平時(shí),SDA 線從高電平向低電平切換表示起始條件;當(dāng)SCL 是高電平時(shí)SDA 線由低電平向高電平切換表示停止條件如圖2 所示。

圖2 起始和停止信號(hào)

圖2 起始和停止信號(hào)

發(fā)送到SDA 線上的每個(gè)字節(jié)必須為8 位。

可以由高位到低位傳輸多個(gè)字節(jié)。每個(gè)字節(jié)后必須跟一個(gè)響應(yīng)位(ACK)。響應(yīng)時(shí)鐘脈沖由主機(jī)產(chǎn)生。主機(jī)釋放SDA 線從機(jī)將SDA 線拉低,并在時(shí)鐘脈沖的高電平期間保持穩(wěn)定。如圖3 示。當(dāng)主機(jī)接受數(shù)據(jù)時(shí),它收到最后一個(gè)數(shù)據(jù)字節(jié)后,必須向從機(jī)發(fā)出一個(gè)結(jié)束傳送的信號(hào)。這個(gè)信號(hào)是由主機(jī)對(duì)從機(jī)的“非應(yīng)答”來(lái)實(shí)現(xiàn)的。然后,從機(jī)釋放SDA 線,以允許主機(jī)產(chǎn)生終止或重復(fù)起始信號(hào)。

圖3 字節(jié)格式與應(yīng)答

圖3 字節(jié)格式與應(yīng)答

二、數(shù)據(jù)幀格式

(1)主機(jī)向從機(jī)發(fā)送數(shù)據(jù),數(shù)據(jù)的傳送方向在傳輸過(guò)程中不改變,如圖4 所示。

圖4 主機(jī)向從機(jī)發(fā)送數(shù)據(jù)

圖4 主機(jī)向從機(jī)發(fā)送數(shù)據(jù)

注:陰影部分:表示主機(jī)向從機(jī)發(fā)送數(shù)據(jù);無(wú)陰影部分:表示主機(jī)向從機(jī)讀取數(shù)據(jù)。

A:表示應(yīng)答;:表示非應(yīng)答。S:起始信號(hào);P :終止信號(hào)。

(2)主機(jī)在第一個(gè)字節(jié)后,立即向從機(jī)讀取數(shù)據(jù),如圖5 所示。

圖5 主機(jī)在第一個(gè)字節(jié)后立即讀從機(jī)

圖5 主機(jī)在第一個(gè)字節(jié)后立即讀從機(jī)

(3)復(fù)合格式,如圖6 所示。傳輸改變方向的時(shí)候,起始條件和從機(jī)地址都會(huì)被重復(fù),但R/ W-位取反。如果主機(jī)接收器發(fā)送一個(gè)停止或重復(fù)起始信號(hào),它之前應(yīng)該發(fā)送了一個(gè)不響應(yīng)信號(hào)()。

圖6 復(fù)合格式

圖6 復(fù)合格式

由以上格式可見(jiàn),無(wú)論哪種傳輸方式,起始信號(hào)、終止信號(hào)和地址均由主機(jī)發(fā)出(圖中陰影部分),數(shù)據(jù)字節(jié)的傳送方向則由尋址字節(jié)中的方向位規(guī)定,每個(gè)字節(jié)的傳送都必須有應(yīng)答位(A 或)。

下面通過(guò)24C02 實(shí)例在增強(qiáng)型PIC 實(shí)驗(yàn)板上編程,其硬件原理圖如圖7 所示,U7 為實(shí)驗(yàn)板上24C02 芯片,SDA 與單片機(jī)的RB5 口相連,SCL 與單片機(jī)RB4 相連,七段數(shù)碼管D5、D7、D8 組成了顯示單元,字形碼的數(shù)據(jù)通過(guò)RC 口送入,各數(shù)碼管的顯示片選信號(hào)分別不同的RA 口進(jìn)行控制。

圖7 讀/ 寫(xiě)AT24C 系列存儲(chǔ)器原理圖

圖7 讀/ 寫(xiě)AT24C 系列存儲(chǔ)器原理圖

在MPLab IDE 軟件中新建工程,加入源程序代碼,同時(shí)進(jìn)行芯片型號(hào)的選擇和配置位的設(shè)置,我們實(shí)驗(yàn)所用的芯片型號(hào)為PIC16F877A。

編寫(xiě)的程序代碼如下,其中程序流程圖如圖8 所示。

三、軟件流程圖

圖8 I2C 總線讀/ 寫(xiě)數(shù)據(jù)流程圖

圖8 I2C 總線讀/ 寫(xiě)數(shù)據(jù)流程圖

四、軟件代碼

/**********/

/* 目標(biāo)器件:PIC16F877A */

/* 晶振:4.0MHZ */

/* 編譯環(huán)境:MPLAB V7.51 */

/**********/

/**********

包含頭文件

**********/

#include

/**********

數(shù)據(jù)定義

**********/

#define address 0xa

#define nop() asm("nop")

#define OP_READ 0xa1

// 器件地址以及讀取操作

#define OP_WRITE 0xa0

// 器件地址以及寫(xiě)入操作

/**********

端口定義

**********/

#define SCL RB4

#define SDA RB5

#define SCLIO TRISB4

#define SDAIO TRISB5

/**********

共陰LED 段碼表

**********/

const char table[]={0xC0,0xF9,0xA4,0x

B0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x

83,0xC6,0xA1,0x86,0x8E};

/**********

函數(shù)功能: 延時(shí)子程序

**********/

void delay()

{

int i;

for(i=0;i<100;i++)

{;}

}

/**********

函數(shù)功能: 開(kāi)始信號(hào)

**********/

void start()

{

SDA=1;

nop();

SCL=1;

nop();nop();nop();nop();nop();

SDA=0;

nop();nop();nop();nop();nop();

SCL=0;

nop();nop();

}

/**********

函數(shù)功能: 停止信號(hào)

**********/

void stop()

{

SDA=0;

nop();

SCL=1;

nop();nop();nop();nop();nop();

SDA=1;

nop();nop();nop();nop();

}

/**********

函數(shù)功能: 讀取數(shù)據(jù)

出口參數(shù):read_data

**********/

unsigned char shin()

{

unsigned char i,read_data;

for(i=0;i<8;i++)

{ nop();nop();nop();

SCL=1;

nop();nop();

read_data《=1;

if(SDA == 1)

read_data=read_data+1;

nop();

SCL=0;

}

return(read_data);

}

/**********

函數(shù)功能: 向EEPROM 寫(xiě)數(shù)據(jù)

入口參數(shù):write_data

出口參數(shù):ack_bit

**********/

bit shout(unsigned char write_data)

{

unsigned char i;

unsigned char ack_bit;

for(i = 0; i < 8; i++)

{

if(write_data&0x80)

SDA=1;

else

SDA=0;

nop();

SCL = 1;

nop();nop();nop();nop();nop();

SCL = 0;

nop();

write_data 《= 1;

}

nop();nop();

SDA = 1;

nop();nop();

SCL = 1;

nop();nop();nop();

ack_bit = SDA; // 讀取應(yīng)答

SCL = 0;

nop();nop();

return ack_bit;

// 返回AT24Cxx 應(yīng)答位

}

/**********

函數(shù)功能: 向指定地址寫(xiě)數(shù)據(jù)

入口參數(shù):addr,write_data

**********/

void write_byte(unsigned char addr,

unsigned char write_data)

{

start();

shout(OP_WRITE);

shout(addr);

SDAIO = 0;

// 在寫(xiě)入數(shù)據(jù)前SDA 應(yīng)設(shè)置為輸出

shout(write_data);

stop();

delay();

}

/**********

函數(shù)功能: 向指定地址讀數(shù)據(jù)

入口參數(shù):random_addr

出口參數(shù):read_data

**********/

unsigned char read_random(unsigned

char random_addr)

{ unsigned char read_data;

start();

shout(OP_WRITE);

shout(random_addr);

start();

shout(OP_READ);

SDAIO = 1;

// 讀取數(shù)據(jù)前SDA 應(yīng)設(shè)置為輸入

read_data = shin();

stop();

return(read_data);

}

/**********

函數(shù)功能: 顯示子程序

入口參數(shù):k

**********/

void display(unsigned char k)

{

TRISA=0X00;

// 設(shè)置A 口全為輸出

PORTC=table[k/1000];

// 顯示千位

PORTA=0xEF;

delay();

PORTC=table[k/100%10];

// 顯示百位

PORTA=0xDF;

delay();

PORTC = table [k/ 10%10] ;

// 顯示十位

PORTA=0xFB;

delay();

PORTC=table[k%10]; // 顯示個(gè)位

PORTA=0xF7;

delay();

}

/**********

函數(shù)功能: 主程序

**********/

void main()

{

unsigned char eepromdata;

TRISB=0X00;

OPTION&=~(1《7);

// 設(shè)置RB 口內(nèi)部上拉電阻有效

TRISC=0X00;

PORTB=0X00;

PORTC=0xff;

TRISA=0X00;

eepromdata=0;

write_byte(0x01,0x55);

// 向0x01 地址寫(xiě)入0x55(85) 的數(shù)據(jù)

delay();

write_byte(0x02,0xaa);

// 向0x02 地址寫(xiě)入0xAA(170) 的數(shù)據(jù)

delay();

eepromdata=read_random(0x02);

// 讀取其中一個(gè)地址內(nèi)的數(shù)據(jù)來(lái)驗(yàn)證

while(1)

{

display(eepromdata);

}

}

編好程序后將編譯好的HEX 碼通過(guò)ICD2仿真燒寫(xiě)器燒入單片機(jī)芯片,上電運(yùn)行,主程序中在0x01 地址寫(xiě)入了“0x55”, 在0x02 地址寫(xiě)入了“0xaa”,然后在while 循環(huán)中讀出0x02地址的值,也就是我們之前寫(xiě)入的“0x55”,讀出后顯示在數(shù)碼管上,我們可以看到數(shù)碼管顯示“170”,即“0xaa”相應(yīng)的十進(jìn)制數(shù)。

作為初學(xué)者的讀者一定對(duì)有些語(yǔ)句會(huì)有點(diǎn)疑問(wèn),可以看程序中的注釋部份,24c 系列IC 數(shù)據(jù)手冊(cè)和源程序相結(jié)合來(lái)進(jìn)行分析。

關(guān)鍵字:PIC單片機(jī)  I2C總線  主從結(jié)構(gòu) 編輯:什么魚(yú) 引用地址:http://news./mcu/ic487155.html 本網(wǎng)站轉(zhuǎn)載的所有的文章、圖片、音頻視頻文件等資料的版權(quán)歸版權(quán)所有人所有,本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如果本網(wǎng)所選內(nèi)容的文章作者及編輯認(rèn)為其作品不宜公開(kāi)自由傳播,或不應(yīng)無(wú)償使用,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,以迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多