stm32 freertos下基于 hal庫的模擬I2C驅動實現

一 前言

最近搞了兩個項目,調了一版freertos下基于hal庫得模擬I2C驅動,非常實用,直接拷貝就能用,這里做下記錄,主要用到如下四個文件:

  • delay.c
  • delay.h
  • i2cc.c
  • i2cc.h

二 代碼實現

delay.c

#include "main.h"
#include "delay.h"// achieve by DWT
void delay_init(void)
{CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;  // 使能 DWT 外設DWT->CYCCNT = 0;                                 // 清除計數器DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;             // 使能 cycle counter
}void delay_us(uint16_t us)
{uint32_t cycles = us * (SystemCoreClock / 1000000);  // 72MHz 時,cycles = us × 72uint32_t start = DWT->CYCCNT;while ((DWT->CYCCNT - start) < cycles);
}void delay_ms(uint16_t ms)
{for(uint32_t i = 0;i < ms;i++)delay_us(1000);
}
delay.h
#ifndef BSP_DELAY_H_
#define BSP_DELAY_H_void delay_init(void);       /* 初始化延遲函數 */
void delay_ms(uint16_t nms);            /* 延時nms */
void delay_us(uint16_t nus);            /* 延時nus */#endif /* BSP_DELAY_H_ */
i2cc.c
#include "i2cc.h"
#include "delay.h"/*** @brief       IIC延時函數,用于控制IIC讀寫速度* @param       無* @retval      無*/
static void iic_delay(void)
{delay_us(2);    /* 2us的延時, 讀寫速度在250Khz以內 */
}/*** @brief       產生IIC起始信號* @param       無* @retval      無*/
void iic_start(void)
{IIC_SDA(1);IIC_SCL(1);iic_delay();IIC_SDA(0);     /* START信號: 當SCL為高時, SDA從高變成低, 表示起始信號 */iic_delay();IIC_SCL(0);     /* 鉗住I2C總線,準備發送或接收數據 */iic_delay();
}/*** @brief       產生IIC停止信號* @param       無* @retval      無*/
void iic_stop(void)
{IIC_SDA(0);     /* STOP信號: 當SCL為高時, SDA從低變成高, 表示停止信號 */iic_delay();IIC_SCL(1);iic_delay();IIC_SDA(1);     /* 發送I2C總線結束信號 */iic_delay();
}/*** @brief       等待應答信號到來* @param       無* @retval      1,接收應答失敗*              0,接收應答成功*/
uint8_t iic_wait_ack(void)
{uint8_t waittime = 0;uint8_t rack = 0;IIC_SDA(1);     /* 主機釋放SDA線(此時外部器件可以拉低SDA線) */iic_delay();IIC_SCL(1);     /* SCL=1, 此時從機可以返回ACK */iic_delay();while (IIC_READ_SDA)    /* 等待應答 */{waittime++;if (waittime > 250){iic_stop();rack = 1;break;}}IIC_SCL(0);     /* SCL=0, 結束ACK檢查 */iic_delay();return rack;
}/*** @brief       產生ACK應答* @param       無* @retval      無*/
void iic_ack(void)
{IIC_SDA(0);     /* SCL 0 -> 1  時 SDA = 0,表示應答 */iic_delay();IIC_SCL(1);     /* 產生一個時鐘 */iic_delay();IIC_SCL(0);iic_delay();IIC_SDA(1);     /* 主機釋放SDA線 */iic_delay();
}/*** @brief       不產生ACK應答* @param       無* @retval      無*/
void iic_nack(void)
{IIC_SDA(1);     /* SCL 0 -> 1  時 SDA = 1,表示不應答 */iic_delay();IIC_SCL(1);     /* 產生一個時鐘 */iic_delay();IIC_SCL(0);iic_delay();
}/*** @brief       IIC發送一個字節* @param       data: 要發送的數據* @retval      無*/
void iic_send_byte(uint8_t data)
{uint8_t t;for (t = 0; t < 8; t++){IIC_SDA((data & 0x80) >> 7);    /* 高位先發送 */iic_delay();IIC_SCL(1);iic_delay();IIC_SCL(0);data <<= 1;     /* 左移1位,用于下一次發送 */}IIC_SDA(1);         /* 發送完成, 主機釋放SDA線 */
}/*** @brief       IIC讀取一個字節* @param       ack:  ack=1時,發送ack; ack=0時,發送nack* @retval      接收到的數據*/
uint8_t iic_read_byte(uint8_t ack)
{uint8_t i, receive = 0;for (i = 0; i < 8; i++ )    /* 接收1個字節數據 */{receive <<= 1;  /* 高位先輸出,所以先收到的數據位要左移 */IIC_SCL(1);iic_delay();if (IIC_READ_SDA){receive++;}IIC_SCL(0);iic_delay();}if (!ack){iic_nack();     /* 發送nACK */}else{iic_ack();      /* 發送ACK */}return receive;
}
i2cc.h

