日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32的IIC应用详解3

發布時間:2025/6/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32的IIC应用详解3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

分享:

?這兩天將STM32的IIC按照原子哥的程序,大致走了一遍,多少對IIC不是那么地陌生了,也多少有了自己的一些感悟,在這里,將這兩天的學習的一個大致步驟總結下,一來可以讓自己形成一個清晰地思路,二來,希望能給一些新手一點啟發。

? 首先IIC是一種通信協議,通信方式相對比較簡單,主要有兩條線,SDA,SCL。SDA是串行數據線,上面走命令和數據,而SCL只是一條時鐘線,其保證數據是按照時鐘節拍來進行傳輸。IIC上面可以外掛很多的IIC芯片,每一個芯片對應著不同的地址,通過地址來將不同的芯片進行分開,保證不同芯片之間的數據傳輸,由于每一個芯片都是可以獨立地收發,故,每一個芯片都是主機/從機。接下來,就是數據的傳輸過程了,

? 大致的一個數據傳輸流程是:主機向SDA線上發送一個起始信號,表示有信號進行傳輸,此時所有連接到IIC總線上的芯片都處于接收狀態,接下來,主機發送想要與其進行數據傳輸的從機地址信號,所有的從機都會接收到該地址信號并和自己固有的地址信號進行匹配,當配對成功時,接下來就在時鐘信號的帶動下進行數據傳輸,數據的傳輸是按照每8位一個單元進行數據的傳輸。每一位的傳輸過程中,在SCL高電平期間,一定要保證SDA數值的穩定,否則會出現出錯的情況,SDA數值的改變發生在SCL的低電平期間。最終8位全部傳輸完畢,從機產生一個應答信號給主機,主機在接收到該應答信號后決定接下來是發送一組新的數據還是終止發送。

? 大致按照傳輸的一個流程和模擬IIC的源碼來對數據傳輸過程進行分析:

分析之前,將一些定義告訴大家,免得有疑問:

//I/O方向設置

#define SDA_OUT() {GPIOB->CRL &= 0X0FFFFFFF;GPIOB->CRL |= 3<<28;} //0011 通用推挽輸出,50M

#define SDA_IN() {GPIOB->CRL &= 0X0FFFFFFF;GPIOB->CRL |= 8<<28;} //1000 上拉/下拉輸入

?

//I/O操作函數

#define IIC_SCL PBout(6)

#define IIC_SDA PBout(7)

#define READ_SDA PBin(7)

?

其中SDA_IN()、?SDA_OUT()設置了I/O口的方向,也就是SDA是輸入那?還是輸出那?

IIC_SCL ? 是SCL輸出管腳

IIC_SDA ? 是SDA輸出管腳

READ_SDA ?讀取SDA輸入引腳,等待應答信號時要用。

?

OK!接下來就磨刀霍霍,開始分析數據傳輸過程

1、起始信號

首先,SDA、SCL線默認是高,表示總線處于空閑狀態,接著SDA線被主機拉低,表示主機有信號進行傳輸,要么是發數據,或者是要進行讀數據,當SDA線拉低之后,SCL線也同樣被拉低,準備接下來的數據傳輸。用了原子哥的模擬IIC,此開始信號的產生如下:

聲明:此時將CPU當做了主機,而AT24C02當做了從機。

//起始信號

void IIC_Start(void)

{

SDA_OUT(); //設為主機輸出

IIC_SDA = 1;

IIC_SCL = 1;

delay_us(4);

IIC_SDA = 0; //scl為高電平時,SDA出現低電平跳變,表示傳輸開始

delay_us(5);

IIC_SCL = 0; ?? //鉗位SCL,方便接下來進行數據傳輸

?

}

此程序產生的波形就是上面起始信號所對應的波形。

2、終止信號

終止信號:就是在SCL為高電平時,SDC出現一個上升沿的跳變,即表示終止信號

源程序如下:

//終止信號

void IIC_Stop(void)

{

SDA_OUT(); ?? //設為主機輸出

IIC_SDA = 0;

IIC_SCL = 1;

delay_us(2); ??//scl為高電平,SDA出現高電平跳變,表示傳輸結束

IIC_SDA = 1;

?

}

3、等待應答信號

