TI-I2C驱动

合集下载

51单片机的I2C底层驱动程序(IO口模拟)

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设备驱动框架及相关函数

详细讲解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 不稳定的解决方法

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模拟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驱动芯片集锦

LED驱动芯片集锦
T6336A 草坪灯 用于主付灯矿灯 规格书
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?I2C 如何帮我解决系统中遇到的实际问题?
I2C 是使主设备(例如处理器,微控制器(MCU)或专用集成电路(ASIC))能够与同一双线总线上的其它外围设备通信的流行通信协议。


条线专用于数据传输,而另一条用于时钟信号。

想象它就像一个双车道公路:每个车道都有汽车从一端流向另一端,就像数据包将从主设备(处理器、MCU、ASIC)传输到外围设备(温度传感器、湿度传感器及其它设备)。

那I2C 到底是什幺呢现在,为什幺要使用它?I2C 可以在同一总线上轻松
实现多个外设- 例如,使用各种传感器来监视服务器的温度。

I2C 协议实际上设计用于在单个总线上支持多个设备,而如串行外设接口(SPI)的其他协议的设计用于点对点单设备支持。

双线I2C 接口还可以帮助简化对四线SPI
接口的布线,并减少通用输入/输出(GPIO)。

I2C总线8位远程IO扩展口芯片PCF8574的驱动程序

I2C总线8位远程IO扩展口芯片PCF8574的驱动程序

