日韩av偷拍-无码人妻丰满熟妇区五十路-怡红院av亚洲一区二区三区h-中文字幕久久一区二区三区-黄色午夜网站-69视频网站-久久无码中文字幕久久无码app-诱惑网综合-xxx69-久久综合加勒比-久久综合网欧美色妞网-自拍偷拍精品视频-色综合天天-国产一区二区色-欧美日日夜夜-天堂在线视频观看-一级黄色片看看

TDA2030功放電路圖 電動車充電器電路圖 電子電路 功放電路 電子制作 集成塊資料 電子報 pcb 變壓器 元器件知識 逆變器電路圖 電路圖 開關(guān)電源電路圖 傳感器技術(shù) led 電磁兼容
電子電路圖
當(dāng)前位置: 首頁 > 電子電路 > 設(shè)計編程

單片機的I2C通信設(shè)計

時間:2019-12-05 09:15:30來源:電子發(fā)燒友 作者:admin 點擊:
I2C每一位信號的時序流程,而I2C通信在字節(jié)級的傳輸中,也有固定的時序要求。I2C通信的起始信號(Start)后,首先要發(fā)送一個從機的地址,這個地址一共有 7位,緊跟著的第 8

bit I2CAddressing(unsigned char addr);

extern void InitLcd1602();

extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

void main(){

bit ack;

unsigned char str[10];

InitLcd1602(); //初始化液晶

ack = I2CAddressing(0x50); //查詢地址為 0x50 的器件

str[0] = ‘5’; //將地址和應(yīng)答值轉(zhuǎn)換為字符串

str[1] = ‘0’;

str[2] = ‘:’;

str[3] = (unsigned char)ack + ‘0’;

str[4] = ‘’;

LcdShowStr(0, 0, str); //顯示到液晶上

ack = I2CAddressing(0x62); //查詢地址為 0x62 的器件

str[0] = ‘6’; //將地址和應(yīng)答值轉(zhuǎn)換為字符串

str[1] = ‘2’;

str[2] = ‘:’;

str[3] = (unsigned char)ack + ‘0’;

str[4] = ‘’;

LcdShowStr(8, 0, str); //顯示到液晶上

while (1);

}

/* 產(chǎn)生總線起始信號 */

void I2CStart(){

I2C_SDA = 1; //首先確保 SDA、SCL 都是高電平

I2C_SCL = 1;

I2CDelay();

I2C_SDA = 0; //先拉低 SDA

I2CDelay();

I2C_SCL = 0; //再拉低 SCL

}

/* 產(chǎn)生總線停止信號 */

void I2CStop(){

I2C_SCL = 0; //首先確保 SDA、SCL 都是低電平

I2C_SDA = 0;

I2CDelay();

I2C_SCL = 1; //先拉高 SCL

I2CDelay();

I2C_SDA = 1; //再拉高 SDA

I2CDelay();

}

/* I2C 總線寫操作,dat-待寫入字節(jié),返回值-從機應(yīng)答位的值 */

bit I2CWrite(unsigned char dat){

bit ack; //用于暫存應(yīng)答位的值

unsigned char mask; //用于探測字節(jié)內(nèi)某一位值的掩碼變量

for (mask=0x80; mask!=0; mask》》=1){ //從高位到低位依次進(jìn)行

if ((mask&dat) == 0){ //該位的值輸出到 SDA 上

I2C_SDA = 0;

}else{

I2C_SDA = 1;

}

I2CDelay();

}

I2C_SCL = 1; //拉高 SCL

I2CDelay();

I2C_SCL = 0; //再拉低 SCL,完成一個位周期

I2C_SDA = 1; //8 位數(shù)據(jù)發(fā)送完后,主機釋放 SDA,以檢測從機應(yīng)答

I2CDelay();

I2C_SCL = 1; //拉高 SCL

ack = I2C_SDA; //讀取此時的 SDA 值,即為從機的應(yīng)答值

I2CDelay();

I2C_SCL = 0; //再拉低 SCL 完成應(yīng)答位,并保持住總線

return ack; //返回從機應(yīng)答值

}

/* I2C 尋址函數(shù),即檢查地址為 addr 的器件是否存在,返回值-從器件應(yīng)答值 */