? 主機將一組數據發送完畢,接下來就進入等待從機發送応答信號的到來,從機會在第9個時鐘信號時,發送該應答信號,此應答信號就是將SDA信號線拉低,而又由于SDA、SCL為開漏輸出,故支持線與的形式,當從機那邊將SDA線拉低,而主機這邊依舊是將SDA線置高,主機通過判斷SDA線的高低電平就可以知道是否收到了該應答信號,當然,接收到該應答信號的前提是,使能了從機的應答功能,否則接受不到,之能通過每組發送完畢的一個長延時來保證從機接收數據完畢。

//等待應答信號到來

//返回值:1,接收應答失敗

// ? ? ? ?0,接收應答成功

u8 IIC_Wait_Ack(void)

{

u16 Errtime=0;

SDA_IN(); //此時設置為輸入

IIC_SCL = 1;

IIC_SDA = 1; //線與的關系

if(READ_SDA)

{

Errtime++;

if(Errtime > 250)

{

IIC_Stop();

return 1;

}

}

else

IIC_SCL = 0; //鉗位,方便下次傳輸

return 0;

}

程序中需要注意的地方是,雖然設置了GPIO的方向為輸入,但是GPIO的電平還是可以設置的,沒有矛盾,GPIO方向由CRL ?CRH來決定,輸出電平由ODR寄存器來決定

?

4、產生應答信號

如上所說,從機可以選擇產生應答信號,同樣也可以選擇不產生應答信號。

產生應答辛號就是從機將SDA線拉低,不產生應答辛號就是SDA線一直保持高電平

//產生應答信號

void IIC_Ack(void)

{

SDA_OUT(); ?//此時,相當于主機在接收數據,是被動方

IIC_SCL = 0;

IIC_SDA = 0;

IIC_SCL = 1;

delay_us(2);

IIC_SCL = 0;

}

需要注意的是,此時,CUP相當于是從機,故I/O方向為輸出

5、不產生應答信號

//不產生應答信號

void IIC_NAck(void)

{

SDA_OUT(); ?//此時,相當于主機在接收數據,是被動方

IIC_SCL = 0;

IIC_SDA = 1;

IIC_SCL = 1;

delay_us(2);

IIC_SCL = 0;

?

}

道理同上

?

6、寫一個字節

按照該時序圖就可以寫數據了,流程如下:

?主機:起始信號----->第一位------>第二位---------> ? ........ ? ?-------->第八位---------> ? 等待應答信號------->停止信號

SDA數據的有效性,在上面已經分析過,就是在SCL高電平期間,SDA數據不能改變,這樣才是一個有效數據,否則無效

? ? ? SDA只能在SCL低電平期間改變

//發送一個字節數據

void IIC_Send_Byte(u8 txd)

{

u8 i;

SDA_OUT();

IIC_SCL=0;//拉低時鐘開始數據傳輸

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

{

if(txd & 0x80)

IIC_SDA = 1;

else

IIC_SDA = 0;

txd <<= 1;

delay_us(2);

IIC_SCL = 1;

delay_us(2);

IIC_SCL = 0;

delay_us(2);

}

}?

高位先發,程序中嚴格保證了SDA的有效性

7、讀一個字節

此時CPU相當于是從機,而芯片才是主機,主機在發數據,從機在接受

//讀一個字節數據 ? ack = 1 時,產生應答 ?? ack = 0 ?,不產生應答

u8 IIC_Read_Byte(unsigned char ack)

{

unsigned char i,receive=0;

SDA_IN();

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

{

IIC_SCL = 0;

delay_us(2);

IIC_SCL = 1; ??//高電平時數據已經穩定,故進行數據的讀取

receive <<= 1;

if(READ_SDA)

receive++;

}

if(ack)

IIC_Ack();

else

IIC_NAck();

return receive;

}

以上就是模擬IIC的函數

?

接下來就要針對AT24C02來進行程序的編寫

1、在AT24C02指定地址讀出一個數據

先來看AT24C02的隨機讀數據的時序圖

此時序圖上需要注意兩個地方,箭頭所標記的兩次開始信號,以及橢圓圈起來的寫信號和讀信號,接下來就分析該過程

首先,發送一個開始信號,接下來發送器件的地址,注意最后一位為Write標志位(0),等待應答,然后發送要讀的地址,等待應答,又要發送一個起始信號,發送器件的地址,注意此時,最后一位為Read標志位(1),等待應答,接下來數據就可以讀回來了。

器件的地址:

地址按照這個來進行設置,AT24CXX,這個XX即表示存儲量XX(K),很顯然AT24C02為2K,有256Byte,A2,A1,A0定義看芯片,如下

