当前位置: 首页 > news >正文

# 智融PD芯片I2C通信实战:从零实现高效可靠的模拟I2C驱动

🔥 智融PD芯片I2C通信实战:从零实现高效可靠的模拟I2C驱动

📋 概述

本文详细介绍了一个用于与智融PD芯片进行通信的模拟I2C驱动程序实现。该驱动通过GPIO模拟I2C协议,实现了完整的I2C通信功能,包括起始信号、停止信号、数据传输和应答检测等核心功能。

🛠️ 驱动程序基础函数

1. GPIO引脚配置

/* SDA引脚输出模式设置 */staticinlinevoidpd_sda_set_out_mode(structpd_i2c_bus_typedef*bus){gpio_init(PD_SDA_GPIO_PORT,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,PD_SDA_PIN);}/* SDA引脚输入模式设置 */staticinlinevoidpd_sda_set_in_mode(structpd_i2c_bus_typedef*bus){gpio_init(PD_SDA_GPIO_PORT,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,PD_SDA_PIN);}/* 获取SDA引脚状态 */staticinlineuint8_tget_sda(structpd_i2c_bus_typedef*bus){returngpio_input_bit_get(bus->gpiox,bus->sda_gpio_pin);}/* SDA引脚电平控制 */staticinlinevoidPD_SDA_L(structpd_i2c_bus_typedef*bus){gpio_bit_reset(bus->gpiox,bus->sda_gpio_pin);}staticinlinevoidPD_SDA_H(structpd_i2c_bus_typedef*bus){gpio_bit_set(bus->gpiox,bus->sda_gpio_pin);}/* SCL引脚电平控制 */staticinlinevoidPD_SCL_L(structpd_i2c_bus_typedef*bus){gpio_bit_reset(bus->gpiox,bus->scl_gpio_pin);}staticinlinevoidPD_SCL_H(structpd_i2c_bus_typedef*bus){gpio_bit_set(bus->gpiox,bus->scl_gpio_pin);}

IIC 起始信号

staticinlinevoidpd_i2c_start(structpd_i2c_bus_typedef*bus){pd_sda_set_out_mode(bus);PD_SDA_H(bus);bus->udelay(10);PD_SCL_H(bus);bus->udelay(10);PD_SDA_L(bus);bus->udelay(10);PD_SCL_L(bus);bus->udelay(10);}

IIC结束信号

staticinlinevoidpd_i2c_stop(structpd_i2c_bus_typedef*bus){bus->udelay(6);PD_SDA_L(bus);bus->udelay(6);PD_SCL_H(bus);bus->udelay(6);PD_SDA_H(bus);bus->udelay(6);PD_SDA_H(bus);pd_sda_set_out_mode(bus);}

IIC 重启信号

staticinlinevoidpd_i2c_restart(structpd_i2c_bus_typedef*bus){PD_SDA_H(bus);bus->udelay(6);PD_SCL_H(bus);bus->udelay(6);PD_SDA_L(bus);bus->udelay(6);PD_SCL_L(bus);bus->udelay(6);}

判断从机回复

/** * @brief pd_iic 检测响应,pd_iic * @param struct pd_i2c_bus_typedef *bus * @param NONE * @retval 返回 0 从机接收成功; 返回1,应答失败 */staticinlineuint8_tpd_i2c_check_ack(structpd_i2c_bus_typedef*bus){uint8_tack=0;uint16_tpd_chip_timeout=0;PD_SDA_H(bus);bus->udelay(5);PD_SCL_H(bus);bus->udelay(5);pd_sda_set_in_mode(bus);while(1==get_sda(bus)){pd_chip_timeout++;if(pd_chip_timeout>250){pd_i2c_stop(&pd_i2c_bus);ack=1;break;}}pd_sda_set_out_mode(bus);PD_SCL_L(bus);bus->udelay(5);returnack;}

发送检测响应

