軟件IIC和硬件IIC的主要區別,用標準庫舉例!

學習交流792125321,歡迎一起加入討論!

在學習iic的時候,我們經常會遇到軟件 I2C和硬件 I2C,它兩到底有什么區別呢?

軟件 I2C(模擬 I2C)和硬件 I2C(外設 I2C)是兩種實現 I2C 總線通信的方式,核心區別在于 ?是否依賴微控制器(MCU)內置的硬件 I2C 外設。以下是詳細對比及標準庫(以 STM32 標準外設庫為例)的實現差異:

?1. 核心區別

?特性?軟件 I2C?硬件 I2C
?實現方式通過 GPIO 引腳模擬 I2C 時序(軟件控制)使用 MCU 內置的硬件 I2C 外設(硬件控制)
?CPU 占用高(需 CPU 持續操作 GPIO)低(硬件自動完成時序,CPU 可處理其他任務)
?時序精度依賴軟件延時,精度較低由硬件時鐘控制,精度高且穩定
?開發復雜度簡單(無需配置復雜寄存器)復雜(需初始化外設、處理中斷/DMA)
?靈活性高(可適配任意 GPIO 引腳)低(必須使用硬件 I2C 外設的固定引腳)
?速度較慢(受限于軟件延時)較快(支持標準模式 100kHz、快速模式 400kHz+)
?兼容性通用性強(可適配不同 MCU)依賴具體 MCU 的硬件支持

?2. 標準庫實現對比(以 STM32F1 標準外設庫為例)?

?(1) 硬件 I2C 實現

硬件 I2C 使用 STM32 內置的 I2C 外設,需配置時鐘、引腳復用、中斷/DMA 等。

代碼示例:初始化硬件 I2C1(標準模式,100kHz)?

#include "stm32f10x_i2c.h"void I2C_Hardware_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;I2C_InitTypeDef I2C_InitStruct;// 使能時鐘(I2C1 和 GPIOB)RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 配置 GPIOB6 (SCL) 和 GPIOB7 (SDA) 為復用開漏模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; // 復用開漏GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStruct);// 配置 I2C1I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 占空比 16:9I2C_InitStruct.I2C_OwnAddress1 = 0xA0;          // 主機地址(可忽略)I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;        // 啟用應答I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStruct.I2C_ClockSpeed = 100000;         // 100kHzI2C_Init(I2C1, &I2C_InitStruct);// 啟用 I2C1I2C_Cmd(I2C1, ENABLE);
}// 發送數據函數(需處理狀態標志和中斷)
void I2C_WriteByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {I2C_GenerateSTART(I2C1, ENABLE);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Transmitter);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, regAddr);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, data);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);
}
?(2) 軟件 I2C 實現

通過 GPIO 手動控制 SCL 和 SDA 引腳電平,模擬 I2C 時序。

代碼示例:模擬 I2C 時序(使用 GPIOB8 和 GPIOB9)?

#include "stm32f10x_gpio.h"// 定義 SCL 和 SDA 引腳
#define SOFT_I2C_SCL_PIN    GPIO_Pin_8
#define SOFT_I2C_SDA_PIN    GPIO_Pin_9
#define SOFT_I2C_PORT       GPIOB// 初始化 GPIO
void Soft_I2C_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// 配置 SCL 和 SDA 為開漏輸出模式GPIO_InitStruct.GPIO_Pin = SOFT_I2C_SCL_PIN | SOFT_I2C_SDA_PIN;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD; // 開漏輸出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SOFT_I2C_PORT, &GPIO_InitStruct);// 初始拉高 SCL 和 SDAGPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);
}// 微秒級延時函數(需根據實際時鐘調整)
void Delay_us(uint32_t us) {us *= 72; // 假設主頻為 72MHzwhile (us--) __NOP();
}// 發送起始信號
void Soft_I2C_Start(void) {GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);Delay_us(5);GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);
}// 發送停止信號
void Soft_I2C_Stop(void) {GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);Delay_us(5);GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);Delay_us(5);GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);
}// 發送一個字節
void Soft_I2C_WriteByte(uint8_t data) {for (int i = 0; i < 8; i++) {if (data & 0x80) {GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);} else {GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);}Delay_us(2);GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);Delay_us(5);GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);data <<= 1;}// 等待從機應答(省略應答檢查)GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SDA_PIN);Delay_us(2);GPIO_SetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);Delay_us(5);GPIO_ResetBits(SOFT_I2C_PORT, SOFT_I2C_SCL_PIN);
}

?3. 適用場景

?場景?推薦方式?原因
高速通信(>100kHz)硬件 I2C依賴硬件時序精度,避免軟件延時誤差
多任務系統硬件 I2C減少 CPU 占用,支持 DMA/中斷
引腳資源緊張硬件 I2C必須使用固定引腳,避免浪費 GPIO
適配非標準 I2C 設備軟件 I2C可靈活調整時序(如長延時、非標準協議)
硬件 I2C 外設不可用軟件 I2C解決硬件資源沖突或兼容性問題

