日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

歷史上的今天

今天是:2024年09月01日(星期日)

正在發(fā)生

2021年09月01日 | C51—模擬IIC總線實現EEPROM存取數據

發(fā)布者:vnerwb池塘邊 來源: eefocus關鍵字:C51  模擬IIC總線  EEPROM 手機看文章 掃描二維碼
隨時隨地手機看文章

- 什么是IIC總線

IIC總線是同步通信的一種特殊形式,具有接線口少、控制簡單、器件封裝形式小、通信速率高等特點。在主從通信中,可以有多個IIC總線器件同時連接到IIC總線上,所有與IIC兼容的器件都具有標準的接口,通過地址來識別通信對象,使他們可以經由IIC總線互相直接通信。


IIC總線由SDA數據線和SCL時鐘線倆條線構成通信線路,既可發(fā)送數據也可以接收數據。在CPU和IC之間、IC與IC間都可以雙向傳播,每個器件都有唯一的地址,這樣就可以使信息進行準確的傳輸。CPU發(fā)出的信號分為地址碼和數據碼倆部分,地址碼用來選址,數據碼是通信的內容。


總而言之,IIC總線就是器件之間的通信線路,主器件可以通過IIC總線向從器件發(fā)送數據,也可以從從器件接收數據。51單片機不具備IIC總線接口,但我們可以通過軟件模擬IIC總線的工作時序,只需要正確調用各個函數就能夠方便的拓展IIC總線接口器件。


-什么是EEPROM

EEPROM就是一種存儲介質,就像ROM、PROM、FLASH儲存器等,下面我粗略地介紹一下EEPROM的由來


ROM:只讀存儲器,其中的內容在工廠中就燒錄好了,內容只能讀,不能改,所以用戶只能讀取其中數據,一旦數據出錯,ROM就相當于廢掉了。


PROM:可編程的ROM,相比于原來的ROM,用戶可以將自己所需要的數據寫入,但也只有一次機會,數據一旦寫入之后就無法修改。


EPROM:可擦除可編程ROM,相比較PROM,此芯片可以重復擦除和寫入,雖然它解決了PROM只能寫入一次的弊端,但EPROM數據的擦除是通過紫外線的照射來完成的,所以使用此芯片時對紫外線的防護是很重要的。


EEPROM電可擦除可編程ROM,鑒于EPROM擦除數據的不容易,EEPROM應運而生,它是以電子信號來修改其內容的,而且是以byte為最小修改單位的,不需要將數據全部清除來寫入,可以實現定向修改數據。而且因為其數據保存具有掉電不丟失的特性備受追捧。


在下的程序就是通過51單片機模擬IIC總線對AT24C02(EEPROM的型號)進行數據的存取和修改。


AT24C02的儲存容量為256B一般通過片內子地址尋址對內部256B中任意一個進行讀寫操作,其尋址范圍為00~FF。


-IIC總線的通信格式

就像串口通訊和紅外遙控一樣,IIC總線也有一套通信方式。


硬件結構:

先來認識一下IIC總線的硬件結構,SDA是數據線,SCL是時鐘線,總線上個器件均采用漏極開路結構與總線相連,因此SDA和SCL都需要上拉電阻,總線在空閑狀態(tài)保持高電平,一旦某一器件輸出低電平,都將使總線的信號變低,所以說各器件的SDA和SCL都是線“與”關系。

在這里插入圖片描述

數據位有效性:

IIC中數據的傳輸是通過SDA和SCL進行高低電平變化來完成的,在傳送數據時,只有當時鐘線SCL為高電平的時候數據線SDA上的電平才有效(即SDA高電平代表1;SDA低電平代表0),所以在SCL為高電平的時候SDA上的數據一定要保持穩(wěn)定才行,不然數據的傳輸會很不穩(wěn)定的。那就是說SCL為低電平的時候SDA怎么變化都沒有關系,但SCL為高電平時SDA一定要穩(wěn)定,可以理解為傳輸信號的改變是在SCL為低電平的時候進行的(SCL高電平時SDA的改變即為傳輸信號的改變)。

在這里插入圖片描述

啟始信號、停止信號:

IIC每次進行數據傳輸時先由主機發(fā)出啟始信號,代表數據傳輸的開始,信號格式為:在SCL高電平時期SDA產生下降沿(注意這與數據的傳輸不同,SCL高電平時器SDA要變化),這樣從器件就會檢測到該信號并做好準備。


相對應,停止信號時在SCL高電平時期SDA產生上升沿信號。倆種信號的時序圖如下

在這里插入圖片描述

尋址信號:

主機在發(fā)出啟始信號后,再發(fā)出尋址信號,這里介紹一下七位尋址方式。


尋址信號由一個字節(jié)(8byte)構成,高七位為地址位,用來確定要進行通信的從器件,最低位是方向位,用來說明是傳輸數據還是接收數據。每一個從器件都會對比主機發(fā)送的地址碼和自己的地址,如果安排上了,再判斷從器件是接收主機數據還是向主機發(fā)送數據。


