TI-I2C驱动
51单片机的I2C底层驱动程序(IO口模拟)
51单片机的I2C底层驱动程序(IO口模拟)/*Title:I2C for 80C51Author:yuyouliang51单片机(本人使用STC89C52单片机,12T模式)的I2C驱动程序,使用逻辑分析仪对该协议进行分析,发现波形比较美观,SCL 的频率在70KHz左右(11.0592M晶振),低于标准的100K,可以适应大多数的I2C器件。
如果感觉速度过快或过慢,可以自行修改延时。
希望可以给读者一个参考,给读者一些帮助!*//*i2c.h文件 */#ifndef __I2C_H_#define __I2C_H_sbit SCL = P2^1;sbit SDA = P2^0;void start_i2c(); //启动I2C总线:SCL高电平期间,SDA由高变低void stop_i2c(); //停止I2C总线:SCL高电平期间,SDA由低变高void send_i2c(unsigned char c); //主机发送一个字节,先发送最高位unsigned char receive_i2c(); //主机接收一个字节,先接收最高位void master_ack(bit ack); //主机非应答信号(填参数0)或应答信号(填参数1)void slave_ack(); //等待从机应答信号#endif/* i2c.c文件 */#include#include#include#define nop() _nop_()void start_i2c() //启动I2C总线:SCL高电平期间,SDA由高变低{SDA=1;SCL=1;nop();nop();nop();nop();SDA=0;SCL=0;}void stop_i2c() //停止I2C总线,SCL高电平期间,SDA由低变高{SDA=0;SCL=1;nop();nop();nop();nop();SDA=1;}void slave_ack() //等待从机应答信号,如果从机迟迟没有应答,则结束总线。
详细讲解RT-Thread I2C设备驱动框架及相关函数
详细讲解RT-Thread I2C设备驱动框架及相关函数本应用笔记以驱动I2C接口的6轴传感器MPU6050为例,说明了如何使用I2C设备驱动接口开发应用程序,并详细讲解了RT-Thread I2C设备驱动框架及相关函数。
1 本文的目的和结构1.1 本文的目的和背景I2C(或写作i2c、IIC、iic)总线是由Philips公司开发的一种简单、双向二线制(时钟SCL、数据SDA)同步串行总线。
它只需要两根线即可在连接于总线上的器件之间传送信息,是半导体芯片使用最为广泛的通信接口之一。
RT-Thread中引入了I2C设备驱动框架,I2C 设备驱动框架提供了基于GPIO模拟和硬件控制器的2种底层硬件接口。
1.2 本文的结构本文首先描述了RT-Thread I2C设备驱动框架的基本情况,然后详细描述了I2C设备驱动接口,并使用I2C设备驱动接口编写MPU6050的驱动程序,并给出了在正点原子STM32F4探索者开发板上验证的代码示例。
2 I2C设备驱动框架简介在使用MCU进行项目开发的时候,往往需要用到I2C总线。
一般来说,MCU带有I2C 控制器(硬件I2C),也可以使用MCU的2个GPIO自行编写程序模拟I2C总线协议实现同样的功能。
RT-Thread提供了一套I/O设备管理框架,它把I/O设备分成了三层进行处理:应用层、I/O 设备管理层、底层驱动。
I/O设备管理框架给上层应用提供了统一的设备操作接口和I2C 设备驱动接口,给下层提供的是底层驱动接口。
应用程序通过I/O设备模块提供的标准接口访问底层设备,底层设备的变更不会对上层应用产生影响,这种方式使得应用程序具有很好的可移植性,应用程序可以很方便的从一个MCU移植到另外一个MCU。
本文以6轴惯性传感器MPU6050为例,使用RT-Thread I2C设备驱动框架提供的GPIO模拟I2C控制器的方式,阐述了应用程序如何使用I2C设备驱动接口访问I2C设备。
TI CC2541 I2C 不稳定的解决方法
TI CC2541 I2C 不稳定的解决方法最近用CC2541 开发一个设备,用它自带的硬件I2C, 发现很不稳定,很烦恼。
于是自己写了一个软件I2C ,解决了问题。
贡献给大家,共勉。
//-----------------------------------------------------------------------------// Includes//-----------------------------------------------------------------------------#include "common.h"#include "I2C.h"#include <ioCC2541.h>/* ------------------------------------------------------------------------------------------------* Constants* ------------------------------------------------------------------------------------------------*/// I2CWC#define I2C_OVR BV(7) // 1: GPIO functionality.0: I2C functionality#define I2C_SCLPUE BV(3) //SCL pin pullup enable#define I2C_SDAPUE BV(2) //SDA pin pullup enable.#define I2C_SCLOE BV(1) //SCL pin output enable#define I2C_SDAOE BV(0) //SDA pin output enable// I2CIO#define I2C_SCLD BV(1) //SCL data value#define I2C_SDAD BV(0) //SDA data value#define SDA_0 I2CIO &= ~I2C_SDAD //SDA=0#define SDA_1 I2CIO |= I2C_SDAD //SDA=1#define SCL_0 I2CIO &= ~I2C_SCLD //SCL=0#define SCL_1 I2CIO |= I2C_SCLD //SCL=1#define SDA_IN I2CWC &= ~I2C_SDAOE //SDA INPUT#define SDA_OUT I2CWC |= I2C_SDAOE //SDA OUTPUT#define SCL_IN I2CWC &= ~I2C_SCLOE //SCL INPUT#define SCL_OUT I2CWC |= I2C_SCLOE //SCL OUTPUT#define I2C_GPIO I2CWC = 0x80; //1: I2C GPIO//***************************************************************************** ******//*名称:i2c_send_noack()*//*功能:无应答I2C总线*//*参数:无*//*返回:1 有NOACK信号0 无NOACK信号*//***************************************************************************** ******voidsend_noack(){SDA_OUT; //开路输出,SDA_1; //SDA = 1; NO ACKasm("nop");SCL_1; //SCL = 1;asm("nop");SCL_0; //SCL = 0; //START}// iic应答for slavervoidsend_ack() {SDA_OUT; //开路输出,SDA_0; //OUT 0 ACKasm("nop");SCL_1;asm("nop");SCL_0;}/**停止iic*/static void stop(){SDA_OUT; //开路输出,并输出0.SCL_0; //SCL = 0;asm("nop");SCL_1; //SCL = 1; STOPasm("nop");SDA_1; //SDA = 1;SDA_IN;SCL_IN;}/** 启动iic*/// static void start() {static void start(){SDA_OUT; //开路输出,并输出0.SCL_OUT;SDA_1; //SDA = 1;SCL_1; //SCL = 1;asm("nop");SDA_0; //SDA = 0;asm("nop");SCL_0; //SCL = 0; //START}/** iic写一个字节*/voidiic_write(uint8 datIn) {uint8dat, j;dat = datIn;SDA_OUT;for (j = 0; j < 8; j++) {if((dat& 0x80)) SDA_1;else SDA_0;asm("nop"); asm("nop"); asm("nop");SCL_1; //write TDOS_SDA begin asm("nop");dat<<= 1;SCL_0; //write TDOS_SDA end }}boolcheck_ack() {boolack_flag;SDA_IN; //开路输入,asm("nop");SCL_1; //read ask beginasm("nop");if((I2CIO & I2C_SDAD) ==1){ //if (SDA==1)ack_flag = 0; //1: err}else{ack_flag = 1; //0: ok}SCL_0; //read ask endreturnack_flag;}/** iic读一个字节*/uint8 iic_read() {uint8 j, dat = 0;SDA_IN; //开路输入,for (j = 0; j < 8; j++) {SCL_1; //read TDOS_SDA begin. delay 0.7usdat<<= 1;asm("nop"); asm("nop"); asm("nop");if((I2CIO & I2C_SDAD) ==1){ //if (SDA==1)dat |= 0x01; //input TDOS_SDA}SCL_0; //read TDOS_SDA end. delay 1.4us }returndat;}/** 通过I2C总线向某一寄存器写入一个字节数据*/void I2C_write_byte(uint8 I2C_addr, uint8 Raddr, uint8 dat) { start(); //发启动信号iic_write(I2C_addr | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(Raddr); //发送寄存器地址if (check_ack()==0) {goto err;}iic_write(dat); //发送数据字节if (check_ack()==0) {goto err;}err:stop();}/** 通过I2C总线读出某一寄存器的数据*/uint8 I2C_read_byte(uint8 I2C_addr, uint8 Raddr) { uint8dat;start();iic_write(I2C_addr | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(Raddr); //TDOS'registerif (check_ack()==0) {goto err;}start(); //重发起动信号iic_write(I2C_addr | 0X01); //READif (check_ack()==0) {goto err;}dat = iic_read(); //接收读出的数据send_noack();err:stop();returndat;}/** 通过I2C总线读出某一寄存器的数据*/uint32 I2C_read_3byte(uint8 I2C_addr, uint8 Raddr) { uint8 dat1,dat2,dat3;start();iic_write(0X98 | 0X00); //WRITE i2cif (check_ack()==0) {goto err;}iic_write(0X00); //TDOS'registerif (check_ack()==0) {goto err;}start(); //重发起动信号iic_write(0X98 | 0X01); //READif (check_ack()==0) {goto err;}dat1 = iic_read(); //接收读出的数据send_ack();dat2 = iic_read(); //接收读出的数据send_ack();dat3 = iic_read(); //接收读出的数据send_noack();err:stop();return (dat1<<16) | (dat2<<8) | dat3;}//----------------------------------------------------------------------------- // End Of File//---------------。
防止gpio模拟iic驱动被其他线程打断的方法
防止gpio模拟iic驱动被其他线程打断的方法防止GPIO模拟I2C驱动在多线程环境下被打断是一个重要的问题。
在这篇文章中,我将介绍一些方法来解决这个问题,以确保GPIO模拟I2C驱动的稳定性和可靠性。
首先,让我们了解一下什么是GPIO和I2C。
GPIO是通用输入输出端口,它可以用来控制外部设备或读取外部设备的状态。
而I2C是一种通信协议,它可以用于连接和控制多个设备,通过两根线进行数据传输。
在使用GPIO模拟I2C驱动时,我们需要保证驱动程序能够正确地处理并发访问和时序要求。
为了实现这一点,我们可以采取以下几个步骤:1. 锁定访问:在GPIO模拟I2C驱动中,我们可以使用信号量或互斥锁来实现对共享资源的访问控制。
当一个线程访问I2C总线时,它可以获得锁,阻止其他线程同时访问。
2. 设置优先级:在多线程环境中,我们可以通过设置线程的优先级来控制它们的执行顺序。
将GPIO模拟I2C驱动的线程设置为较高的优先级,可以确保它能够及时地响应,并且不会被低优先级的线程打断。
3. 中断处理:在一些特殊情况下,我们可能需要使用中断来处理GPIO模拟I2C驱动的数据请求。
通过配置中断处理程序,我们可以在需要时及时响应外部设备的请求,而不会被其他线程的操作打断。
4. 错误处理:在GPIO模拟I2C驱动中,我们应该实现错误处理机制,以便在发生错误时进行适当的处理。
例如,在发送或接收数据时发生错误,我们可以采取一些补救措施,如重新发送或重新接收数据,以确保数据的可靠性。
综上所述,要防止GPIO模拟I2C驱动在多线程环境下被打断,我们可以采取一系列的措施来确保驱动程序的稳定性和可靠性。
通过锁定访问、设置优先级、中断处理和错误处理等方法,我们可以保证GPIO模拟I2C驱动能够正确地处理并发访问和时序要求,从而实现可靠的数据传输和外设控制。
希望本文能够对需要实现GPIO模拟I2C驱动的开发者有所帮助,并能够在实际应用中发挥指导作用。
LED驱动芯片集锦
T6315A 草坪灯 规格书
T6317A MR16-1W 7-24V 350mA 1W多颗驱动IC 规格书
美国灿瑞科技公司 15
美商茂力公司(MPS) 16
美国CATALYST 16
欧洲英国IXYS半导体公司 17
美国迈瑞半导体公司 17
欧洲部分: 17
德国英பைடு நூலகம்凌 17
奥地利微电子 17
NXP 荷兰皇家飞利浦公司I&SUP2;C LED 显示控制 17
NXP 荷兰皇家飞利浦公司 高功率系统用 SMPS 芯片 17
台湾台晶科技
T6309A 手机背光 规格书
T6309B 手机背光 规格书
AMC7140 5-50V DC&DC 最大500mA电流可调,1颗或多颗LED驱动IC 规格书
AMC7150 5-24V DC&DC 最大1.5A固定式, 1-3颗LED驱动IC 规格书
AMC7169 LED保护IC 规格书
台湾聚积科技公司
MBI1801 1路恒流驱动1.2A电流可设定PWM信号灰度调节 规格书
MBI1802 2路恒流驱动360mA电流可两路单独设定PWM信号灰度调节 规格书
MBI1804 4路恒流驱动240mA电流可设定PWM信号灰度调节 规格书
T6325A MR16-3/5W 7-24V 700mA 多颗LED驱动IC 规格书
ON 安森美半导体 7
美国超科公司 (SUPERTEX) 7
TI 美国德州仪器公司 屏幕驱动部分 8
TI 美国德州仪器公司 白光LED驱动器 8
美国美信集成产品公司 白光LED驱动器 9
I2C是什么,什么类型设备支持I2C,为什么要使用它?
I2C 是什么,什么类型设备支持I2C,为什么要使用
它?
我相信互联网搜索引擎可为我提供可靠、快速的答案,因此当我第一次遇到I2C 协议时,我首先寻求互联网搜索引擎获得帮助。
我的搜索给出如下响应:内部集成电路(I2C)协议是双向双线串行总线,其提供集成电路之间的通信链路。
这一解释已经很清楚了,但我还有更多的问题:它究竟是什幺?什幺类型的设备使用I2C?I2C 如何帮我解决系统中遇到的实际问题?
I2C 是使主设备(例如处理器,微控制器(MCU)或专用集成电路(ASIC))能够与同一双线总线上的其它外围设备通信的流行通信协议。
一
条线专用于数据传输,而另一条用于时钟信号。
想象它就像一个双车道公路:每个车道都有汽车从一端流向另一端,就像数据包将从主设备(处理器、MCU、ASIC)传输到外围设备(温度传感器、湿度传感器及其它设备)。
那I2C 到底是什幺呢现在,为什幺要使用它?I2C 可以在同一总线上轻松
实现多个外设- 例如,使用各种传感器来监视服务器的温度。
I2C 协议实际上设计用于在单个总线上支持多个设备,而如串行外设接口(SPI)的其他协议的设计用于点对点单设备支持。
双线I2C 接口还可以帮助简化对四线SPI
接口的布线,并减少通用输入/输出(GPIO)。
I2C总线8位远程IO扩展口芯片PCF8574的驱动程序
//......................................//名称: PCF8574(A).c I2C扩展8位I/O芯片的接口程序//编程: 不详//日期: 20111025////发现问题请指点,谢谢!//......................................//CPU: 89C55 11.0592MHz//环境:KeilC51 V8.01//引脚定义://CPU_P2.0--- P CF8574X_SC L 时钟// CP U_P2.1 ---PCF8574X_SDA 数据//CPU_P2.2 --- PC F8574X_INT中断//......................................#incl ude <Publi c.h>#incl ude <Intri ns.h>#inc lude"dela y_s.h"#in clude "pcf8574.h"//PCF8574(A)芯片指令的定义#defi ne PC F8574_WRIT E 0x40 //器件地址= 0111 A2 A1 A0r/w#defin e PCF8574_READ0x41//器件地址= 0111 A2 A1A0 r/w#de finePCF8574A_W RITE0x70//器件地址= 0111 A2 A1A0 r/w#de finePCF8574A_R EAD 0x71 //器件地址= 0111 A2 A1 A0 r/w#de fineP CF8574X_R EGIST ER_AD DR_MA X 7 //器件内部寄存器地址的最大值//内部函数s tatic void i2c_star t_con d(voi d);s tatic void i2c_stop_cond(void);st aticuchar i2c_read_byte(void);sta tic u chari2c_r ead_b yte_n ack(v oid);stat ic vo id i2c_wr ite_b yte(u charda);//============================================================== ===============//接口调用函数部分//*******************************************************//序号:// HD_PC F8574X_S01//功能://读出芯片的复位状态// is_pcf8574a=1 是A芯片// ad d_of_part器件的子地址 0~3//输出://端口的数据//********************************************************uch ar PC F8574X_rea d_io(uchar is_p cf8574a, u charadd_o f_par t){uchar i;i2c_s tart_cond();i f(is_pcf8574a !=0){i2c_wr ite_b yte(P CF8574A_RE AD |((add_of_pa rt <<1) &0x0E));//器件地址=0111 A2 A1 A0 r/w}else{i2c_write_byte(PCF8574_R EAD |((add_of_p art <<1) &0x0E));//器件地址=0100 A2 A1A0 r/w}i =i2c_re ad_by te_na ck();//顺序读的方式读出一个字节i2c_st op_co nd();ret urn(i);}//*******************************************************//序号:// H D_PCF8574X_S02//功能://写数据到I/O端口//输入://is_pcf8574a =1 是A芯片//add_of_p art:器件的子地址 0~7//dat:写入的字节//输出: // 无//********************************************************voidPCF8574X_w rite_io(uc har i s_pcf8574a, uch ar ad d_of_part, ucha r dat){i2c_s tart_cond();i f(is_pcf8574a !=0){i2c_wr ite_b yte(P CF8574A_WR ITE |((add_of_p art <<1) &0x0E)); //器件地址=0111A2 A1 A0 r/wel se{i2c_wri te_by te(PC F8574_WRIT E |((add_o f_par t <<1) &0x0E));//器件地址=0100 A2 A1 A0 r/w}i2c_write_byte(dat);i2c_st op_co nd();}//==============//内部调用函数部分//==============//----------------------------------------------//I2C发启始条件:时钟线为高时数据线发生下降沿跳变//----------------------------------------------sta tic v oid i2c_st art_c ond(v oid){CO DE_SC L_LOW;_D ELAY_NOP3;COD E_SDA_HIGH;_D ELAY_NOP3;COD E_SCL_HIGH;_D ELAY_NOP3;COD E_SDA_LOW;_DE LAY_N OP3;}//----------------------------------------//I2C 发结束条件:时钟线为高时数据线发生上升沿跳变//----------------------------------------st aticvoidi2c_s top_c ond(v oid){CO DE_SC L_LOW;_D ELAY_NOP3;COD E_SDA_LOW;_DE LAY_N OP3;CODE_SCL_HIGH;_DE LAY_N OP3;CODE_SDA_HIGH;_DE LAY_N OP3;}//----------------------------------------// I2C 读取一个中间字节的数据//----------------------------------------/*stat ic uc har i2c_re ad_by te(vo id){uch ar i;uch ar da=0;for(i =0;i<8;i++){da <<=1; //传输的数据高位在前C ODE_S CL_LO W;_DELA Y_NOP3;CODE_SCL_H IGH;//时钟为高时读数据//N OP3;if(JUDG E_PCF8574X_SDA) da++;}CODE_SCL_LOW;_DEL AY_NO P3;CODE_SDA_L OW; //发送应答位_DELA Y_NOP3;C ODE_S CL_HI GH;_DELA Y_NOP3;C ODE_S CL_LO W;_DELAY_NOP3;CO DE_SD A_HIG H;r eturn(da);}*///----------------------------------------// I2C读取一个结尾字节的数据//----------------------------------------stat ic uc har i2c_re ad_by te_na ck(vo id){uch ar i;uch ar da =0;for(i =0; i<8; i++){da<<=1;CO DE_SC L_LOW;_DELAY_NOP3;C ODE_S CL_HI GH;//NOP3;i f(JUD GE_PC F8574X_SDA) da++;}COD E_SCL_LOW;_DE LAY_N OP3;CODE_SDA_HIGH;_DE LAY_N OP3;CODE_SCL_HIGH;_DE LAY_N OP3;CODE_SCL_LOW;retu rn( d a );}//----------------------------------------// I2C 写入一个字节的数据//----------------------------------------stat ic vo id i2c_wri te_by te(uc har d a ){uch ar i;for(i =0; i<8; i++){COD E_SCL_LOW;if(da&0x80){COD E_SDA_HIGH;}el se{CODE_SDA_L OW;}CODE_SCL_H IGH;da<<=1;}CODE_SCL_L OW; //第8个SCL下降沿,写入8位数据_DELA Y_NOP3;C ODE_S DA_HI GH;_DELA Y_NOP3;C ODE_S CL_HI GH;}//============================================================== ===============//End O f Fil e。
Linux下基于I2C的电源管理芯片驱动设计
0 引 言
内部 集 成 电路 (ne—ne rtd crut 2 itritg ae i i c ,IC)
12 IC 总 线 信 号 时序 . 2
S DA 和 S L2条 信 号 线 都 处 于 高 电平 ,即 总 线 C 空 闲状 态 , 2条 信 号 线 各 自的 上 拉 电阻 把 电平 拉 高 ;
( tritgae i ut u d r iu . h 2 u miga dtese il rhtcueo eICb s nte n xk re ae i e— e rtdcr i n e n x T eICb s i n n p ca ac i tr fh 2 u u en l r n n c ) L t h e t i h Li
23 I C设 备 驱 动 . 2
CON Dn1 oN
图 1 IC总 线起 始 信 号 与结 束信 号【 2
定 义 描 述 具 体 设 备 的 IC cin 2 l t和 可 能 的私 有 e 数 据 结 构 、借 助 IC 框 架 的 IC pr be 函 数 实 现 注 2 2 o
S
‘ 、
.
源 转 换 输 出 的应 用 ,提 供 简 单 易 用 而 又 可 以灵 活 配 置 的完 整 电源 解 决 方 案 , 充 分 满 足 目前 日益 复 杂 的 应 用 处 理器 系 统 对 于 电源 相 对 复 杂 而 精 确 控 制 的要 求 。AXP 9 提 供 了一 个 与主 机 通 讯 的 两 线 串行 通 12
接 收 端 接 收 完 一 个 字 节 后 , 会 立 刻 在 AC 周 期 内 K
1 IC总线 概 述 与时序 2
11 IC 总 线 介 绍 . 2
将 S DA 由高 电平 翻 转 为低 电 平 ,这 便 产 生 了 一 个
i2c驱动传入probe的参数解释
I2C驱动传入probe的参数解释在进行I2C设备的驱动开发过程中,常常会涉及到I2C驱动的probe 函数。
probe函数是Linux内核驱动中的一种特殊函数,它在驱动被加载并且设备被检测到时被调用,用于初始化设备并注册设备驱动。
在编写I2C驱动的probe函数时,通常需要传入不同的参数进行配置和初始化。
本文将对I2C驱动传入probe的参数进行解释和说明,帮助读者更好地理解和使用I2C设备驱动。
1. struct i2c_client *client在I2C驱动的probe函数中,通常需要传入一个指向structi2c_client结构体的指针作为参数。
这个结构体是I2C设备在内核中的表示,包含了I2C设备的位置区域、总线信息、驱动信息等。
通过这个参数,我们可以获取I2C设备的各种信息,并进行相应的初始化和配置。
2. const struct i2c_device_id *id另一个常见的参数是一个指向const struct i2c_device_id结构体的指针,用于指定要注册的设备驱动的ID信息。
这个结构体中通常包含了设备的厂商ID、设备类型、设备名称等信息,用于匹配加载指定的设备驱动。
在probe函数中,我们可以使用这个参数来判断当前检测到的I2C设备是否匹配当前的驱动,从而进行相应的初始化和注册操作。
3. int (*probe)(struct i2c_client *client, const struct i2c_device_id *id)最后一个重要的参数是probe函数本身。
这个参数是一个函数指针,用于指定实际的probe函数的位置区域。
在probe函数中,我们可以根据传入的client和id参数,进行设备的初始化、资源的申请、注册设备驱动等操作。
通过这个函数指针参数,内核可以在加载驱动并检测到设备时正确地调用对应的probe函数。
I2C驱动传入probe的参数包括指向I2C设备结构体的指针、指向设备ID信息的指针以及probe函数的函数指针。
TI-I2C驱动
TI-I2C驱动一、与I2C驱动相关的文件分成两部分:1)应用层接口部分:程序在svn中的路径如下:在https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/user/i2c目录下,i2ctest.c文件,提供了lm75a_temp_read()方法,用来读取LM75A设备温度寄存器中的温度信息的功能。
2)内核驱动部分:内核位于svn中的路径如下:https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/kernel(1)总线驱动:i2c-davinci.c:在内核目录中driver/i2c/busses目录下,适用于TI的I2C总线驱动程序。
I2C总线驱动是对I2C硬件体系结构中适配器端的实现。
(2)I2C驱动代码核心:i2c-core.c:在内核目录中driver/i2c/目录下,是I2C代码的核心,用于沟通虚拟文件系统与底层实现。
该文件提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。
(3)I2C设备驱动:lm75.c:在内核目录中driver/hwmon目录下,是针对LM75A以及其他能兼容的温度传感器的设备驱动。
I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。
二、I2C简要工作流程1)在总线驱动初始化时候,当通过Linux内核源代码/driver/base/platform.c文件中定义platform_driver_register()函数注册platform_driver结构体时,其中probe指针指向的davinci_i2c_probe()函数将被调用,以初始化适配器硬件。
2)而davinci_i2c_remove()函数则完成与davinci_i2c_probe()相反的功能。
硬件i2c调用
硬件i2c调用
I2C(Inter-Integrated Circuit)是一种串行通信协议,通常用于连接微控制器和各种外围设备,如传感器、EEPROM、显示器等。
在硬件I2C调用中,我们直接使用硬件的I2C 模块,而不是通过软件模拟I2C通信。
这样可以提高通信速度,降低CPU的负担,并确保数据的可靠传输。
硬件I2C调用的步骤通常如下:
初始化硬件I2C模块:首先,我们需要配置I2C模块的参数,如通信速率、数据位宽度、奇偶校验等。
这些参数根据所连接的外围设备和需求进行设置。
发送设备地址:在开始通信时,主设备会发送一个设备地址给从设备,表示它想与之通信。
从设备会响应这个地址,确认它在接收数据。
发送数据:一旦建立通信,主设备就可以发送数据给从设备。
数据在I2C总线上以字节的形式传输,每个字节后跟一个应答信号。
接收数据:从设备可以发送数据回主设备。
同样,数据以字节的形式传输,每个字节后跟一个应答信号。
结束通信:当所有数据都已发送或接收完毕时,主设备会发送一个停止信号,结束通信。
硬件I2C调用通常需要特定的硬件支持,包括I2C控制器和相关硬件引脚。
不同的微控制器制造商可能会有不同的硬件I2C调用方法和库函数。
例如,在Arduino平台上,硬件I2C调用可以使用Wire库函数实现,而在基于STM32的系统中,可以使用HAL库提供的函数。
需要注意的是,硬件I2C调用需要仔细配置和正确使用,否则可能会导致通信错误或设备损坏。
因此,在进行硬件I2C调用时,建议仔细阅读相关硬件和软件文档,并遵循制造商的推荐做法。
C2000的I2C模块使用
C2000的I2C模块使用Email:fannian@QQ:3457561982012-5-5I2C模块作为TI公司在C2000系列中新加入的外设控制模块,在实际控制使用中得到了广泛的运用。
特别是作为EEPROM的读写操作时,有占用系统资源少,使用方便等各种优点,但是国内相关资料甚少,甚至连实际使用的参考例程也难以找到,给学习和使用带来了极大地困惑,特结合自身学习和实际工程应用为大家分析I2C模块的使用方式,在实际使用中已利用I2C模块最为广泛的EEPROM为例编写相关程序。
以前大家在没有I2C模块的处理其中使用I2C通讯协议多使用GPIO口模拟协议时序,这种方式也是使用较多的一种方式,虽然I2C协议内容简单,但模拟协议总归没有实际的硬件模块做的精准,尤其在频率控制上。
为将C2000的I2C模块在EEPROM上的应用进行编程进行说明,特从EEPROM操作说起,再结合C2000的I2C模块的相关配置进行分析。
因为C2000的I2C模块采用硬件实现I2C协议,因此对于I2C协议的“开始、应答、结束”以及读写相关时序不做说明,若想了解具体的I2C协议实现过程参阅相关文档。
24C01/02/04/08/16/32/64/128/256的使用器件地址:在对EEPROM进行操作之前必须识别该器件的地址,在I2C协议中,器件地址首先发送,器件地址由8位组成,地址信息为:1010(A2)(A1)(A0)(R/W)。
其中高四位1010为24x系列固定地址,A[2:0]为同一I2C总线上的EEPROM芯片片选信号,该三位由硬件电路决定(器件的1、2、3管脚电路连接决定),R(1)/W(0)位控制对芯片进行读写的选择内存地址:要读写的地址由主机发送,紧跟器件地址。
在对内存地址进行分析时先解释EEPROM型号问题。
以24C01为例,该芯片存储空间为1Kbit(不是1KByte)。
其分布为128*8bit我利用下表对内存地址进行表示,先说明16K以内的。
i2c_register_driver函数详解
i2c_register_driver函数详解在嵌入式软件开发中,I2C(Inter-Integrated Circuit)总线是一种常用的串行通信接口,用于在微控制器和外部设备之间传输数据。
i2c_register_driver函数是Linux内核中一个重要的函数,用于注册I2C 驱动程序。
本文将详细解析i2c_register_driver函数的功能、参数和应用。
一、i2c_register_driver函数概述i2c_register_driver函数是在Linux内核中注册一个I2C驱动程序的函数。
它的作用是将驱动程序与对应的I2C适配器绑定,使得操作系统能够正确地识别和管理该驱动程序。
在驱动程序注册后,当相应的I2C设备连接到系统时,驱动程序将会自动加载并为该设备提供服务。
二、i2c_register_driver函数参数i2c_register_driver函数包含一个结构体参数,该结构体用于指定驱动程序的相关信息和功能。
1. struct i2c_driverstruct i2c_driver是一个定义I2C驱动程序的结构体,包含了以下重要的成员:- .driver:指向内核的struct device_driver结构体,用于描述驱动程序的信息,如名称、文件操作方法等。
- .probe:指向I2C设备探测函数的指针,用于在设备连接时进行初始化和配置。
- .remove:指向I2C设备移除函数的指针,用于在设备断开连接时进行清理和释放资源。
- .id_table:指向I2C设备ID表的指针,用于匹配设备和驱动程序。
2. I2C设备探测函数(probe函数)I2C设备探测函数是I2C驱动程序的核心功能之一,在I2C设备连接到系统时被调用。
该函数的作用是检测和初始化I2C设备,并将设备与驱动程序进行绑定。
在probe函数中,可以执行一系列必要的操作,如配置寄存器、分配内存、注册字符设备等。
i2c总线(pfc8563)驱动子法度模范集[精华]
I2C总线(PFC8563)驱动子程序集;I2C总线说明:;I2_SDA =1时,即总线空闲;I2_SDA =0时,即总线忙,即正在使用; 本程序集在I2_SDA =0时,使I2_SCL=0,;此时即可改变I2_SDA 的数据,或接受I2_SDA 数据的改变;I2_SCL=0时,数据是可以改变的;I2_SCL=1时,数据的改变视为控制信号,如0到1则为停止控制;如1到0则为启动控制;========================================================== =;I2C总线(PFC8563)驱动子程序集I2_SCL EQU P2.6I2_SDA EQU P2.7I2ADDRW EQU 0A2HI2ADDRR EQU 0A3HI2TIMER EQU 02HI2TIMERN EQU 07HORG 0000HJMP MAINORG 0030HMAIN:MOV SP,#80HMOV R0,#20HCALL I2_WRTIME ;写时间初始值ED:MOV R0,#28H ;此处断点,不停执行,观测CALL I2_RDTIME ;读时间值JMP ED;================================================== 开始I2CU总线子程序I2_START: SETB I2_SDANOPSETB I2_SCLNOP ;建立起始条件的时间大于4.7usNOPNOPNOPNOPCLR I2_SDA ;起始条件NOPNOPNOPNOPNOPCLR I2_SCL ;钳隹总线NOPRET;===================================================结束I2CU总线子程序I2_STOP: CLR I2_SDANOPSETB I2_SCL ;结束总线时间大于4usNOPNOPNOPNOPNOPSETB I2_SDA ;结束总线NOPNOPNOPNOPRET;=============================================发送应答信号子程序:即发送0I2_SDACK: CLR I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLSETB I2_SDANOPNOPRET;===========================================发送非应答信号子程序,即发送1I2_SDNACK: SETB I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLCLR I2_SDANOPNOPRET;==================================================== ;检查应答子程序,即读应答信号:若读出结果为0;证明有应答,即总线上有器件响应,否则可能无器件或器件坏;出口参数:;FO=O有应答I2_CHKACK: SETB I2_SDANOPNOPSETB I2_SCLNOPNOPNOPNOPCLR F0MOV C, I2_SDAJNC CENDSETB F0CEND: CLR I2_SCLRET;=============================================发送字节子程序;入口参数;A: 被发送数;占用资源:;R2;说明:每写一字节要调用一次I2_CHKACK取应答位I2_WRBYTE: MOV R2, #08HI2_WRBYTELP1: RLC AMOV I2_SDA, CNOPSETB I2_SCLNOPNOPNOPNOPNOPCLR I2_SCLDJNZ R2, I2_WRBYTELP1NOPNOPRET;==================================================读取字节子程序;出口参数:;A: 读出的数;占用资源;R2;说明: 每读取一字节要发送一应答/非应答位I2_RDBYTE: MOV R2, #08HI2_RDLP: SETB I2_SDANOPSETB I2_SCLNOPNOPMOV C, I2_SDANOPCLR I2_SCLRLC ANOPNOPNOPNOPDJNZ R2, I2_RDLPRET;===================================BCD码转二进制子程序;入口参数:;A: BCD码;出口参数;A: 二进制数;占用资源: A R2 R3BCD2BIN: MOV R3, AANL A, #0F0HRR AMOV R2, ARR ARR AADD A, R2MOV R2, AMOV A, R3ANL A, #0FHADD A, R2RET;========================================写8563万年历子程序;入口参数:;R0: 参数区首址: 参数区格式(秒分钟小时日星期月年,BCD码表示);占用资源:;A;R0;R2;R3I2_WRTIME:CALL I2_START ;发送起始条件MOV A, #I2ADDRWCALL I2_WRBYTE ;发送8563地址 CALL I2_CHKACK ;检查应答JB F0,I2_WRTIMEMOV A, #I2TIMER ;发送8563时间寄存器地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_WRTIMEMOV R3, #I2TIMERNI2_WRTIMELP1:MOV A, @R0CALL I2_WRBYTE ;向8563写时间CALL I2_CHKACKJB F0,I2_WRTIMEINC R0DJNZ R3, I2_WRTIMELP1CALL I2_STOP ;发送停止条件 RET;===================================读8563万年历子程序;入口参数:;R0: 参数区首址(格式同上);出口参数:参数区存放万年历数据(二进制);占用资源:;A;R0;R2;R3I2_RDTIME:CALL I2_START ;发送起始条件MOV A, #I2ADDRW ;发送8563写地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMEMOV A, #I2TIMER ;发送8563时间寄存器首址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMECALL I2_START ;发送起始条件MOV A, #I2ADDRR ;发送8563读地址CALL I2_WRBYTECALL I2_CHKACKJB F0,I2_RDTIMEMOV R3, #I2TIMERN-1I2_RDTIMELP1:CALL I2_RDBYTE ;读取8563万年历数据MOV @R0, ACALL I2_SDACK ;发送应答信号INC R0DJNZ R3, I2_RDTIMELP1CALL I2_RDBYTE ;读取8563万年历年数据MOV @R0, ACALL I2_SDNACK ;发送非应答信号 CALL I2_STOP ;发送停止条件 RET;等长一点: acc = 0 时,为 errorI2_CHKACK:SETB I2_SDANOPNOPSETB I2_SCLCLR F0MOV A, #20I2_CHKACK_L1:JNB I2_SDA, I2_CHKACK_L2DJNZ ACC, I2_CHKACK_L1SETB F0I2_CHKACK_L2:CLR I2_SCLRETEND。
Kinetis MCUs I2C Timing Configuration说明书
1IntroductionThe I 2C module is popular in most applications. Kinetis MCUs provide strong features on the I 2C module, which is compatible with the I 2C-bus specification and easy to interface with other devices. However, incorrect configuration may cause potential timing issues. This document shows how to configure the I 2C timing of a slave device to meet application needs which apply to Kinetis parts that contain I2C IP instead of LPI2C.2OverviewThe I 2C specification defines detailed timing specifications to enable the I 2C device to follow the same standard and make different devices working together. Figure 1. on page 1 shows the timing definition for tSU:DAT.Figure 1.Definition of I2C timingThe Kinetis IP provides register I2Cx_F to tune the timing. The reference manual provides the reference table on how to impact the I 2C baud rate and data hold time. For the slave mode, this register also heavily impacts the timing and incorrect settings mayContents1 Introduction..........................................12 Overview...............................................13 Timing issues caused byincorrect settings..............................24 Tuning the timing using registerI2Cx_F................................................35 Conclusion. (5)6 References...........................................57 Revision history.. (5)AN12377Tuning I2C Timing In Slave ModeRev. 1 — April 2019Application Notecause timing issues. There might not be a clear explanation in the reference manual, but it must be consulted to get a correct configuration.3Timing issues caused by incorrect settingsWhen configuring the I 2C for a master device, most users know how to configure the I2Cx_F register to get the expected baud rate. However, when enabling it in the slave mode, users are not aware of the I2Cx_F function during the timing tuning and do nothing with the I2Cx_F register. In most customer applications, this possibly causes a timing issue. For example, when it works in the slave mode after events (interrupt of receiving new data or transmitting complete) occur, the slave device drives the SCL low by clock stretching and waits to handle I 2C events. It releases the SCL together with the SDA after writing/reading the I 2C data register when the I2Cx_F is set to 0. This causes the master to detect a wrong signal and fail to meet the SDA setup time requirement.Figure 2.on page 2 shows the captured waveform.Figure 2.I2C signals with clock stretching Figure 3. on page 3 shows the clock stretching timing.Timing issues caused by incorrect settingsFigure 3.Clock stretching timingFigure 3. on page 3 shows the SDA and SCL release at almost the same time. For the I2C timing definition to match the values in Figure 4. on page 3, the tSU:DA T minimum value must be around 100 ns in the fast mode and 250 ns in the standard mode. Therefore, the above timing violates the specification.The tSU:DA T timing and the I2C specification give the characteristic parameters shown in Figure 4. on page 3.Figure 4.Characteristics of tSU:DAT4Tuning the timing using register I2Cx_FConfigure the I2Cx_F register to fix the timing issue and get the tSU:DA T using this formula:SDA setup time = I2C module clock period (s) x mul x SDA setup valueNote to keep the SBRC bit field to be 0 in the I2Cx_C2 register when using this solution. Get the SDA setup value from T able 1. I2C setup value on page 4.Table 1.I2C setup valueICR (hex)SDA SetupValueICR(hex)SDA SetupValueICR(hex)SDA SetupValueICR(hex)SDA SetupValue021016206430256 131120218031320 231220228032320 341324239633384 441424249634384 5515282511235448 6616322612836512 7917442717637704 8618322812838512 98194029160396400A101A402A1603A6400B121B482B1923B7680C121C482C1923C7680D141D562D2243D8960E161E642E2563E10240F221F882F3523F1408ICR : register value of bit field ICR of I2C_FSDA Setup Value : number of I2C function clockTable 1. I2C setup value on page 4 is just for reference. Set the I2Cx_F to have a sufficient margin to meet the I Ctiming.For example, when the I2CxF is set to 0x02 and the I2C module clock frequency is 48 MHz, the setup time is calculated as: Setup time = 1/48 MHz * 1 * 3 = 62.5 nsWhen the I2Cx_F value and the setup time value are bigger, they can get a longer margin by setting the big value to I2Cx_F. However, this causes the I2C bus to drop due to clock stretching. Clock stretching happens in the below condition. At the start of a single-bit communication, the master sends the first SCL clock on the bus and the slave samples this pulse and compares it with its own I2Cx_F configuration. If the slave’s baud rate is lower than the master’s baud rate, I2C IP begins to stretch the bus. For example, if the master’s baud rate is 400 kHz and the slave’s baud rate is configured to be 100 kHz by the I2Cx_F register, the final I2C SCL bus period is composed by the slave’s 100-kHz SCL low period time and master’s 400-kHz SCL high period time. The bus period is 0.5 * (1 / 100 K + 1 / 400 K) seconds, so the SCL bus is about 160 kHz.It is recommended to set the slave's baud rate higher than the master baud rate and give a sufficient margin to meet the I2C timing.Conclusion 5ConclusionThis document introduces a way to tune the I2C timing and meet the specifications by setting I2CxF correctly, which helps customers to solve I2C timing issues.6References•I²C-bus Specification, Version 6.0, 4th of April 2014•KL16 Sub-Family Reference Manual with Addendum (document KL16P80M48SF4RM)•Kinetis KL03 reference manual (document KL03P24M48SF0RM)7Revision historyT able 2. Revision history on page 5 summarizes the changes done to this document since the initial release.Table 2.Revision historyHow To Reach Us Home Page: Web Support: /support Information in this document is provided solely to enable system and software implementers to use NXP products. There are no express or implied copyright licenses granted hereunder to design or fabricate any integrated circuits based on the information in this document. NXP reserves the right to make changes without further notice to any products herein.NXP makes no warranty, representation, or guarantee regarding the suitability of its products for any particular purpose, nor does NXP assume any liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation consequential or incidental damages. “Typical” parameters that may be provided in NXP data sheets and/or specifications can and do vary in different applications, and actual performance may vary over time. All operating parameters, including “typicals,” must be validated for each customer application by customer's technical experts. NXP does not convey any license under its patent rights nor the rights of others. NXP sells products pursuant to standard terms and conditions of sale, which can be found at the following address: / SalesTermsandConditions.While NXP has implemented advanced security features, all products may be subject to unidentified vulnerabilities. Customers are responsible for the design and operation of their applications and products to reduce the effect of these vulnerabilities on customer’s applications and products, and NXP accepts no liability for any vulnerability that is discovered. Customers should implement appropriate design and operating safeguards to minimize the risks associated with their applications and products.NXP, the NXP logo, NXP SECURE CONNECTIONS FOR A SMARTER WORLD, COOLFLUX, EMBRACE, GREENCHIP, HIT AG, I2C BUS, ICODE, JCOP, LIFE VIBES, MIFARE, MIFARE CLASSIC, MIFARE DESFire, MIFARE PLUS, MIFARE FLEX, MANTIS, MIFARE ULTRALIGHT, MIFARE4MOBILE, MIGLO, NTAG, ROADLINK, SMARTLX, SMARTMX, ST ARPLUG, TOPFET, TRENCHMOS, UCODE, Freescale, the Freescale logo, AltiVec, C‑5, CodeTEST, CodeWarrior, ColdFire, ColdFire+, C‑Ware, the Energy Efficient Solutions logo, Kinetis, Layerscape, MagniV, mobileGT, PEG, PowerQUICC, Processor Expert, QorIQ, QorIQ Qonverge, Ready Play, SafeAssure, the SafeAssure logo, StarCore, Symphony, VortiQa, Vybrid, Airfast, BeeKit, BeeStack, CoreNet, Flexis, MXC, Platform in a Package, QUICC Engine, SMARTMOS, Tower, TurboLink, and UMEMS are trademarks of NXP B.V. All other product or service names are the property of their respective owners. AMBA, Arm, Arm7, Arm7TDMI, Arm9, Arm11, Artisan, big.LITTLE, Cordio, CoreLink, CoreSight, Cortex, DesignStart, DynamIQ, Jazelle, Keil, Mali, Mbed, Mbed Enabled, NEON, POP, RealView, SecurCore, Socrates, Thumb, TrustZone, ULINK, ULINK2, ULINK-ME, ULINK-PLUS, ULINKpro, µVision, Versatile are trademarks or registered trademarks of Arm Limited (or its subsidiaries) in the US and/or elsewhere. The related technology may be protected by any or all of patents, copyrights, designs and trade secrets. All rights reserved. Oracle and Java are registered trademarks of Oracle and/or its affiliates. The Power Architecture and word marks and the Power and logos and related marks are trademarks and service marks licensed by .© NXP B.V. 2019.All rights reserved.For more information, please visit: Forsalesofficeaddresses,pleasesendanemailto:**********************Date of release: April 2019Document identifier: AN12377。
TI bq25703A I2C多种化学电池升压-降压充电控制器解决方案
TI bq25703A I2C多种化学电池升压-降压充电控制器解决方案TI公司的bq25703A是带有系统电源监视器和处理器热监视器的I2C多种化学电池升压-降压充电控制器,具有低元件数量和高效率的优势,可从各种输入源对1-4颗电池充电,输入电压3.5V-24V,支持USB2.0, USB 3.0, USB 3.1 (Type C)和USB_PD输入电流设定,降压和升压工作无缝转换.输出电流高达6.35A,可编程开关频率800kHz或1.2MHz,充电电压0.5%,输入/充电电流2%,输入/充电电流监视2%,电源监视5%.主要用在无人机,蓝牙扬声器, IP照相机,可拆电源,平板电脑和电源组,工业和医疗设备和带可充电电池的手持设备.本文介绍了bq25703A主要特性,功能框图,典型应用电路图以及评估模块bq2570x EVM (bq25700AEVM-732和bq25703AEVM-732)主要特性,电路图,材料清单和PCB装配图.The bq25703A is a synchronous NVDC battery buck-boost charge controller, offering low component count, high efficiency soluTIon for space-constraint, mulTI-chemistry battery charging applicaTIons.The NVDC-1 configuration allows the system to be regulated at battery voltage, but not drop below system minimum voltage. The system keeps operating even when the battery is completely discharged or removed. When load power exceeds input source rating, the battery goes into supplement mode and prevents the input source from being overloaded.The bq25703A charges battery from a wide range of input sources including USB adapter, high voltage USB PD sources and traditional adapters.During power up, the charger sets converter to buck, boost or buck-boost configuration based on input source and battery conditions. The charger automatically transits among buck, boost and buck-boost configuration without host control.In the absence of an input source, the bq25703A supports On-the-Go (OTG) function from 1- to 4-cell battery to generate 4.48 V to 20.8 V on VBUS. During OTG mode, the charger regulates output voltage and output current.The bq25703A monitors adapter current, battery current and system power. The flexibly programmed PROCHOT output goes directly to CPU for throttle back when needed.bq25703A主要特性:Charge 1- to 4-Cell Battery From Wide Range of Input Sources3.5-V to 24-V Input Operating V oltageSupports USB2.0, USB 3.0, USB 3.1 (Type C), and USB_PD Input Current SettingsSeamless Transition Between Buck and Boost OperationInput Current and V oltage Regulation (IDPM and VDPM) Against Source OverloadPower/Current Monitor for CPU ThrottlingComprehensive PROCHOT Profile, IMVP8 CompliantInput and Battery Current MonitorSystem Power Monitor, IMVP8 CompliantNarrow-VDC (NVDC) Power Path ManagementInstant-On With No Battery or。
TI TMS320C2000 I2C模块参考指南
图 1 I2C 总线连接图 SDA 和 SCL 都是双向线路,通过一个上拉电阻连接到正的电源电压(如上图),总线特征包 括: a) 当场效应管接通时总线相当于接地,处于低电平状态; b) 当场效应管断开时上拉电阻 Rp 将总线上拉至高电平; c) 只要有设备将总线拉至低电平时,不管其它设备状态怎样,总线都将一直保持低电平; d) 当总线空闲时时钟线和数据线路都处于高电平状态。 2 I2C 模块的时钟 I2C 模块作为一个外设模块受到外设时钟控制寄存器 PCLKCR0 管理,在配置 I2C 模块前应该 确认 I2C 模块的时钟被打开(SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // I2C)。
不管是七位地址还是十位地址模式,都有相当的数据传送和控制方式,包括重复起始条件、停 止条件、应答等,唯一不同的只是地址位数而已!
I2caRegs.I2CSAR 寄存器用于存储从机的地址。当满足开始发送条件的条件时,在发送完开始 条件后,I2C 模块将 I2caRegs .I2CSAR 中的地址复制到移位寄存器并按位发送出去。 3.2.1 七位地址格式
3.2 I2C 总线地址格式 I2C 总线规范中定义了两种地址格式:七位地址格式和十位地址格式。 I2C 模块中的 I2caRegs.I2CMDR.bit.XA 控制着地址格式,当 XA 为 1 时地址处于 10 位格式模式,
当 XA 为 0 时处于七位地址模式。同时还需要确认自由格式控制位已被关闭 (I2caRegs.I2CMDR.bit.FDF = 0),即七位地址和十位地址模式都不适用于自由模式。
b) 工作在主发模式工作时,有一个非应答(NACK)中断可用于主机对 NACK 位进行处理。
Mini2440之i2c驱动(2)
i2c 异常波形 调试
i2c 异常波形调试I2C(Inter-Integrated Circuit)是一种常用的串行总线协议,用于连接微控制器和各种外设。
然而,在实际调试中,我们常常会遇到一些异常波形问题。
本文将介绍如何生动、全面、有指导意义地调试I2C异常波形。
首先,我们需要了解I2C的基本工作原理。
I2C总线由两根信号线组成,分别是SDA(Serial Data Line)和SCL(Serial Clock Line)。
SDA负责数据传输,而SCL负责数据时钟同步。
在正常情况下,SDA和SCL信号应呈现一个类似矩形波的形状。
当我们遇到异常波形时,首先需要确认硬件连接是否正确。
检查是否存在短路、开路等问题,以确保信号能够正常传输。
接下来,检查I2C总线上的电源供应是否稳定。
电源电压不稳定可能导致信号形变,从而产生异常波形。
使用示波器来测量电源电压,确保其在规定范围内波动较小。
进一步,我们需要确认是否存在信号线上的干扰。
附近的高频设备、电磁干扰源可能会影响I2C信号的传输。
移动这些干扰源,或添加屏蔽罩以隔离I2C信号线,可以帮助减少干扰。
除了硬件问题外,软件编程错误也可能导致异常波形。
检查软件中相关的I2C调试代码,确保正确配置I2C总线速率和其他相关参数。
如果以上方法都无法解决异常波形问题,那么可能存在I2C驱动器或设备的故障。
尝试更换驱动器或设备,以确定是哪个组件引起了异常波形。
最后,持续监测调试过程中的异常波形,通过示波器或逻辑分析仪实时观察信号变化,有助于找出问题的根源。
不断尝试不同的调试方法,结合硬件和软件层面的检查,从而逐步排除异常波形问题。
综上所述,调试I2C异常波形需要全面的硬件和软件分析,以及不断尝试不同的解决方法。
通过正确配置硬件连接、检查电源供应、排除信号干扰、检查软件程序等步骤,可以解决大多数异常波形问题。
坚持持续监测和调试,找到问题的根源,并进行相应的修复措施,保证I2C总线正常工作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TI-I2C驱动
一、与I2C驱动相关的文件分成两部分:
1)应用层接口部分:
程序在svn中的路径如下:
在https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/user/i2c目录下,i2ctest.c文件,提供了lm75a_temp_read()方法,用来读取LM75A设备温度寄存器中的温度信息的功能。
2)内核驱动部分:
内核位于svn中的路径如下:
https://dareglob-971006/svn/eocOS/branches/eocOS_v4/branches/bsp/kernel
(1)总线驱动:
i2c-davinci.c:在内核目录中driver/i2c/busses目录下,适用于TI的I2C总线驱动程序。
I2C总线驱动是对I2C硬件体系结构中适配器端的实现。
(2)I2C驱动代码核心:
i2c-core.c:在内核目录中driver/i2c/目录下,是I2C代码的核心,用于沟通虚拟文件系统与底层实现。
该文件提供了I2C总线驱动和设备驱动的注册、注销方法,I2C通信方法上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。
(3)I2C设备驱动:
lm75.c:在内核目录中driver/hwmon目录下,是针对LM75A以及其他能兼容的温度传感器的设备驱动。
I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。
二、I2C简要工作流程
1)在总线驱动初始化时候,当通过Linux内核源代码/driver/base/platform.c文件中定义platform_driver_register()函数注册platform_driver结构体时,其中probe指针指向的davinci_i2c_probe()函数将被调用,以初始化适配器硬件。
2)而davinci_i2c_remove()函数则完成与davinci_i2c_probe()相反的功能。
用于内存和中断等系统资源的释放和注销。
3)总线驱动i2c-davinci.c中,定义了i2c_davinci_xfer函数。
该函数是I2C总线通信传输函数。
并且I2C适配器对应的i2c_algorithm结构体实例为i2c_davinci_algo,其中的master_xfer函数指针指向i2c_davinci_xfer函数。
4)当设备被打开,并且用户开始读操作时,会调用设备驱动lm75.c中show_temp()函数,该函数会调用i2c-core.c中的i2c_smbus_xfer()函数,i2c_smbus_xfer()函数会检查适配器对应的i2c_algorithm结构体中是否注册了smbus_xfer函数(目前i2c_davinci_algo中未注册smbus_xfer函数),程序会调用i2c_smbus_xfer_emulated()函数,最终,还是会调用标准的I2C总线通信函数master_xfer(),由于master_xfer 已经指向i2c_davinci_xfer函数,所以会调用总线驱动i2c-davinci.c中的i2c_davinci_xfer函数来读取信息。
三、接口函数
1)应用层接口:
Int lm75a_temp_read(float *temp) 读取lm75a 温度
2)内核中:lm75.c文件
static ssize_t show_temp(struct device *dev, struct device_attribute *da,char *buf)
当应用层开始读操作时,内核中会调用show_temp()函数,该函数最终会调用master_xfer()函数来获取数据。
四、修改记录
1)i2c-davinci.c:davinci_i2c_remove函数中,
- free_irq(IRQ_I2C, dev);
+ free_irq(dev->irq, dev);
2)lm75.c:
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+ static const unsigned short normal_i2c[] = { 0x48,I2C_CLIENT_END };
+ #define LM75A_ID 0xA1
lm75_detect()函数中,主要增加了对LM75A的检查,
if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
/* LM75A returns 0xff on unused registers so
just to be sure we check for that too. */
if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
|| i2c_smbus_read_byte_data(new_client, 5) != 0xff
|| i2c_smbus_read_byte_data(new_client, 6) != 0xff)
return -ENODEV;
is_lm75a = 1;
hyst = i2c_smbus_read_byte_data(new_client, 2);
os = i2c_smbus_read_byte_data(new_client, 3);
}
3)lm75.h:
- return ((s16)reg / 128) * 500;
+ return reg;
3)kernel根目录下,.config文件:
+ CONFIG_HWMON=y
+ CONFIG_SENSORS_LM75=y。