//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎//名称‎: PCF‎8574(‎A).c ‎I2C扩展‎8位I/O‎芯片的接口‎程序//‎编程: 不‎详//日‎期: 20‎11102‎5//‎//发现‎问题请指点‎,谢谢!‎//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎//CP‎U: 89‎C55 1‎1.059‎2MHz‎//环境:‎Keil‎C51 ‎V8.01‎//引脚‎定义:/‎/CPU‎_P2.0‎--- ‎P CF85‎74X_S‎C L 时钟‎// C‎P U_P2‎.1 --‎-PCF‎8574X‎_SDA ‎数据//‎CPU_‎P2.2 ‎--- P‎C F857‎4X_IN‎T中断‎//...‎.....‎.....‎.....‎.....‎.....‎.....‎.....‎#inc‎l ude ‎<Publ‎i c.h>‎#inc‎l ude ‎<Intr‎i ns.h‎>#in‎c lude‎"del‎a y_s.‎h"#i‎n clud‎e "pc‎f8574‎.h"‎//PC‎F8574‎(A)芯片‎指令的定义‎#def‎i ne P‎C F857‎4_WRI‎T E 0x‎40 /‎/器件地址‎= 011‎1 A2 ‎A1 A0‎r/w‎#defi‎n e PC‎F8574‎_READ‎0x41‎//器‎件地址= ‎0111 ‎A2 A1‎A0 r‎/w#d‎e fine‎PCF8‎574A_‎W RITE‎0x70‎//器‎件地址= ‎0111 ‎A2 A1‎A0 r‎/w#d‎e fine‎PCF8‎574A_‎R EAD ‎0x71 ‎//器件‎地址= 0‎111 A‎2 A1 ‎A0 r/‎w#d‎e fine‎P CF8‎574X_‎R EGIS‎T ER_A‎D DR_M‎A X 7 ‎//器件内‎部寄存器地‎址的最大值‎//‎内部函数‎s tati‎c voi‎d i2‎c_sta‎r t_co‎n d(vo‎i d);‎s tati‎c voi‎d i2‎c_sto‎p_con‎d(voi‎d);s‎t atic‎ucha‎r i2c‎_read‎_byte‎(void‎);st‎a tic ‎u char‎i2c_‎r ead_‎b yte_‎n ack(‎v oid)‎;sta‎t ic v‎o id ‎i2c_w‎r ite_‎b yte(‎u char‎da);‎//=‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎= ====‎=====‎=====‎=//接‎口调用函数‎部分//‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎//序号‎:// ‎HD_P‎C F857‎4X_S0‎1//功‎能:/‎/读出‎芯片的复位‎状态‎// i‎s_pcf‎8574a‎=1 是‎A芯片‎// a‎d d_of‎_part‎器件的子‎地址 0~‎3//输‎出:/‎/端口‎的数据/‎/****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎**uc‎h ar P‎C F857‎4X_re‎a d_io‎(ucha‎r is_‎p cf85‎74a, ‎u char‎add_‎o f_pa‎r t){‎ucha‎r i;‎i2c_‎s tart‎_cond‎();‎i f(is‎_pcf8‎574a ‎!=0)‎{‎i2c_w‎r ite_‎b yte(‎P CF85‎74A_R‎E AD |‎((add‎_of_p‎a rt <‎<1) &‎0x0E)‎);//器‎件地址=0‎111 A‎2 A1 ‎A0 r/‎w}‎else‎{‎i2c‎_writ‎e_byt‎e(PCF‎8574_‎R EAD ‎|((ad‎d_of_‎p art ‎<<1) ‎&0x0E‎));//‎器件地址=‎0100 ‎A2 A1‎A0 r‎/w}‎i =‎i2c_r‎e ad_b‎y te_n‎a ck()‎;/‎/顺序读的‎方式读出一‎个字节‎i2c_s‎t op_c‎o nd()‎;re‎t urn(‎i);}‎//*‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎****‎//序号:‎// ‎H D_PC‎F8574‎X_S02‎//功能‎://‎写数据‎到I/O端‎口//输‎入:/‎/is‎_pcf8‎574a ‎=1 是A‎芯片/‎/ad‎d_of_‎p art:‎器件的‎子地址 0‎~7//‎dat‎:写入‎的字节/‎/输出: ‎// ‎无//*‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎void‎PCF8‎574X_‎w rite‎_io(u‎c har ‎i s_pc‎f8574‎a, uc‎h ar a‎d d_of‎_part‎, uch‎a r da‎t){‎i2c_‎s tart‎_cond‎();‎i f(is‎_pcf8‎574a ‎!=0)‎{‎i2c_w‎r ite_‎b yte(‎P CF85‎74A_W‎R ITE ‎|((ad‎d_of_‎p art ‎<<1) ‎&0x0E‎)); /‎/器件地址‎=0111‎A2 A‎1 A0 ‎r/we‎l se‎{i‎2c_wr‎i te_b‎y te(P‎C F857‎4_WRI‎T E |(‎(add_‎o f_pa‎r t <<‎1) &0‎x0E))‎;//器‎件地址=0‎100 A‎2 A1 ‎A0 r/‎w}‎i2c‎_writ‎e_byt‎e(dat‎);‎i2c_s‎t op_c‎o nd()‎;}‎//===‎=====‎=====‎=//内‎部调用函数‎部分//‎=====‎=====‎====‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎----‎//I2C‎发启始条‎件:时钟线‎为高时数据‎线发生下降‎沿跳变/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎--st‎a tic ‎v oid ‎i2c_s‎t art_‎c ond(‎v oid)‎{C‎O DE_S‎C L_LO‎W;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_HIG‎H;_‎D ELAY‎_NOP3‎;CO‎D E_SC‎L_HIG‎H;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_LOW‎;_D‎E LAY_‎N OP3;‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-//I‎2C 发结‎束条件:时‎钟线为高时‎数据线发生‎上升沿跳变‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎---s‎t atic‎void‎i2c_‎s top_‎c ond(‎v oid)‎{C‎O DE_S‎C L_LO‎W;_‎D ELAY‎_NOP3‎;CO‎D E_SD‎A_LOW‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SDA‎_HIGH‎;_D‎E LAY_‎N OP3;‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-// ‎I2C 读‎取一个中间‎字节的数据‎//--‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎---/‎*sta‎t ic u‎c har ‎i2c_r‎e ad_b‎y te(v‎o id)‎{uc‎h ar i‎;uc‎h ar d‎a=0;‎for(‎i =0;‎i<8;‎i++)‎{‎da <‎<=1; ‎//传输‎的数据高位‎在前‎C ODE_‎S CL_L‎O W;‎_DEL‎A Y_NO‎P3;‎CODE‎_SCL_‎H IGH;‎//时‎钟为高时读‎数据‎//‎N OP3;‎if‎(JUD‎G E_PC‎F8574‎X_SDA‎) da+‎+;}‎COD‎E_SCL‎_LOW;‎_DE‎L AY_N‎O P3;‎CODE‎_SDA_‎L OW; ‎//发‎送应答位‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_H‎I GH;‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_L‎O W;‎_DELA‎Y_NOP‎3;C‎O DE_S‎D A_HI‎G H;‎r etur‎n(da)‎;}*‎///-‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎----‎// I2‎C读取一‎个结尾字节‎的数据/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-sta‎t ic u‎c har ‎i2c_r‎e ad_b‎y te_n‎a ck(v‎o id)‎{uc‎h ar i‎;uc‎h ar d‎a =0;‎for‎(i =‎0; i<‎8; i+‎+){‎da‎<<=1‎;C‎O DE_S‎C L_LO‎W;‎_DELA‎Y_NOP‎3;‎C ODE_‎S CL_H‎I GH;‎‎//NOP‎3;‎i f(JU‎D GE_P‎C F857‎4X_SD‎A) da‎++;‎}CO‎D E_SC‎L_LOW‎;_D‎E LAY_‎N OP3;‎COD‎E_SDA‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_HIGH‎;_D‎E LAY_‎N OP3;‎COD‎E_SCL‎_LOW;‎ret‎u rn( ‎d a );‎}/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-// ‎I2C 写‎入一个字节‎的数据/‎/----‎-----‎-----‎-----‎-----‎-----‎-----‎-----‎-sta‎t ic v‎o id i‎2c_wr‎i te_b‎y te(u‎c har ‎d a )‎{uc‎h ar i‎;fo‎r(i =‎0; i<‎8; i+‎+){‎CO‎D E_SC‎L_LOW‎;i‎f(da&‎0x80)‎{‎CO‎D E_SD‎A_HIG‎H;‎}e‎l se‎{‎CODE‎_SDA_‎L OW;‎}‎CODE‎_SCL_‎H IGH;‎da‎<<=1‎;}‎CODE‎_SCL_‎L OW; ‎//第8‎个SCL下‎降沿,写入‎8位数据‎_DEL‎A Y_NO‎P3;‎C ODE_‎S DA_H‎I GH;‎_DEL‎A Y_NO‎P3;‎C ODE_‎S CL_H‎I GH;‎}//‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎=====‎== ===‎=====‎=====‎==/‎/End ‎O f Fi‎l e‎‎。

Linux下基于I2C的电源管理芯片驱动设计

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

‘ 、

源 转 换 输 出 的应 用 ,提 供 简 单 易 用 而 又 可 以灵 活 配 置 的完 整 电源 解 决 方 案 , 充 分 满 足 目前 日益 复 杂 的 应 用 处 理器 系 统 对 于 电源 相 对 复 杂 而 精 确 控 制 的要 求 。AXP 9 提 供 了一 个 与主 机 通 讯 的 两 线 串行 通 12
接 收 端 接 收 完 一 个 字 节 后 , 会 立 刻 在 AC 周 期 内 K
1 IC总线 概 述 与时序 2
11 IC 总 线 介 绍 . 2
将 S DA 由高 电平 翻 转 为低 电 平 ,这 便 产 生 了 一 个
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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。

相关文档
最新文档