從器件的地址由固定地址和可編程地址倆部分組成,固定地址用于區(qū)別類別,可編程地址用來區(qū)別同類從器件。比如AT24C02有四位固定地址和三位可編程地址,三位可編程地址可以有八種表達方式,所以最多可以有八個AT24C02器件接再IIC中。


方向位為0時,主機向從機傳輸數據;方向位為1時,從機向主機傳輸數據。


應答信號:

IIC總線協(xié)議規(guī)定:每傳輸1字節(jié)數據(含地址及命令)后,都要有一個應答信號,以確定數據傳送是否被對方收到。應答信號由接收方產生,應答信號的格式為:在SCL為高電平時SDA為低電平(被動的,我們到時候只要檢測一下SDA是否被拉低即可),表示數據傳輸正確,產生應答。但當主機為接收方時,對最后一字節(jié)不應答。

在這里插入圖片描述

(在敲代碼時我們一般將應答信號的檢驗放在數據發(fā)送函數中)


模塊化設計注解

這里只是挑重要模塊進行注解,后面有完整代碼。

延時10um函數:


void dy()

{

uint a;

for(a=3;a>0;a--)

;

}


IIC啟始函數:


void IICstart()//產生下降沿,啟動信號

{

SDA=1;

dy();

SCL=1;

dy();

SDA=0;

dy();

SCL=0;

}


IIC停止函數:


void IICstop()//產生上升沿,停止信號

{

SDA=0;

dy();

SCL=1;

dy();

SDA=1;

dy();

SCL=0;

}


IIC發(fā)送一個字節(jié)函數:


uchar IICsendbyte(uchar dat)//將dat一個字節(jié)的內容發(fā)送出去,先發(fā)送最高位,并檢測應答

{

uint i;

SCL=0

for(i=0;i<8;i++)//8位逐次發(fā)送

{

dat<<=1;

SDA=CY;//進行左移操作后最高位自動移入PSW寄存器中的CY位(可以用來zb)

dy();

SCL=1;

dy();

SCL=0;

dy();

}

SDA=1;//拉高SDA電平,準備檢測應答信號

dy();

SCL=1;

while(SDA)

{

j++;

if(j>200)//當超過2000umSDA還沒被拉低,算應答失敗或非應答

{

SDA=0;

dy();

return 0;//發(fā)送失敗返回0

}

}

SCL=0;

dy();

return 1;//發(fā)送成功返回1

}


IIC接收一個字節(jié)函數:


uchar IICreadbyte()//讀取一個字節(jié)數據,并返回

{

uint i;

uchar dat;

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

{

SCL=1;

dy();

dat<<=1;//一定要先移位

dat |=SDA;//與運算

dy();

SCL=0;

dy();

}

return dat;

}


向AT24C02寫字節(jié):


void AT24C02write(uchar addr,uchar dat)//往addr地址寫入dat數據

{

IICstart();//開始

IICsendbyte(0Xa0);//發(fā)送尋址 0Xa0代表尋址AT24C02并且方向位為0,主機向從機傳輸數據

IICsendbyte(addr);//發(fā)送儲存地址

IICsendbyte(dat);//發(fā)送儲存數據

ICCstop();//結束

}


從AT24C02讀字節(jié):


uchar AT24C02read(uchar addr)//讀取AT24C02中addr位置數據并返回

{

uchar dat;

IICstart();

IICsendbyte(0Xa0);//偽寫

IICsendbyte(addr);

IICstart();//開始讀取

IICsendbyte(0Xa1);//發(fā)送尋址 0Xa0代表尋址AT24C02并且方向位為1,從機向主機傳輸數據

dat=IICreadbyte(addr);//讀取數據

IICstop();

return dat;//返回數據

}


整體代碼

在下通過按鍵k1、k2、k3、k4實現數據在AT14C02中的保存、讀取、自增、清零等操作,并通過數碼管顯示數值(38譯碼器),親自測試可以運行。


 #include"reg52.h"

 #define uint unsigned int

 #define uchar unsigned char

 uchar num,duan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

 sbit SDA=P2^0;

 sbit SCL=P2^1;


 sbit a=P2^2;

 sbit b=P2^3;

 sbit c=P2^4;


 sbit k1=P1^3;

 sbit k2=P1^2;

 sbit k3=P1^1;

 sbit k4=P1^0;


void delay10us()   //時間>4.7um就ok

{

    unsigned char a;

    for(a=3;a>0;a--);

}


void dy(uint x)   //按鍵時用的延時函數

{

while(x--);

}


void xs() //數碼管顯示

{

uint i;

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

{

switch(i)

{

case 0:a=0;b=0;c=0;P0=duan[num/1000];break; //千位

case 1:a=1;b=0;c=0;P0=duan[num/100];break;    //百位

case 2:a=0;b=1;c=0;P0=duan[num/10%10];break;   //十位

case 3:a=1;b=1;c=0;P0=duan[num%10];break;   //個位

}

dy(100);

P0=0X00;

    }  

}


void IICstart() //起始信號

{

SDA=1;

delay10us();

SCL=1;

delay10us();

SDA=0;

delay10us();

}