#ifndef _I2CC_H_
#define _I2CC_H_#include "main.h"
#include "data.h"/******************************************************************************************/
/* 引腳 定義 */#define IIC_SCL_GPIO_PORT               I2C_SCL_GPIO_Port
#define IIC_SCL_GPIO_PIN                I2C_SCL_Pin
#define IIC_SDA_GPIO_PORT               I2C_SDA_GPIO_Port
#define IIC_SDA_GPIO_PIN                I2C_SDA_Pin
/******************************************************************************************//* IO操作 */
#define IIC_SCL(x)        do{ x ? \HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT, IIC_SCL_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* SCL */#define IIC_SDA(x)        do{ x ? \HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN, GPIO_PIN_RESET); \}while(0)       /* SDA */#define IIC_READ_SDA     HAL_GPIO_ReadPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) /* 讀取SDA *//* IIC所有操作函數 */
void iic_start(void);           /* 發送IIC開始信號 */
void iic_stop(void);            /* 發送IIC停止信號 */
void iic_ack(void);             /* IIC發送ACK信號 */
void iic_nack(void);            /* IIC不發送ACK信號 */
uint8_t iic_wait_ack(void);     /* IIC等待ACK信號 */
void iic_send_byte(uint8_t txd);/* IIC發送一個字節 */
uint8_t iic_read_byte(unsigned char ack);/* IIC讀取一個字節 */
void get_tempare(void);#endif /* _I2CC_H_ */

三 總結

使用時,cubeIDE配置相應的GPIO管腳,SDA管腳要配置為開漏,然后main函數里面調用delay_init啟動DWT模塊,再調用I2C相關函數組成操作接口即可。

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

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

相關文章

文心大模型 4.5 系列開源首發:技術深度解析與應用指南

文心大模型 4.5 系列開源首發&#xff1a;技術深度解析與應用指南 2025 年 6 月 30 日&#xff0c;百度正式在國內領先的開源平臺 GitCode 發布文心大模型 4.5 系列開源模型。此次開源不僅覆蓋了從數億到數百億參數的多種規模&#xff0c;還在多模態理解、指令遵循、世界知識記…

智能制造——58頁智慧工廠解決方案【附全文閱讀】

適應人群為制造業企業管理者、技術人員及規劃改造團隊。主要內容是以 JetLinks IoT 平臺為基礎&#xff0c;構建涵蓋設備層、網絡層、平臺層和應用層的智慧工廠體系&#xff0c;通過多種通信協議實現設備互聯&#xff0c;利用大數據、AI 等技術實現數據采集與處理、設備全生命周…

DeepSeek16-open-webui Pipelines開發填坑

一、虛擬環境安裝 mkdir open_webui_pipelines cd open_webui_pipelines python -m venv py3119_env call py3119_env\Scripts\activate 二、下載服務以及安裝依賴 git clone https://github.com/open-webui/pipelines.git cd pipelines pip install -r requirements.txt三、…

蘭亭妙微APP 界面設計與軟件開發綜合服務商

蘭亭妙微作為 APP 界面設計公司與軟件開發公司&#xff0c;自 2011 年成立以來&#xff0c;由清華團隊主導&#xff0c;在軟件和互聯網 UI/UE 設計開發領域發展 16 年&#xff0c;積累了一定的行業經驗。 在 APP 界面設計方面&#xff0c;我們的團隊包含交互設計師、用戶體驗相…

【算法】動態規劃:1137. 第 N 個泰波那契數

1137. 第 N 個泰波那契數 簡單 相關標簽 premium lock icon 相關企業 提示 泰波那契序列 Tn 定義如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的條件下 Tn3 Tn Tn1 Tn2 給你整數 n&#xff0c;請返回第 n 個泰波那契數 Tn 的值。 示例 1&#xff1a; 輸入&am…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的校園家教兼職信息交流平臺管理系統,推薦!

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術&#xff0c;讓傳統數據信息的管理升級為軟件存儲&#xff0c;歸納&#xff0c;集中處理數據信息的管理方式。本校園家教兼職信息交流平臺就是在這樣的大環境下誕生&#xff0c;其可以幫助管理者在短時間內處理完畢龐大的…

vue-33(實踐練習:使用 Nuxt.js 和 SSR 構建一個簡單的博客)

實踐練習:使用 Nuxt.js 和 SSR 構建一個簡單的博客 使用 Nuxt.js 和 SSR 構建一個簡單的博客是鞏固你對服務器端渲染理解以及 Nuxt.js 如何簡化這一過程的好方法。這個練習將帶你完成設置基本博客結構、獲取數據并以用戶友好的格式展示,同時利用 SSR 的優勢來提升 SEO 和性能…

如何在 .Net 7 中使用 MQTT 客戶端

介紹 MQTT&#xff08;消息隊列遙測傳輸&#xff09;是一種輕量級消息傳遞協議&#xff0c;專為資源受限的環境而設計。MQTT 廣泛應用于物聯網 (IoT) 和機器對機器 (M2M) 通信。 本文將討論如何在 .NET 7 中實現 MQTT 消費者。我們將使用 MQTTnet 庫&#xff0c;這是 C# 中的高…

