发布时间:2026/7/15 15:01:04
自用模拟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/7/15 14:56:01

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/7/15 15:41:10

CANN/asc-devkit remove_reference类型特性

remove_reference 产品支持情况产品 是否支持 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 A…

2026/7/15 15:41:10

Spring Boot+Vue+微信小程序全栈电商系统架构设计与实施指南

Spring BootVue微信小程序全栈电商系统架构设计与实施指南 【免费下载链接】litemall 又一个小商城。litemall Spring Boot后端 Vue管理员前端 微信小程序用户前端 Vue用户移动端 项目地址: https://gitcode.com/gh_mirrors/li/litemall 在数字化转型浪潮中&#xf…

2026/7/15 15:41:10

CANN/Ascend C标准库min函数

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

2026/7/15 15:41:10

从算力到实用性,全方位解析AI 主机选购指南要点

当下AI绘图、自动化办公、代码生成需求持续上涨,不少用户想要一台适配AI运行的小型设备,却不懂分辨产品优劣,一份完整的AI主机选购指南能够大幅降低踩坑概率。翻阅各类迷你主机排行榜、能打游戏的迷你主机性价比排行榜对比多款产品后&#xf…

2026/7/15 15:36:10

计算机毕业设计之jsp鲜花购物商城系统的设计与实现

当今社会已经步入了科学技术进步和经济社会快速发展的新时期,国际信息和学术交流也不断加强,计算机技术对经济社会发展和人民生活改善的影响也日益突出,人类的生存和思考方式也产生了变化。传统鲜花购物商城采取了人工的管理方法,…

2026/7/14 12:47:32

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/14 19:23:19

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/14 18:30:06

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/15 0:08:29

【LINUX】驱动

【LINUX驱动】【字符设备】【中断】【Platform】【网课 设备树】【GPIO】【PINCTRL】【INPUT】【IIC】【SPI】【网络驱动】【屏幕驱动】【一 设备树】【二 内核模块编译】【三 基本驱动框架】【四 Platform总线设备驱动框架】【五 驱动子系统】【六 综合】

2026/7/15 0:08:29

【1982-2026】全国高精度建筑轮廓|村级精度|SHP矢量

🔍 数据简介 本次分享1982-2026年全国村级精度建筑轮廓矢量数据,覆盖全国各省市区县,到村级别精细,为2026年最新实时采集成果,非网传仅60/77个城市的老旧数据。 数据含带高度/不带高度双版本,单体建筑边界精…

2026/7/15 0:08:29

【1975-2026】全国水系水路数据|河流/水库/运河|SHP矢量

🔍 数据简介 本次分享1975-2026年全国高精度水系水路矢量数据,覆盖全国全域,包含河流、水系、水库、运河、湿地、冰川、沟渠等全类别水文要素。 数据集包含双层矢量图层,字段分类清晰、要素齐全,支持2013-2026逐年完整…

2026/7/15 13:36:32

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…