?

故,AT24C02的寫地址為0XA0,讀地址為0XA1,到這里,任督二脈已打通,接下來,上源碼

//在AT24CXX指定地址讀出一個數據

//ReadAddr:開始讀數的地址 ? 0-255

//返回值 ?:讀到的數據

u8 AT24C02_ReadOneByte(u8 ReadAddr)

{

u8 temp;

?

IIC_Start();

IIC_Send_Byte(0XA0); //發送器件地址

IIC_Wait_Ack();

IIC_Send_Byte(ReadAddr); //發送首地址

IIC_Wait_Ack();

?

IIC_Start();? ?? //注意,這個需要一個新的起始信號

IIC_Send_Byte(0XA1);

IIC_Wait_Ack();

?

temp = IIC_Read_Byte(0); //不產生應答

IIC_Stop();

return temp;

}

2、在AT24C02指定地址寫入一個數據

有了上面讀的分析,這里應該可以看懂,注意箭頭那位就好,嚴格按照這個流程來就好了

//在AT24CXX指定地址寫入一個數據

//WriteAddr ?:寫入數據的目的地址 ? ?

//DataToWrite:要寫入的數據

void AT24C02_WriteOneByte(u8 WriteAddr,u8 DataToWrite)

{

IIC_Start();

IIC_Send_Byte(0XA0); //發送器件地址

IIC_Wait_Ack();

IIC_Send_Byte(WriteAddr); //發送首地址

IIC_Wait_Ack();

IIC_Send_Byte(DataToWrite);

IIC_Wait_Ack();

IIC_Stop();

?

delay_ms(10); ?//這個延時是必須的,保證下次發送之前,上次的數據已經被接收

}

需要注意的地方是這個延時,紅色標記,因為后面要用到這個進行連續的寫操作,故這里加一個延時,保證下次寫之前,上次的數據已經被完全接收,否則有可能會出錯

?

3、在AT24C02里面的指定地址開始寫入長度為Len的數據

直接調用上面的在指定位置寫數據的函數即可

//在AT24CXX里面的指定地址開始寫入長度為Len的數據

//該函數用于寫入16bit或者32bit的數據.

//WriteAddr ?:開始寫入的地址 ?

//DataToWrite:數據數組首地址

//Len ? ? ? ?:要寫入數據的長度2,4

void AT24C02_WriteLenByte(u16 WriteAddr,u32 DataToWtie,u8 Len)

{

u8 i;

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

{

AT24C02_WriteOneByte(WriteAddr + i,(DataToWtie >> (8*i)) & 0XFF);

}

?

}

需要注意的是,此時將數據的高位寫到了后面地址處,所以接下來讀數據的時候,要從后面開始讀,免得出錯

4、在AT24C02里面的指定地址開始讀取長度為Len的數據

同上,直接調用上面在指定位置讀取數據的函數即可

//在AT24CXX里面的指定地址開始讀取長度為Len的數據

//該函數用于讀取16bit或者32bit的數據.

//WriteAddr ?:開始寫入的地址 ?

//Len ? ? ? ?:要寫入數據的長度2,4

u32 AT24C02_ReadLenByte(u16 WriteAddr,u8 Len)

{

u8 i;

u32 temp=0;

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

{

temp <<= 8;?

temp += AT24C02_ReadOneByte(WriteAddr + Len - i - 1);

}

return temp;

}

注意,先讀的是后面的數據

5、校驗IIC芯片是否在,是否正常

通過IIC芯片的最后一個地址255,寫入數據0X55,當能讀回這個數據時,說明芯片工作正常,否則不正常

源碼如下

//檢查AT24C02是否正常

//這里用了2402的最后一個地址(255)來存儲標志字.0x55

//返回1:檢測失敗

//返回0:檢測成功

u8 AT24C02_Check(void)

{

u8 temp=0;

temp = AT24C02_ReadOneByte(255);

if(temp == 0X55)

{

return 0;

}

else

{

AT24C02_WriteOneByte(255,0X55);

temp = AT24C02_ReadOneByte(255);

if(temp == 0X55)

return 0;

?

}

return 1;

}

上來直接讀,可以免得每次都要寫,寫一次就好了,其他時間都是讀她就行

?

6、在AT24C02里面的指定地址開始讀出指定個數的數據

?

依舊是調用上面的,不多說了,要餓死了zzzzzzzzz