bit I2CAddressing(unsigned char addr){

bit ack;

I2CStart(); //產(chǎn)生起始位,即啟動一次總線操作

//器件地址需左移一位,因?qū)ぶ访畹淖畹臀?/p>

//為讀寫位,用于表示之后的操作是讀或?qū)?/p>

ack = I2CWrite(addr《《1);

I2CStop(); //不需進(jìn)行后續(xù)讀寫,而直接停止本次總線操作

return ack;

}

我們把這個程序在 KST-51開發(fā)板上運行完畢,會在液晶上邊顯示出來我們預(yù)想的結(jié)果,主機發(fā)送一個存在的從機地址,從機會回復(fù)一個應(yīng)答位,即應(yīng)答位為 0;主機如果發(fā)送一個不存在的從機地址,就沒有從機應(yīng)答,即應(yīng)答位為 1。

前面的章節(jié)中已經(jīng)提到利用庫函數(shù)_nop_()可以進(jìn)行精確延時,一個_nop_()的時間就是一個機器周期,這個庫函數(shù)包含在 intrins.h 這個文件中,如果要使用這個庫函數(shù),只需要在程序最開始,和包含 reg52.h 一樣,include之后,程序中就可以使用這個庫函數(shù)了。

還有一點要提一下,I2C通信分為低速模式 100kbit/s、快速模式 400kbit/s 和高速模式3.4Mbit/s。因為所有的 I2C 器件都支持低速,但卻未必支持另外兩種速度,所以作為通用的I2C 程序我們選擇 100k 這個速率來實現(xiàn),也就是說實際程序產(chǎn)生的時序必須小于等于 100k的時序參數(shù),很明顯也就是要求 SCL 的高低電平持續(xù)時間都不短于 5us,因此我們在時序函數(shù)中通過插入 I2CDelay()這個總線延時函數(shù)(它實際上就是 4 個 NOP 指令,用 define 在文件開頭做了定義),加上改變 SCL 值語句本身占用的至少一個周期,來達(dá)到這個速度限制。如果以后需要提高速度,那么只需要減小這里的總線延時時間即可。

此外我們要學(xué)習(xí)一個發(fā)送數(shù)據(jù)的技巧,就是I2C通信時如何將一個字節(jié)的數(shù)據(jù)發(fā)送出去。大家注意函數(shù) I2CWrite 中,用的那個 for 循環(huán)的技巧。for (mask=0x80; mask!=0; mask》》=1),由于 I2C 通信是從高位開始發(fā)送數(shù)據(jù),所以我們先從最高位開始,0x80 和 dat 進(jìn)行按位與運算,從而得知 dat 第 7 位是 0 還是 1,然后右移一位,也就是變成了用 0x40 和 dat 按位與運算,得到第 6 位是 0 還是 1,一直到第 0 位結(jié)束,最終通過 if 語句,把 dat 的 8 位數(shù)據(jù)依次發(fā)送了出去。其它的邏輯大家對照前邊講到的理論知識,認(rèn)真研究明白就可以了。容-源-電-子-網(wǎng)-為你提供技術(shù)支持

本文地址:http://m.zhongyiwenxian.com.cn/dz/22/15755085833520.shtml


本文標(biāo)簽:


.
首頁 上一頁123下一頁尾頁
頂一下
0%
返回首頁
0
0%

------分隔線----------------------------
發(fā)表評論
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
表情:
名稱: E-mail: 驗證碼: 匿名發(fā)表
發(fā)布文章,推廣自己產(chǎn)品。
余干县| 岳阳县| 调兵山市| 博白县| 郁南县| 尼玛县| 永城市| 西宁市| 淮安市| 松桃| 秦安县| 灵璧县| 富阳市| 二手房| 利川市| 吴旗县| 三都| 金坛市| 阿鲁科尔沁旗| 东宁县| 二连浩特市| 峨山| 沐川县| 金寨县| 琼海市| 襄城县| 宝清县| 如皋市| 岳西县| 永清县| 永州市| 景宁| 桐乡市| 大新县| 昌乐县| 义马市| 苗栗市| 托里县| 雷山县| 广德县| 澎湖县|