前言: IIC協(xié)議簡介
維基百科的解釋如下: I2C(Inter-Integrated Circuit)字面上的意思是積體電路之間,它其實(shí)是I2C Bus簡稱,所以中文應(yīng)該叫集成電路總線,它是一種串行通訊匯流排,使用多主從架構(gòu),由飛利浦公司在1980年代為了讓主機(jī)板、嵌入式系統(tǒng)或手機(jī)用以連接低速周邊裝置而發(fā)展。I2C的正確讀法為“I平方C”("I-squared-C"),而“I二C”("I-two-C")則是另一種錯誤但被廣泛使用的讀法。自2006年10月1日起,使用I2C協(xié)定已經(jīng)不需要支付專利費(fèi),但制造商仍然需要付費(fèi)以取得I2C從屬裝置位址。
我們需要了解的是 : I2C通信只需要兩根線即可進(jìn)行數(shù)據(jù)傳輸; 即串行數(shù)據(jù)線(SDA::Serial DAta)和串行時(shí)鐘線(SCL::Serial CLock); IIC總線具有多主設(shè)備的優(yōu)點(diǎn), 就是有多個(gè)主機(jī)進(jìn)行數(shù)據(jù)發(fā)送并且不會有混亂.
IIC總線可以用簡單、優(yōu)雅四個(gè)字形容,很方便。下面是IIC的時(shí)序圖:
IIC總共有三種信號:開始信號,結(jié)束信號,應(yīng)答信號
說明:高電平為1,低電平為0
1、圖中S即為起始信號: SCL處于1時(shí), SDA由高變低↓—>Start
下面是STM32的這部分代碼,每句話我基本上都加了注釋,可以對照時(shí)序圖看, 便于理解
2、圖中末尾P為結(jié)束信號: SCL=1, SDA 由低變高↑
3、數(shù)據(jù)傳送: 每次數(shù)據(jù)傳送都是8個(gè)字節(jié); SCL=1時(shí), SDA的數(shù)據(jù)不可以變化, 只有SCL為低電平, 數(shù)據(jù)線的數(shù)據(jù)才可以變化;
3.1、 數(shù)據(jù)傳輸流程:SCL=0, —>開始數(shù)據(jù)傳輸, 傳輸完一位之后,—> SCL=1(拉高時(shí)鐘線);===
下面接著循環(huán), 直到傳輸完一個(gè)字節(jié)8位數(shù)據(jù).
下面舉個(gè)例子:
e.g.
傳輸1001 1100?
SCL=0 --> SDA=1 --> SCL=1 (先傳送最高位MSB)
SCL=0 --> SDA=0 --> SCL=1
SCL=0 --> SDA=0 --> SCL=1
…
**Tips:**在IIC協(xié)議中,起始信號必須有. 因?yàn)镮C必須知道什么時(shí)候開始了,才可以正確判斷接受數(shù)據(jù).
下面開始Cube配置+IAR編程
6.1 操作簡介
??(1) 我所使用的STM32開發(fā)板板載了一個(gè)24C02的EEPROM存儲芯片; 這個(gè)芯片就是通過IIC總線和單片機(jī)通信的;
??(2) 通過GPIO軟件模擬IIC通信 , 實(shí)現(xiàn)對24C02芯片內(nèi)部數(shù)據(jù)的讀寫操作 .
注:
??本次實(shí)驗(yàn)的代碼是用的原子的底層代碼, 修改了部分代碼, 和Cube配置的工程以及HAL庫函數(shù)匹配. 野火的例程沒有看過,如果這個(gè)代碼又有什么限制或者問題, 可以評論或者私信告訴我, 共同學(xué)習(xí),感激不盡.
6.1 軟件流程圖
開機(jī)檢測24C02--->主循環(huán)檢測按鍵--->串口打印相關(guān)信息...
6.2 硬件接口
以我用的單片機(jī)為例:
但是這里并沒有用板子上的硬件 IIC, 只是用這兩個(gè)對應(yīng)的引腳做軟件模擬 IIC
Step1 : STM32CubeMX配置
(1) 像前面那樣配置好基礎(chǔ)的東西[RCC--SYS--時(shí)鐘樹配置不變]
還要配置 串口 和 按鍵 ; 時(shí)鐘樹的配置跟之前的博客都一樣
Tips: Click the blue word to open the corresponding blog link
(2) 配置IIC通信用的兩個(gè)引腳(SCL&SDA)
兩個(gè)引腳都配置為輸出模式, 在程序中需要改變引腳方向, 那個(gè)時(shí)候直接操作寄存器改動引腳輸入輸出即可, 配置的時(shí)候先默認(rèn)配置一個(gè)輸出;
補(bǔ)充: 后面又加上了兩個(gè)LED引腳, 用以做指示
(3) Project Manager and Generate Code
Step2 : IAR或Keil編程
(1) IIC部分代碼
我把我改過部分的底層代碼分享在網(wǎng)盤里面
鏈接:https://pan.baidu.com/s/17ogW2r-WzN9u-w511VzBJQ
提取碼:9m4v
.c文件放在 src 文件夾,.h文件復(fù)制到 Inc 文件夾
在myiic.h里面有兩句宏定義SDA_OUT()和SDA_IN(); 如果你用的是F4的板子是可以直接用的, 但是如果用的是F1的或者其他的, 這個(gè)宏定義要改一下, 因?yàn)椴煌男酒拇嫫鞯拿趾筒僮鞑惶粯? 如果有人用的F1在這里遇到困難可以評論或者私信我, 這里就不單獨(dú)寫了
說明 : ?24cxx文件是24CXX系列芯片的底層驅(qū)動文件, myiic文件是修改后的iic通信的驅(qū)動文件; 在主函數(shù)里面就是調(diào)用myiic里面的函數(shù)去實(shí)現(xiàn)通信的功能
部分底層代碼分析
??大概說一下底層驅(qū)動, 24cxx文件是通過iic協(xié)議對24c02芯片通信的底層驅(qū)動,直接用就可以了。
??myiic文件是iic的關(guān)鍵.
??關(guān)于起始信號, 結(jié)束信號就不多說了
??在myiic.h中宏定義了SDA引腳的輸入輸出模式, 因?yàn)樽x數(shù)據(jù)的時(shí)候需要SDA這根線為輸入模式, 往里面讀數(shù)據(jù)
??關(guān)于應(yīng)答信號之類的幾個(gè)函數(shù),有興趣可以去了解一下具體的IIC的協(xié)議總結(jié)或者數(shù)據(jù)手冊
發(fā)送字節(jié)函數(shù)
?IIC協(xié)議發(fā)送字節(jié), 一個(gè)字節(jié)8位, 通過一個(gè)for循環(huán)發(fā)送;
?txd是要發(fā)送的一個(gè)字節(jié), IIC是先傳輸最高位, 所以讓txd和0x80相與, 再右移7位
?數(shù)據(jù)為1就給數(shù)據(jù)線(SDA)引腳寫高電平, 然后txd左移一位,進(jìn)入下一循環(huán), 逐漸把8bits的數(shù)據(jù)發(fā)送完畢
讀一個(gè)字節(jié)函數(shù)
?IIC發(fā)送數(shù)據(jù)是往外發(fā)送數(shù)據(jù), 所以SDA為輸出模式, 但是讀取字節(jié)是把外面的讀進(jìn)來;
?舉個(gè)形象一點(diǎn)的例子, 你的大腦就是24C02儲存芯片, 你的身體器官就是IIC,即你的身體器官是通過IIC協(xié)議與外界進(jìn)行數(shù)據(jù)交換的
?發(fā)送字節(jié)就是你用嘴巴給別人說話把你腦子里想的東西告訴別人; ? 而接收字節(jié)就是你通過眼睛讀書, 把知識記到腦子里
?這樣就很好理解了吧
(2) 按鍵部分
新建一個(gè)文件Ctrl+N—>Ctrl+S保存為 key.c到Src文件夾 ; 再新建一個(gè)保存在Inc文件夾, 命名為key.h
把.c和.h文件添加到工程中
+
寫代碼
#include "key.h"
#include "main.h"
/******************************************************************************************************
*【文件名稱】 : key.c
*【文件描述】 : 核心板板載按鍵驅(qū)動代碼
*【文件功能】 : 實(shí)現(xiàn)按鍵輸入掃描功能
*【主控芯片】 : STM432F407zg
*【實(shí)驗(yàn)平臺】 : STM32F4xx開發(fā)板
*【編寫環(huán)境】 : IAR 8.30.1
*【編寫時(shí)間】 : 2019-12-31
*【作 者】 : 李剴(KevinLee)
*【歷史記錄】 :
<1> $【修改時(shí)間】
$【修改內(nèi)容】
$【修改詳情】
$【修改人員】
*******************************************************************************************************/
/**
* @brief 按鍵處理函數(shù)
* @param mode:0,不支持連續(xù)按;1,支持連續(xù)按;
* @retval 0: 沒有任何按鍵按下 1: KEY0按下
* 2: WKUP按下 WK_UP
*/
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key_up = 1;//按鍵按松開標(biāo)志
if (mode)
key_up=1; //支持連按
if (key_up && (KEY0 == 0 || WK_UP != 0))
{
HAL_Delay(10);//去抖動
key_up = 0;
if(KEY0 == 0)
return 1;
else if(WK_UP != 0)
return 2;
}else if(KEY0 != 0 && WK_UP == 0)
key_up = 1;
return 0;// 無按鍵按下
}
key.h代碼如下
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/******************************************************************************************************
*【文件名稱】 : key.h
*【文件描述】 : 核心板板載按鍵驅(qū)動代碼
*【文件功能】 : 實(shí)現(xiàn)按鍵輸入掃描功能
*【主控芯片】 : STM432F407zg
*【實(shí)驗(yàn)平臺】 : STM32F4xx開發(fā)板
*【編寫環(huán)境】 : IAR 8.30.1
*【編寫時(shí)間】 : 2019-12-31
*【作 者】 : 李剴(KevinLee)
*【歷史記錄】 :
<1> $【修改時(shí)間】
$【修改內(nèi)容】
$【修改詳情】
$【修改人員】
*******************************************************************************************************/
#define KEY0 HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) //PE4
#define WK_UP HAL_GPIO_ReadPin(WKUP_GPIO_Port, WKUP_Pin) //PA0
#define KEY0_PRES 1 // 宏定義按鍵按下的鍵值
#define WKUP_PRES 2
uint8_t KEY_Scan(uint8_t); //按鍵掃描函數(shù)
#endif
(3) 串口重定向printf
參考第三節(jié): 串口通信(用CubeMX學(xué)習(xí)STM32);
(4) main.c文件
① 包含頭函數(shù)
② 自定義變量
TEXT_Buffer數(shù)組存放的是等會要寫入24c02芯片的數(shù)據(jù)
③ 主函數(shù)變量定義
key用于獲取掃描按鍵值; datatemp數(shù)組作為傳輸數(shù)據(jù)的暫存地點(diǎn)
④ 初始化操作
在/ USER CODE BEGIN 2 /下, 先初始化IIC, 在測試串口, 并用串口打印提示信息, 然后檢測存儲芯片是否存在
/* USER CODE BEGIN 2 */
AT24CXX_Init(); //IIC初始化
printf("Usart is Ok!!!n");
printf("***************************n");
printf("** STM32 IIC TEST **n");
printf("** Kevin_8_Lee **n");
printf("** KEY0:Write WKUP:Read **n"); // 打印提示信息; KEY0按下寫數(shù)據(jù);WKUP按下讀數(shù)據(jù)
printf("***************************n");
// 檢測24C02芯片是否存在
while(AT24CXX_Check())
{
printf("未檢測到24C02!n");
HAL_Delay(500);
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin); // LED0閃爍
}
printf("24C02 Ready!n");
/* USER CODE END 2 */
⑤ while(1)循環(huán)
循環(huán)進(jìn)行安檢掃描, 如果KEY0按下, 就把之前定義的一個(gè)字符串?dāng)?shù)組的數(shù)據(jù)寫入24C02, 如果檢測到WKUP按鍵按下就把24C02內(nèi)部的數(shù)據(jù)讀取出來并打印在串口
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key = KEY_Scan(0); // 按鍵掃描獲取鍵值
// 如果KEY0按下,則向24C02芯片寫入指定數(shù)據(jù)
if (key == KEY0_PRES)
{
printf("開始寫入24C02...n");
AT24CXX_Write(0,(uint8_t *)TEXT_Buffer,SIZE);
printf("傳輸完成nn");
}
// 如果WKUP按鍵按下,則從24C02芯片讀出數(shù)據(jù), 并打印在串口
if (key == WKUP_PRES)
{
printf("開始讀24C02......n");
AT24CXX_Read(0,datatemp,SIZE);
printf("讀取到的數(shù)據(jù)為 : %s", datatemp);
}
// 下面的是進(jìn)行一定的延時(shí), 保證上面掃描安全運(yùn)行, 同事
// 以LED閃爍提示系統(tǒng)正在運(yùn)行
i++;
HAL_Delay(10);
if (i == 20)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
i = 0;
}
}
/* USER CODE END 3 */
實(shí)際效果
串口助手打印出的結(jié)果:
上一篇:第五節(jié):STM32輸入捕獲(用CubeMX學(xué)習(xí)STM32)
下一篇:【STM32】HAL庫 STM32CubeMX教程四---UART串口通信詳解
推薦閱讀
史海拾趣
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- Microchip 升級數(shù)字信號控制器(DSC)產(chǎn)品線 推出PWM 分辨率和 ADC 速度業(yè)界領(lǐng)先的新器件
- 意法半導(dǎo)體STM32MP23x:突破成本限制的工業(yè)AI應(yīng)用核心
- 意法半導(dǎo)體推出用于匹配遠(yuǎn)距離無線微控制器STM32WL33的集成的匹配濾波芯片
- ESP32開發(fā)板連接TFT顯示屏ST7789跳坑記
- 如何讓ESP32支持analogWrite函數(shù)
- LGVL配合FreeType為可變字體設(shè)置字重-ESP32篇
- 使用樹莓派進(jìn)行 ESP32 Jtag 調(diào)試
- ESP32怎么在SPIFFS里面存儲html,css,js文件,以及網(wǎng)頁和arduino的通訊
- ESP32 freeRTOS使用測試
- ARXML 規(guī)則下 ECU 總線通訊與 ADTF 測試方案
- 日產(chǎn)在歐洲推出第三代e-POWER技術(shù)
- 福特CEO更看好Waymo激光雷達(dá)方案:比特斯拉純視覺自動駕駛路線可靠
- 智元機(jī)器人兩大核心產(chǎn)品啟動規(guī)?;a(chǎn)
- 固態(tài)電池2026量產(chǎn)豪賭,真相還是泡沫?
- 100億元!湖北“下注”人形機(jī)器人產(chǎn)業(yè)
- 海外磷酸鐵鋰電池產(chǎn)能從0到1
- 基于多傳感器數(shù)據(jù)的自動駕駛仿真確定性驗(yàn)證
- 國芯科技發(fā)布全球首款48V安全氣囊芯片,引領(lǐng)智能汽車新紀(jì)元
- 亞馬遜全球部署100萬臺機(jī)器人
- 悉尼機(jī)場采用機(jī)器人進(jìn)行檢票,省時(shí)省力更便捷
- 科沃斯機(jī)器人,實(shí)現(xiàn)全智能機(jī)器人服務(wù),做到智生活,享人生
- 高仙與合作伙伴強(qiáng)強(qiáng)聯(lián)合,真正起到加快機(jī)器人商用化的步伐
- 機(jī)器人能夠產(chǎn)生意識嗎,擁有靈魂嗎?聽專家怎么說
- 業(yè)者看好下一波機(jī)器人爆發(fā)點(diǎn) 高精密、負(fù)載小是趨勢
- 華為Mate 20 X 5G版電池反而變小,會否影響續(xù)航
- 榮耀20 Pro曝光 后置四攝或搭載P30同款傳感器
- 魅族手機(jī)已申請升降攝像頭專利
- 三星Galaxy Fold屏幕已通過萊茵護(hù)眼認(rèn)證
- iPhone XI或搭載全新科技 隱藏式背部三攝