一 前言

最近搞了两个项目,调了一版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获取全部的“汽车品牌以及车型”数据。 废话不多说,具体实现思路和详细逻辑,笔者将在正文结合完整代码进行详细介绍。接下来,跟着笔者直接往下看正文详…