/** * @brief pd_iic 发送检测响应,iic 协议第9位为应答 * @param struct pd_i2c_bus_typedef *bus * @param ack 需要继续通信拉低0, 不需要继续通信拉高1 * @retval */staticinlinevoidpd_i2c_send_ack_Or_nack(structpd_i2c_bus_typedef*bus,intack){//int re_ack = 0;PD_SCL_L(bus);bus->udelay(10);if(ack){PD_SDA_L(bus);//继续通信}else{PD_SDA_H(bus);}bus->udelay(10);PD_SCL_H(bus);bus->udelay(10);PD_SCL_L(bus);bus->udelay(10);}

写单字节

//写单字节staticvoidpd_i2c_write_byte(structpd_i2c_bus_typedef*bus,uint8_tdata){uint8_ti=0;uint8_tdat=0;uint8_ttemps=0;dat=0x80;temps=data;for(i=0;i<8;i++){PD_SCL_L(bus);if(dat&temps)//对应位为一就发一{PD_SDA_H(bus);bus->udelay(WR_RD_DELAY_TIME);//延时一下PD_SCL_H(bus);bus->udelay(WR_RD_DELAY_TIME);//t(HIGH) Clock high period See Note 2 4.0~50 μs}else{PD_SDA_L(bus);bus->udelay(WR_RD_DELAY_TIME);//延时一下PD_SCL_H(bus);bus->udelay(WR_RD_DELAY_TIME);}dat=dat>>1;}PD_SCL_L(bus);bus->udelay(WR_RD_DELAY_TIME);PD_SDA_H(bus);//数据线拉高,为等待响应做准备bus->udelay(WR_RD_DELAY_TIME);}

读单字节

//读单字节staticuint8_tpd_i2c_read_byte(structpd_i2c_bus_typedef*bus){uint8_tmask;uint8_tdata=0;PD_SDA_H(bus);bus->udelay(10);pd_sda_set_in_mode(bus);for(mask=0x80;mask!=0;mask>>=1){PD_SCL_H(bus);bus->udelay(10);if(get_sda(bus)){data|=mask;}PD_SCL_L(bus);bus->udelay(10);}pd_sda_set_out_mode(bus);returndata;}

读寄存器

intpd_i2c_read_register(uint8_t*pd_data_buff,uint16_taddr,uint16_tlen){uint16_ti=0;// uint16_t data = 0;uint8_tsda_status=0;uint16_tstart_addr=0;// uint8_t start_temp = 0;start_addr=addr;pd_lock();//PD 读pd_i2c_start(&pd_i2c_bus);//开始pd_i2c_write_byte(&pd_i2c_bus,PD_I2C_WRITE_SLAVE_ADDR);//设备地址 0x3Cpd_i2c_bus.udelay(DLY_TIMER_1);sda_status=pd_i2c_check_ack(&pd_i2c_bus);//等待响应if(1==sda_status){pd_i2c_stop(&pd_i2c_bus);pd_i2c_stop(&pd_i2c_bus);pd_unlock();return(-1);}pd_i2c_bus.udelay(DLY_TIMER_1);pd_i2c_write_byte(&pd_i2c_bus,(uint8_t)start_addr);//数据地址pd_i2c_bus.udelay(DLY_TIMER_1);sda_status=pd_i2c_check_ack(&pd_i2c_bus);//等待响应if(1==sda_status){pd_i2c_stop(&pd_i2c_bus);pd_i2c_stop(&pd_i2c_bus);pd_unlock();return(-1);}pd_i2c_bus.udelay(DLY_TIMER_1);pd_i2c_restart(&pd_i2c_bus);//再次启动pd_i2c_write_byte(&pd_i2c_bus,PD_I2C_READ_SLAVE_ADDR);//设备地址 0x3Dsda_status=pd_i2c_check_ack(&pd_i2c_bus);//等待响应if(1==sda_status){pd_i2c_stop(&pd_i2c_bus);pd_i2c_stop(&pd_i2c_bus);pd_unlock();return(-1);}for(i=0;i<len;i++){pd_data_buff[i]=pd_i2c_read_byte(&pd_i2c_bus);//pd_i2c_bus.udelay(DLY_TIMER_2);pd_i2c_send_ack_Or_nack(&pd_i2c_bus,ACK_FLAG);}pd_i2c_bus.udelay(DLY_TIMER_1);pd_i2c_stop(&pd_i2c_bus);//停止pd_unlock();return0;}

写寄存器

/** * @brief PD 芯片写单字节 * @param register PD 芯片写寄存器 * @param p_data 数据指针 * @retval 异常返回 1,正常返回 0 * @note 软件模拟SMBUS协议 */uint8_tpd_i2c_write_register(uint8_t*pd_data_buff,uint16_taddr,uint16_tlen){uint16_ti=0;//uint16_t data = 0;uint8_tsda_status=0;uint16_tstart_addr=0;//uint8_t start_temp = 0;pd_lock();start_addr=addr;//PD 读pd_i2c_start(&pd_i2c_bus);//开始pd_i2c_write_byte(&pd_i2c_bus,PD_I2C_WRITE_SLAVE_ADDR);//设备地址 0x3Cpd_i2c_bus.udelay(DLY_TIMER_2);sda_status=pd_i2c_check_ack(&pd_i2c_bus);//等待响应if(1==sda_status){pd_unlock();returnsda_status;}pd_i2c_write_byte(&pd_i2c_bus,(uint8_t)start_addr);//数据地址pd_i2c_bus.udelay(DLY_TIMER_2);sda_status=pd_i2c_check_ack(&pd_i2c_bus);//等待响应if(1==sda_status){pd_unlock();returnsda_status;}pd_i2c_bus.udelay(DLY_TIMER_2);for(i=0;i<len;i++){pd_i2c_write_byte(&pd_i2c_bus,pd_data_buff[i]);pd_i2c_bus.udelay(DLY_TIMER_2);sda_status=pd_i2c_check_ack(&pd_i2c_bus);}pd_i2c_stop(&pd_i2c_bus);//停止pd_unlock();returnsda_status;}

🎯 结束语

通过本文的详细讲解,我们完成了智融PD芯片I2C通信驱动的完整实现。从GPIO引脚配置到I2C协议的核心时序控制,再到读写寄存器的完整流程,我们一步步构建了一个高效可靠的模拟I2C驱动。

📚 核心要点回顾

  1. GPIO配置:正确配置SDA和SCL引脚的输入输出模式是I2C通信的基础
  2. 时序控制:严格按照I2C协议的时序要求实现起始、停止、重启信号
  3. 应答机制:完善的应答检测和发送机制确保通信可靠性
  4. 读写操作:完整的读写寄存器函数封装了底层通信细节

💡 实际应用建议

  • 时序调整:根据实际硬件特性微调延时参数,优化通信速度
  • 错误处理:在生产环境中增加更完善的错误日志和重试机制
  • 性能优化:对于频繁的I2C操作,可以考虑使用DMA或硬件I2C外设

希望本文能为您的嵌入式开发工作提供实用的参考。如果在实际应用中遇到问题,欢迎在评论区交流讨论。祝您开发顺利!


本文代码已在多个实际项目中验证,具有良好的稳定性和可靠性。建议在实际使用时根据具体硬件平台进行适当调整。
`

http://www.jsqmd.com/news/1023348/

相关文章:

  • GIS工程师的机器学习实战:三个月掌握空间智能工作流
  • 2026:郫都专业除甲醛公司深度测评,甲醛检测治理怎么选?多项实测对比推荐成都肃醛环保科技有限公司 - 专注室内空气检测治理
  • 2026年6月昭通黄金回收靠谱商家筛选与变现避坑干货 - 余生黄金回收
  • SCMP培训学什么——供应商全生命周期管理从寻源到淘汰六阶段实战 - 众智商学院课程中心
  • 一文讲清,MES系统是什么意思?全面解析MES系统的核心功能
  • 网盘直链下载助手终极指南:一键获取九大网盘真实下载地址的技术解决方案
  • 终极指南:5分钟用Qt Material打造现代化桌面应用界面
  • 2026年中山企业老板力荐专利申请与无效律师 5位实战精选 - 本地品牌推荐
  • 本地 RAG 检索器:加载 FAISS 索引并实现语义搜索
  • AI Agent如何处理无预设流程业务?深度解析大模型自主规划的底层推理能力与架构落地实践
  • 2026年沈阳建筑器材租赁简析:脚手架/钢管/围挡/钢支撑/跳板/吊篮/钢管扣件/、沈阳高新区华洁钢支撑租赁站一站式配齐各类施工配套器材 - 海棠依旧大
  • 深圳值得推荐的设计奖代理机构 - 博客万
  • [特殊字符]️【万字深度干货】数字政府数字化转型规划信息化解决方案全解析——从国土空间规划重构到智能审批的完整技术路线(PPT)
  • 2026年 木托盘厂家推荐榜单:松木/免熏蒸/出口木托盘与IPPC热处理实力品牌大全 - 品牌发掘
  • VLM (4):connector
  • Debian滚动更新实践:Rolling Ridley混合发布架构
  • 榆林黄金回收怎么选靠谱商家 避坑实操干货 - 余生黄金回收
  • 流量监管与流量整形技术详解
  • 硬盘低级格式化工具深度解析:原理、风险与实战指南
  • 伊犁2026年6月黄金回收行情解读 正规商家辨别方法 - 余生黄金回收
  • 2026年6月昭通卖黄金不踩坑 正规回收行情与门店实测指南 - 余生黄金回收
  • 软考全攻略:从科目选择到实战技巧,助你高效备考与职业进阶
  • Gemini 3.5 Flash API 实测指南:绕过UI限制的工程化接入方法
  • 2026年6月六安卖黄金不被坑 正规回收价格与门店实测对比 - 余生黄金回收
  • 2026年北京场地电动车出租公司行业解析:电动老爷车、高尔夫球车、电动巡逻车、电动摆渡车、一站式电动观光车辆租赁、售卖及维保服务参考 - 海棠依旧大
  • 2026武汉市家用空调-中央空调等维修安装移机加氟-本地精选指南 -欧米到家 - 欧米到家
  • 自动驾驶出海新范式:技术引进与本地运营双轨落地
  • 终极XXMI启动器完整指南:一站式管理6大热门游戏模组
  • 2026:郫县(郫都)室内除异味、甲醛治理公司横向测评,为什么本地业主更认可成都肃醛环保科技有限公司 - 专注室内空气检测治理
  • 2026年6月马鞍山机械刀片厂家推荐:锯齿刀片/包装机/印刷机刀片优选指南 - 海棠依旧大