源碼:

//在AT24C02里面的指定地址開始讀出指定個數的數據

//ReadAddr :開始讀出的地址 對24c02為0~255

//pBuffer ?:數據數組首地址

//NumToRead:要讀出數據的個數

void AT24C02_Read(u8 ReadAddr,u8 *pBuffer,u8 NumToRead)

{

while(NumToRead)

{

*pBuffer++ = AT24C02_ReadOneByte(ReadAddr++);

NumToRead--;

}

}

7、在AT24C02里面的指定地址開始寫指定個數的數據

源碼:

//在AT24C02里面的指定地址開始寫指定個數的數據

//WriteAddr :開始寫數據的地址 對24c02為0~255

//pBuffer ?:數據數組首地址

//NumToWrite:要寫數據的個數

void AT24C02_Write(u8 WriteAddr,u8 *pBuffer,u8 NumToWrite)

{

while(NumToWrite)

{

AT24C02_WriteOneByte(WriteAddr++,*pBuffer++);

NumToWrite--;

}?

}?

看好DATASHEET是關鍵,我所獲得的有很多都是來自于網絡,所以要記得回饋,羊有跪乳之恩,只是當今時代發展太快,都忘記了感恩,心懷感恩,世界是這么美好,希望也能給你一點幫助吧!

總結

以上是生活随笔為你收集整理的STM32的IIC应用详解3的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: wwwwyoujizzcom| 艳妇乳肉豪妇荡乳 | 在线免费观看亚洲视频 | 成人免费午夜 | 欧美激情视频二区 | 国产在线第一页 | 五月激情av | 青青草视频网站 | cao在线视频 | 裸体女人a级一片 | 色乱码一区二区三区网站 | 欧美一区二区三区在线视频 | 国产妻精品一区二区在线 | 欧美色呦呦 | 96在线视频 | 黄色福利社 | 99精品区 | 99国产揄拍国产精品 | 国产精品成人久久久久久久 | 97理伦| 国产一区二区视频在线播放 | 久久成人黄色 | www.波多野结衣.com | 日韩免费高清一区二区 | 9999久久久久| 亚洲 欧美 激情 另类 | 免费人成在线观看视频播放 | 青青草成人在线 | 91在线影院| 91激情捆绑调教喷水 | 中文字幕一区二区三区人妻四季 | 又大又粗欧美黑人aaaaa片 | 欧美精品一区在线观看 | 国产后入清纯学生妹 | 欧美一级淫片007 | 美女涩涩网站 | 国产精品久久久免费观看 | 免费淫片 | 亚洲精品99 | 色婷婷久久五月综合成人 | 国产精品suv一区二区 | 国产精品第一区 | 久久成人在线视频 | 国内视频精品 | 黑料视频在线 | 黄色小说图片视频 | 美女爆乳18禁www久久久久久 | 国内精品第一页 | 日韩特黄 | 奇米影视第四色7777 | 精品一区二区三区久久 | 国产亚洲精品成人av久久ww | 97人妻精品一区二区三区 | 性色av一区二区 | 美女裸体网站久久久 | 97超碰免费 | 欧美性爱精品在线 | 最新在线视频 | 日韩一区二区三区不卡视频 | 欧色丰满女同hd | 台湾佬中文字幕 | 少妇高潮久久久久久潘金莲 | 欧美草逼视频 | 91色精品 | 色妞综合 | 91视频这里只有精品 | 姑娘第5集在线观看免费好剧 | 成熟丰满熟妇高潮xxxxx视频 | 最色网站| av资源网址 | 老太婆av| 青青伊人影院 | 亚洲视频一区二区在线观看 | 国产高清亚洲 | 色撸撸在线 | 播放毛片 | av网站有哪些 | 免费观看的毛片 | 日本在线中文 | 亚洲av无码久久精品色欲 | 欧美成一区二区三区 | 91精品国产综合久久福利 | 国产稀缺真实呦乱在线 | 亚欧美在线 | aaa在线| 人人爽人人澡 | 91尤物视频| 69精品丰满人妻无码视频a片 | a级黄片毛片 | 人人爽人人爱 | 日本美女黄色 | 成人av影视在线观看 | 乡村性满足hd | 日韩黄色录像 | 久久精品第一页 | 久久精品国产精品 | 男女靠逼视频 | 午夜精品久久99蜜桃的功能介绍 | 一区二区三区在线视频观看 |