void IICstop()   //停止信號

{

SDA=0;

delay10us();

SCL=1;

delay10us();

SDA=1;

delay10us();

}


uchar IICsendbyte(uchar dat) //發(fā)送一個字節(jié)的數據

{

uint i,j=0;

SCL=0;

for(i=0;i<8;i++) //從最高位開始發(fā)送

{

dat<<=1;

SDA=CY; //左移時最高位會移入PSW寄存器的CY位中

delay10us();

SCL=1;

delay10us();

SCL=0;

delay10us();

}

SDA=1;

delay10us();

SCL=1;

while(SDA) //等待應答 即等待設備把SDA拉低

{

j++;

if(j>200) //如果超過2000um沒有應答就算發(fā)送失敗或非應答  表示接收結束

{

SCL=0;

delay10us();

return 0;

}

}

SCL=0;   //不管應答或非應答,SCL都置0

delay10us();

return 1;

}


uchar IICreadbyte()    //讀一個字節(jié),從最高位開始

{

uint i,dat=0;

SDA=1; //因為下面開始時SCL=1,所以SDA要穩(wěn)定

delay10us();

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

{

SCL=1;

delay10us();

dat<<=1;

dat |=SDA;

delay10us();

SCL=0;

delay10us();

}

return dat;    //返回讀到的數據dat(一個字節(jié))

}



void AT24c02write(uchar addr,uchar dat) //往AT24c02的addr地址寫入dat數據

{

IICstart();

IICsendbyte(0Xa0);   //發(fā)送要與之通信的器件地址,此處為AT24c02的地址

IICsendbyte(addr);   //發(fā)送要寫入的內存地址,AT24c02內部可儲存256字節(jié),故地址可以為0~255

IICsendbyte(dat);   //發(fā)送數據

IICstop();

}


uchar AT24c02read(uchar addr)    //讀取AT24c02中addr地址的值,并返回給函數

{

uchar dat;

IICstart();

IICsendbyte(0Xa0);   //偽寫

IICsendbyte(addr);

IICstart();    //真正開始讀數據

IICsendbyte(0Xa1);

dat=IICreadbyte();

IICstop();

return dat;

}


void key()

{

if(k1==0)

{

dy(1000);

if(k1==0)

{

AT24c02write(1,num);

}

while(!k1);    //檢測放手

}

if(k2==0)

{

dy(1000) ;

if(k2==0)

{

num=AT24c02read(1);

}

while(!k2);    //檢測放手

}

if(k3==0)

{

dy(1000);

if(k3==0)

{

num++;

if(num==256)

num=0;

}

while(!k3);    //檢測放手

}

if(k4==0)

{

dy(1000);

if(k4==0)

{

num=0;

}

while(!k4);    //檢測放手

}

}


void main()

{

while(1)

{

key();

xs();

}

}

關鍵字:C51  模擬IIC總線  EEPROM 引用地址:C51—模擬IIC總線實現EEPROM存取數據

上一篇:51單片機—串口通信
下一篇:C51—小知識點

推薦閱讀

之前寫了篇關于ESP8266使用AT指令進行互相通訊的實驗,在寫STM32串口接發(fā)數據的程序中,覺得有必要將之前學的有關于串口方面的使用經歷加以總結。串口發(fā)送數據:1. 串口發(fā)送數據最直接的方式就是標準調用庫函數 。 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);第一個參數是發(fā)送的串口號,第二個參數是要發(fā)送的數據了。但是用過的朋...
(記者 周毅)27日,記者從國網重慶市電力公司獲悉,5G為建設“三型兩網”和泛在電力物聯網解決了大問題,既能夠全息感知電力設備的運行,關聯企業(yè)、供應商和電力客戶的數據,也可通過平臺實現數據共享,為上下游企業(yè)、電力客戶提供服務。 今年1月,國家電網公司首次提出“三型兩網、世界一流”的全新戰(zhàn)略目標。即把企業(yè)打造成樞紐型、平臺型、共享型的...
在過去5年左右的時間中,工程師一直把重點更多地放在低壓差分信令上,以明顯提高系統(tǒng)性能。數據速率已經以幾何級數提高,推動著設備之間的通信更廣泛地采用復雜的串行協(xié)議,如PCIExpress、Infiniband、XAUI等等。這些環(huán)境涵蓋了各種數據速率和傳輸結構,但所有這些數據速率和傳輸結構都需要嚴格的設計和檢驗方法。這使得示波器等測試設備的重要性大大提高...
近些年來,雖然中國面板產能持續(xù)提升,已成為全球最大的顯示面板生產國,但驅動芯片卻仍以進口為主,成為中國面板產業(yè)發(fā)展的一大瓶頸?! 〗衲?月底,中國投資基金智路資本被同意以14億美元(約90億元人民幣),收購韓國芯片廠商美格納半導體(MagnaChip)的美國總部。美格納是全球第二大OLED面板驅動芯片商,中企此舉有望補齊中國在該產業(yè)上的短板,但該...

史海拾趣

小廣播
設計資源 培訓 開發(fā)板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統(tǒng)推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved