自用模拟I2C的实现

发布时间:2026/10/25 14:01:11

自用模拟I2C的实现 1.头文件#define GPIO_PIN_X #define SDA_IN GPIO-PortC_OutputEN | GPIO_PIN_X;gpio_set_portpull(GPIO_C,GPIO_PIN_X,GPIO_NOPULL); #define SDA_OUT GPIO-PortC_OutputEN ~ GPIO_PIN_X; #define SDA_DATA() gpio_read_pin(GPIO_C, GPIO_PIN_X) #define SDA_H gpio_write_pin(GPIO_C, GPIO_PIN_X, GPIO_PIN_SET) #define SDA_L gpio_write_pin(GPIO_C, GPIO_PIN_X, GPIO_PIN_CLEAR) // IIC所有操作函数 void IIC_Start(void); void IIC_Stop(void); uint8_t IIC_Wait_Ack(void); void IIC_Put_Ack(uint8_t Ack); void IIC_Send_Byte(char Data); uint8_t IIC_Read_Byte(void); unsigned char I2C_WriteByte(uint8_t Master_addr, uint8_t Send_addr, uint8_t data); unsigned char I2C_ReadByte(uint8_t Master_addr, uint8_t Send_addr); unsigned char I2CWrite_Sequence(uint8_t Master_addr, uint8_t *wit_data, uint8_t sequence_length); unsigned char I2CRead_Sequence(uint8_t Master_addr, uint8_t *reg_value, uint8_t sequence_length);2.源码/************************************模拟I2C******************************************/ #define I2C_Delay_Time 5 // 10us // 产生IIC起始信号 void IIC_Start(void) { SDA_OUT; SCL_H; I2Cdelay(I2C_Delay_Time); SDA_H; I2Cdelay(I2C_Delay_Time); SDA_L; I2Cdelay(I2C_Delay_Time); SCL_L; I2Cdelay(I2C_Delay_Time); } // 产生IIC停止信号 void IIC_Stop(void) { SDA_OUT; SDA_L; I2Cdelay(I2C_Delay_Time); SCL_H; I2Cdelay(I2C_Delay_Time); SDA_H; I2Cdelay(I2C_Delay_Time); } // 等待数据接收方反馈ACK // 成功返回0 失败返回1 uint8_t IIC_Wait_Ack(void) { uint16_t wait_time 0; uint8_t ack_nack 0; SCL_L; I2Cdelay(I2C_Delay_Time); SDA_IN; // 释放总线 等待从机拉低 I2Cdelay(I2C_Delay_Time); SCL_H; I2Cdelay(I2C_Delay_Time); while (SDA_DATA()) { wait_time; if (wait_time 200) // 时间过长 退出等待 { ack_nack 1; break; } } SCL_L; SDA_OUT; I2Cdelay(I2C_Delay_Time); return ack_nack; } // 产生ACK应答 // 发送ACK就是在SDA0时 SCL由0变成1 // 发送NACK就是在SDA1时SCL由0变成1 void IIC_Put_Ack(uint8_t Ack) { SDA_OUT; I2Cdelay(I2C_Delay_Time); if (Ack 0) SDA_L; // 应答ACK else SDA_H; // 无应答NACK I2Cdelay(I2C_Delay_Time); SCL_H; I2Cdelay(I2C_Delay_Time); SCL_L; I2Cdelay(I2C_Delay_Time); } // 主设备发送一个字节 void IIC_Send_Byte(char Data) { char i; SDA_OUT; for (i 0; i 8; i) { SCL_L; if (Data 0x80) SDA_H; else SDA_L; Data Data 1; I2Cdelay(I2C_Delay_Time); SCL_H; I2Cdelay(I2C_Delay_Time); } SCL_L; I2Cdelay(I2C_Delay_Time); } // 主设备从从设备读一个字节 uint8_t IIC_Read_Byte(void) { uint8_t i, Data; SCL_L; SDA_IN; // 将SDA设置为输入 I2Cdelay(I2C_Delay_Time); for (i 0; i 8; i) { SCL_H; Data 1; if (SDA_DATA()) Data | 0x01; else Data 0xFE; I2Cdelay(I2C_Delay_Time); SCL_L; I2Cdelay(I2C_Delay_Time); } SDA_OUT; return Data; } // I2C主设备数据发送 // 有应答 0 失败 1 unsigned char I2C_WriteByte(uint8_t Master_addr, uint8_t Send_addr, uint8_t data) { IIC_Start(); IIC_Send_Byte(((Master_addr 1) 0xFE)); // I2C7位地址 if (IIC_Wait_Ack() 0) return 1; IIC_Send_Byte(Send_addr); if (IIC_Wait_Ack() 0) return 1; IIC_Send_Byte(data); if (IIC_Wait_Ack() 0) return 1; IIC_Stop(); return 0; } // I2C主设备数据读取 // 有应答data 失败 1 unsigned char I2C_ReadByte(uint8_t Master_addr, uint8_t Send_addr) // 读寄存器或读数据 { unsigned char reg_value; IIC_Start(); IIC_Send_Byte(((Master_addr 1) 0xFE)); // 主设备地址 if (IIC_Wait_Ack()) return 1; IIC_Send_Byte(Send_addr); if (IIC_Wait_Ack()) return 1; IIC_Start(); IIC_Send_Byte(((Master_addr 1) | 0x01)); // 读器件地址 if (IIC_Wait_Ack()) return 1; reg_value IIC_Read_Byte(); IIC_Stop(); return reg_value; } // I2C的连续写 unsigned char I2CWrite_Sequence(uint8_t slave_addr, uint8_t reg_addr, uint8_t *write_data, uint8_t data_len) { unsigned char i; IIC_Start(); // 发送写器件地址 IIC_Send_Byte(slave_addr 1); if (IIC_Wait_Ack()) { IIC_Stop(); return 1; } // 发送寄存器起始地址 IIC_Send_Byte(reg_addr); if (IIC_Wait_Ack()) { IIC_Stop(); return 2; } // 连续发送数据 for (i 0; i data_len; i) { IIC_Send_Byte(write_data[i]); if (IIC_Wait_Ack()) { IIC_Stop(); return 3; } } IIC_Stop(); return 0; } // I2C的连续读 unsigned char I2CRead_Sequence(uint8 slave_addr, uint8 reg_addr, uint8 *reg_value, uint8 sequence_length) { unsigned char i; IIC_Start(); // 写器件地址 IIC_Send_Byte(slave_addr 1); if (IIC_Wait_Ack()) { IIC_Stop(); return 1; } // 写寄存器地址 IIC_Send_Byte(reg_addr); if (IIC_Wait_Ack()) { IIC_Stop(); return 1; } // 重复起始条件 IIC_Start(); // 读器件地址 IIC_Send_Byte((slave_addr 1) | 0x01); if (IIC_Wait_Ack()) { IIC_Stop(); return 1; } // 读取数据 for (i 0; i sequence_length; i) { reg_value[i] IIC_Read_Byte(); if (i sequence_length - 1) IIC_Put_Ack(0); // ACK else IIC_Put_Ack(1); // NACK } IIC_Stop(); return 0; } void I2Cdelay(int time) { co_delay_10us(time); }
延伸阅读