云上攻防—Docker安全容器逃逸特權模式危險掛載

前言 之前分享的是云服務安全&#xff0c;今天開始云原生安全&#xff0c;安全道路依舊很長。 什么是Docker呢&#xff0c;它是開源的容器化平臺&#xff0c;用于開發、部署和運行應用程序。它通過將應用程序及其依賴項打包在輕量級的容器中&#xff0c;實現環境一致性、快速…

2025API 開發工具Apipost 與 Apifox深度對比

在當今數字化時代&#xff0c;API 開發是構建各類軟件應用的關鍵環節。Apipost 和 Apifox 作為兩款知名的 API 開發工具&#xff0c;它們在實際開發場景中表現究竟如何呢&#xff1f;接下來&#xff0c;讓我們從多個功能點進行深入對比。 一、API 設計功能 接口定義與參數設置…

從零開始搭建Windows AI開發環境:QWQ-32B部署+Cursor插件優化實戰

文章目錄 前言1.安裝Ollama2.QwQ-32B模型安裝與運行3.Cursor安裝與配置4. 簡單使用測試5. 調用本地大模型6. 安裝內網穿透7. 配置固定公網地址總結 前言 本方案提出了一種基于Windows系統的智能化開發平臺搭建策略&#xff0c;通過融合Cursor智能編程平臺、Ollama模型運行框架…

PostgreSQL 中,若需顯示 不在 `IN` 子句列表中的數據

在 PostgreSQL 中&#xff0c;若需顯示 不在 IN 子句列表中的數據&#xff0c;可以通過以下方法實現&#xff1a; 方法 1&#xff1a;使用 NOT IN&#xff08;注意 NULL 值&#xff09; 直接篩選不包含在 IN 列表中的記錄&#xff1a; SELECT * FROM your_table WHERE your_c…

嘉訊科技:醫療信息化、數字化、智能化三者之間的關系和區別

隨著技術的不斷發展&#xff0c;醫療行業也在發生著巨大的變化。在這個過程中&#xff0c;醫療信息化、數字化、智能化成為三個重要方向。這些變化不僅帶來了醫療技術的進步&#xff0c;而且大大提高了醫療服務的質量和效率。 一、醫療信息化 醫療信息化是指醫療行業應用信息技…

Windows VMWare Centos Docker部署Springboot應用

接上篇文章&#xff1a;Windows VMWare Centos環境下安裝Docker并配置MySql-CSDN博客文章瀏覽閱讀370次&#xff0c;點贊3次&#xff0c;收藏4次。Windows VMWare Centos環境下安裝Docker并配置MySqlhttps://blog.csdn.net/u013224722/article/details/148928081 一、新建Sprin…

JavaEE-Spring事務和事務的傳播機制

事務 什么是事務 事務是?組操作的集合, 是?個不可分割的操作. 事務會把所有的操作作為?個整體, ?起向數據庫提交或者是撤銷操作請求. 所以這組操作要么同時成功, 要么同時失敗. 為什么需要事務? 事務的操作 Spring 中事務的實現 創建好數據庫后就是配置數據庫相關的配…

共享經濟視域下社群經濟的本質重構:基于開源AI智能名片鏈動2+1模式S2B2C商城小程序源碼的實證研究

摘要&#xff1a;社群經濟在互聯網時代呈現爆發式增長&#xff0c;但傳統社群運營存在情感維系成本高、商業轉化路徑長、技術賦能不足等痛點。本文以共享經濟理論為框架&#xff0c;結合開源AI智能名片鏈動21模式S2B2C商城小程序源碼的技術實踐&#xff0c;提出“思想-資源-機會…

測試方法的分類

靜態測試 核心分類依據&#xff1a;根據是否執行程序分為靜態測試和動態測試 靜態測試方法 執行特征&#xff1a;不運行被測程序&#xff0c;通過人工檢查或工具分析進行測試 測試對象&#xff1a;主要針對文檔&#xff08;包括需求文檔、設計文檔等&#xff09;和源代碼 實…

查看CPU支持的指令集和特性

1&#xff09;gcc -c -Q -marchnative --helptarget 2&#xff09;結果 The following options are target specific: -m128bit-long-double [enabled] -m16 [disabled] -m32 [disabled…

【大模型應用開發】Unity結合大模型實現智能問答功能

零、最終效果 Unity結合大模型實現智能問答功能 一、文本自動換行效果 新建一個Text文本&#xff0c;設置文本的最大寬度 然后添加Content Size Fitter組件&#xff0c;Vertical Fit選擇Preferred Size 二、背景隨文本長度變化效果 新建一個Image作為文本的背景&#xff0…

Python爬蟲-爬取汽車之家全部汽車品牌及車型數據

前言 本文是該專欄的第64篇,后面會持續分享python爬蟲干貨知識,記得關注。 本文,筆者將基于汽車之家平臺,通過Python獲取全部的“汽車品牌以及車型”數據。 廢話不多說,具體實現思路和詳細邏輯,筆者將在正文結合完整代碼進行詳細介紹。接下來,跟著筆者直接往下看正文詳…