?4. 常見問題

  • ?硬件 I2C 初始化失敗
    檢查時鐘配置、引腳復用、上拉電阻(硬件 I2C 需要外部上拉,通常 4.7kΩ)。

  • ?軟件 I2C 通信不穩定
    調整延時函數精度,確保 SCL/SDA 邊沿時間符合設備要求。

  • ?速度瓶頸
    軟件 I2C 通常無法超過 100kHz,硬件 I2C 可支持 400kHz(Fast Mode)或更高。


?總結

  • ?硬件 I2C:適合高速、高穩定性場景,但開發復雜且依賴固定引腳。
  • ?軟件 I2C:靈活簡單,但占用 CPU 資源且速度受限。
    根據項目需求選擇合適方案:優先使用硬件 I2C 提升性能,若硬件資源不足或需要特殊時序,則用軟件模擬。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/897504.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897504.shtml
英文地址,請注明出處:http://en.pswp.cn/news/897504.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

店匠科技攜手 PayPal 升級支付體驗,助力獨立站商家實現全球增長

在全球化電商競爭加劇的背景下,獨立站為無數商戶插上了通向事業成功的翅膀。然而,搭建店鋪框架容易,真正實現有效運營卻充滿挑戰。只有當各個環節如齒輪般嚴絲合縫,獨立站運營才能更好地助推行進,實現穩健增長。如今,獨立站商家面臨著全鏈路運營的多重挑戰。從品牌塑造、營銷推…

密碼學 網絡安全 科普 網絡安全密碼技術

網絡加密包括密碼技術和網絡加密方法兩個方面。 一、 密碼技術   密碼技術一般分為常規密碼和公鑰密碼。   常規密碼是指收信方和發信方使用相同的密鑰&#xff0c;即加密密鑰和解密密鑰是相同或等價的。比較著名的常規密碼算法有DES及其各種變形、IDEA、FEAL、Skipjack…

P8686 [藍橋杯 2019 省 A] 修改數組--并查集 or Set--lower_bound()的解法!!!

P8686 [藍橋杯 2019 省 A] 修改數組--并查集 題目 并查集解析代碼【并查集解】 Set 解法解析lower_bound代碼 題目 并查集解析 首先先讓所有的f&#xff08;i&#xff09;i&#xff0c;即每個人最開始的祖先都是自己&#xff0c;然后就每一次都讓輪到那個數的父親1&#xff08…

Anaconda中虛擬環境安裝g++和gcc相同版本

安裝torchSDF的時候遇到的&#xff0c;這是g和gcc版本不一致的問題 gcc: fatal error: cannot execute cc1plus: execvp: No such file or directory compilation terminated.查看gcc, g版本 gcc --version | head -n1 g --version | head -n1發現gcc的是anaconda中的&#x…

C++編程:進階階段—4.2對象

目錄 4.2 對象特征 4.2.1 構造函數和析構函數 4.2.2 構造函數的分類 4.2.3 拷貝函數調用時機 4.2.4 構造函數調用規則 4.2.5 深拷貝與淺拷貝 4.2.6 初始化列表 4.2.7 類對象作為類成員 4.2.8 靜態成員 4.2.9 成員變量和成員函數的存儲 4.2.10 this指針 4.2.11 空指針…

【MySQL_04】數據庫基本操作(用戶管理--配置文件--遠程連接--數據庫信息查看、創建、刪除)

文章目錄 一、MySQL 用戶管理1.1 用戶管理1.11 mysql.user表詳解1.12 添加用戶1.13 修改用戶權限1.14 刪除用戶1.15 密碼問題 二、MySQL 配置文件2.1 配置文件位置2.2 配置文件結構2.3 常用配置參數 三、MySQL遠程連接四、數據庫的查看、創建、刪除4.1 查看數據庫4.2 創建、刪除…

配置 Thunderbird 以使用 outlook 郵箱

配置 Thunderbird 以使用 outlook 郵箱 thunder bird 作為郵件客戶端非常好用&#xff0c;不用每次登錄郵箱網頁端查看郵件&#xff0c;直接打開配置好的 thunder bird 即可免登錄查看郵件。 0. 什么是 Thunder Bird ? https://www.thunderbird.net/zh-CN/ Thunderbird 創立…

邊緣計算的業務種類劃分

Pcdn的業務可以根據不同的分類標準來劃分 一、按線路類型劃分 匯聚模式&#xff1a;一個地方有多條線路&#xff0c;業務種類較多。通常使用X86或X99主板組裝的服務器&#xff0c;或各品牌的準系統服務器。收益通常比單線模式更高。 單線模式&#xff1a;一個地方只有一條線路&…