更多相关文章

2026/10/25 1:22:12

CANN坐标转换函数Crd2Idx

Crd2Idx 产品支持情况 产品 是否支持 Ascend 950PR/Ascend 950DT √ Atlas A3 训练系列产品/Atlas A3 推理系列产品√ Atlas A2 训练系列产品/Atlas A2 推理系列产品√ Atlas 200I/500 A2 推理产品x Atlas 推理系列产品AI Core x Atlas 推理系列产品Vector Core x Atlas 训练系…

2026/10/25 13:59:33

TensorFlow+OpenCV实现实时表情识别系统开发指南

1. 项目概述:实时表情识别的技术价值与应用场景人脸表情识别作为计算机视觉领域的重要分支,近年来在智能交互、心理健康监测、安防系统等领域展现出巨大潜力。这个项目通过结合TensorFlow深度学习框架与OpenCV计算机视觉库,构建了一套能够实时…

2026/10/25 13:59:33

印刷体数字字母识别:传统与深度学习方案对比

1. 项目背景与核心需求印刷体数字和字母识别是计算机视觉领域的经典问题,也是深度学习技术落地的典型场景。这个毕设项目结合了传统机器学习与深度学习方法,旨在构建一个能够准确识别印刷体数字和字母的智能系统。在实际应用中,这类技术可以广…

2026/10/25 13:59:33

Seedream爆火背后:AI创作工具的伦理困境与隐私保护指南

1. 从Seedream爆火说起:AI创作工具到底在改变什么Seedream这波热度来得又快又猛。朋友圈、设计群、自媒体圈子里,几乎一夜之间都在讨论它生成的图像质量、风格多样性和出图速度。作为一个长期关注AI创作工具的人,我第一时间上手试了试&#x…

2026/10/25 13:59:33

Ray 2.59 调度更新怎么看:先限制在途任务,再追吞吐数字

任务提交成功得很快,往往意味着客户端积累得很快。调度系统没有因此获得无限 worker,也没有因此消除参数对象、返回对象和重试记录的内存开销。给大模型预处理提交几十万份切片之前,应先回答:允许同时存在多少份未完成工作&#x…

2026/10/25 13:54:33

AI挖因子:大语言模型如何辅助量化选股与因子挖掘

简介:这份国金证券金融工程专题报告聚焦大语言模型在量化选股中的落地路径,面向具备一定因子研究基础的量化从业者与金融工程学习者,系统回答如何借助ChatGPT完成高频因子挖掘与策略构建。压缩包内为1个PDF文件,约2.16MB&#xff…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