服務器數據恢復—raid5陣列中硬盤出現壞道的數據恢復流程

服務器故障情況&#xff1a; 某公司一臺服務器中有一組多塊硬盤組成的磁盤陣列。磁盤陣列中有2塊硬盤出現故障離線&#xff0c;服務器崩潰&#xff0c;上層數據丟失。 硬件檢測&#xff1a; 硬件工程師對客戶服務器內的所有硬盤進行物理故障檢測&#xff0c;最終確認這2塊硬盤…

Linux:多線程(三.POSIX信號量、生產消費模型、線程池)

目錄 1. 生產者消費者模型 1.1 阻塞隊列(BlockingQueue) 1.2 一個實際應用的例子 2. POSIX信號量 2.1 引入 2.2 回顧加深理解信號量 2.3 信號量的操作接口 3. 基于循環隊列的生產消費模型 3.1 循環隊列 3.2 整個項目 4. 線程池 4.1 概念 4.2 線程池實現 1. 生產者…

關于前后端整合和打包成exe文件的個人的總結和思考

前言 感覺有很多東西&#xff0c;不知道寫什么&#xff0c;隨便寫點吧。 正文 前后端合并 就不說怎么開發的&#xff0c;就說點個人感覺重要的東西。 前端用ReactViteaxios隨便寫一個demo&#xff0c;用于CRUD。 后端用Django REST Framework。 設置前端打包 import { …

Android15 Camera框架中的StatusTracker

StatusTracker介紹 StatusTracker是Android15 Camera框架中用來協調Camera3各組件之間狀態轉換的類。 StatusTracker線程名&#xff1a;std::string("C3Dev-") mId "-Status" Camera3 StatusTracker工作原理 StatusTracker實現批處理&#xff08;狀態…

利用OpenResty攔截SQL注入

需求 客戶的一個老項目被相關部門檢測不安全&#xff0c;報告為sql注入。不想改代碼&#xff0c;改項目&#xff0c;所以想到利用nginx去做一些數據校驗攔截。也就是前端傳一些用于sql注入的非法字符或者數據庫的關鍵字這些&#xff0c;都給攔截掉&#xff0c;從而實現攔截sql…

警惕AI神話破滅:深度解析大模型缺陷與禁用場景指南

摘要 當前AI大模型雖展現強大能力&#xff0c;但其本質缺陷可能引發系統性風險。本文從認知鴻溝、數據困境、倫理雷區、技術瓶頸四大維度剖析大模型局限性&#xff0c;揭示醫療診斷、法律決策等8類禁用場景&#xff0c;提出可信AI建設框架與用戶防護策略。通過理論分析與實操案…

顛覆語言認知的革命!神經概率語言模型如何突破人類思維邊界?

顛覆語言認知的革命&#xff01;神經概率語言模型如何突破人類思維邊界&#xff1f; 一、傳統模型的世紀困境&#xff1a;當n-gram遇上"月光族難題" 令人震驚的案例&#xff1a;2012年Google語音識別系統將 用戶說&#xff1a;“我要還信用卡” 系統識別&#xff…

【Linux】詳談 基礎I/O

目錄 一、理解文件 狹義的理解&#xff1a; 廣義理解&#xff1a; 文件操作的歸類認知 系統角度 二、系統文件I/O 2.1 標志位的傳遞 系統級接口open ?編輯 open返回值 寫入文件 讀文件 三、文件描述符 3.1&#xff08;0 & 1 & 2&#xff09; 3.2 文件描…

超分之DeSRA

Desra: detect and delete the artifacts of gan-based real-world super-resolution models.DeSRA&#xff1a;檢測并消除基于GAN的真實世界超分辨率模型中的偽影Xie L, Wang X, Chen X, et al.arXiv preprint arXiv:2307.02457, 2023. 摘要 背景&#xff1a; GAN-SR模型雖然…

Vue3 Pinia 符合直覺的Vue.js狀態管理庫

Pinia 符合直覺的Vue.js狀態管理庫 什么時候使用Pinia 當兩個關系非常遠的組件&#xff0c;要傳遞參數時使用Pinia組件的公共參數使用Pinia

Web Worker如何在本地使用

首先了解一下什么是Web Worker Web Worker 是一種在后臺線程中運行 JavaScript 的機制&#xff0c;允許你在不阻塞主線程的情況下執行耗時的任務。這對于保持網頁的響應性和流暢性非常重要&#xff0c;特別是在需要進行復雜計算或大量數據處理時。 主要特點 多線程&#xff1…

Javaweb后端文件上傳@value注解

文件本地存儲磁盤 阿里云oss準備工作 阿里云oss入門程序 要重啟一下idea&#xff0c;上面有cmd 阿里云oss案例集成 優化 用spring中的value注解