gpio模拟I2C
I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA)。I2C是总线结构,1个Master,1个或多个Slave,各Slave设备以7位地址区分,地址后面再跟1位读写位,表示读(=1)或者写(=0),所以我们有时也可看到8位形式的设备地址,此时每个设备有读、写两个地址,高7位地址其实是相同的。
I2C数据格式如下:
无数据:SCL=1,SDA=1;
开始位(Start):当SCL=1时,SDA由1向0跳变;
停止位(Stop):当SCL=1时,SDA由0向1跳变;
数据位:当SCL由0向1跳变时,由发送方控制SDA,此时SDA为有效数据,不可随意改变SDA;
当SCL保持为0时,SDA上的数据可随意改变;
地址位:定义同数据位,但只由Master发给Slave;
应答位(ACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=0;
否应答位(NACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=1。
当数据为单字节传送时,格式为:
开始位,8位地址位(含1位读写位),应答,8位数据,应答,停止位。
当数据为一串字节传送时,格式为:
开始位,8位地址位(含1位读写位),应答,8位数据,应答,8位数据,应答,……,8位数据,应答,停止位。
需要注意的是:
1,SCL一直由Master控制,SDA依照数据传送的方向,读数据时由Slave控制SDA,写数据时由Master控制SDA。当8位数据传送完毕之后,应答位或者否应答位的SDA控制权与数据位传送时相反。
2,开始位“Start”和停止位“Stop”,只能由Master来发出。
3,地址的8位传送完毕后,成功配置地址的Slave设备必须发送“ACK”。否则否则一定时间之后Master视为超时,将放弃数据传送,发送“Stop”。
4,当写数据的时候,Master每发送完8个数据位,Slave设备如果还有空间接受下一个字节应该回答“ACK”,Slave设备如果没有空间接受更多的字节应该回答“NACK”,Master当收到“NACK”或者一定时间之后没收到任何数据将视为超时,此时Master放弃数据传送,发送“Stop”。
5,当读数据的时候,Slave设备每发送完8个数据位,如果Master希望继续读下一个字节,Master应该回答“ACK”以提示Slave准备下一个数据,如果Master不希望读取更多字节,Master应该回答“NACK”以提示Slave设备准备接收Stop信号。
6,当Master速度过快Slave端来不及处理时,Slave设备可以拉低SCL不放(SCL=0将发生“线与”)以阻止Master发送更多的数据。此时Master将视情况减慢或结束数据传送。
在实际应用中,并没有强制规定数据接收方必须对于发送的8位数据做出回应,尤其是在Master和Slave端都是用GPIO软件模拟的方法来实现的情况下,编程者可以事先约定数据传送的长度,不发送ACK,有时可以起到减少系统开销的效果。开发的过程当中,开发板上的I2C总线有限,如果I2C设备太多的话,就需要用GPIO模拟I2C来解决了。
例子1
1,kernel/arch/arm/mach-pxa/board-test.c增加
设置gpio为普通gpio,为输出口
static mfp_cfg_t littleton_sw_i2c_cfg[] __initdata = {
/* gpio output*/
GPIO37, /*_SW_I2C_CLK, */
GPIO38, /*_SW_I2C_SDA, */
};
pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_sw_i2c_cfg));
gpio_direction_output(GPIO37, 1);
gpio_direction_output(GPIO38, 1);
/* i2c */
static struct i2c_gpio_platform_data i2c_bus_data = {
.sda_pin = VIPER_RTC_I2C_SDA_GPIO,
.scl_pin = VIPER_RTC_I2C_SCL_GPIO,
.udelay = 10,
.timeout = 100,
};
static struct platform_device i2c_bus_device = {
.name= "i2c-gpio",
.id= 1, /* pxa2xx-i2c is bus 0, so start at 1 */
.dev = {
.platform_data = &i2c_bus_data,
}
};
static struct i2c_board_info __initdata viper_i2c_devices[] = {
{
I2C_BOARD_INFO("ds1338", 0x68),
},
};
第一个结构体中sda_pin和scl_pin是开发板上对应的gpio口(data线和clock线),udelay是与具体芯片时钟相关的参数,需要参考具体的datasheet。下面的两个open_drain是表明两个管脚是否是开漏电路,如果是则填1,否则填0。下面一个机构体中需要注意name应该填写i2c-gpio,另外id要注意设定为2,因为系统当中已经有两个I2C设备了。
添加上需要的头文件:#include<linux/i2c-gpio.h>。在头文件devices.h中添加上设备结构体的声明,externstructplatform_devicegpio_device_i2c;
然后将gpio_device_i2c放在board-XXXX.c的数组devices中,形式请参考该数组中其他的设备。
static struct platform_device *viper_devs[] __initdata = {
&smc91x_device,
&i2c_bus_device, ///////////////////////////////////////////
&serial_device,
&isp116x_device,
&viper_mtd_devices[0],
&viper_mtd_devices[1],
&viper_backlight_device,
};
static void __init viper_init(void)
『
;
;
;
i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices));
;
}
然后再用i2c_register_board_info对其进行注册:
i2c_register_board_info(2,i2c_gpio_devices,ARRAY_SIZE(i2c_gpio_devices));
这样就完成了模拟步骤,可以直接用系统的I2C相关的注册等方法对设备进行注册和读写操作。
例子2
设置sda和scl的gpio为普通gpio输出口。
err = gpio_request(EP93XX_GPIO_LINE_EEDAT, dev_name(&pdev->dev));
err = gpio_request(EP93XX_GPIO_LINE_EECLK, dev_name(&pdev->dev));
err = gpio_direction_output(EP93XX_GPIO_LINE_EEDAT,1);
err = gpio_direction_output(EP93XX_GPIO_LINE_EECLK,1);
static struct i2c_gpio_platform_data ep93xx_i2c_data = {
.sda_pin= EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain= 0,
.scl_pin= EP93XX_GPIO_LINE_EECLK,
.scl_is_open_drain= 0,
.udelay= 2,
};
static struct platform_device ep93xx_i2c_device = {
.name= "i2c-gpio",
.id= 0,
.dev.platform_data= &ep93xx_i2c_data,
};
void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
{
i2c_register_board_info(0, devices, num);
platform_device_register(&ep93xx_i2c_device);
}
分享到:
相关推荐
内核gpio模拟i2c,代码为项目抽离代码,请注意排查代码
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
Linux驱动开发:Linux内核模块、字符设备驱动、IO模型、设备树、GPIO子系统、中断子系统、platform总线驱动、I2C总线驱动、SPI总线驱动 Linux项目是一个开放源代码的操作系统项目,由林纳斯·托瓦兹(Linus Torvalds...
I2C总线接口和SPI总线接口 LCD控制器 ADC和触摸屏接口 分析U-Boot的代码结构,并介绍如何移植到开发板上。 分析Linux内核的代码结构以及启动过程,并介绍如何移植到开发板上。 介绍嵌入式Linux文件...
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
具体内容包括Linux驱动开发入门基础知识,Linux操作系统下驱动开发核心技术,并对ARM系统的各类接口的原理、驱动开发与应用层开发进行逐一分析,其中包括GPIO、CAN、I2C、LCD、USB、触摸屏、网络、块设备、红外、SD...
第6章介绍了嵌入式系统的串行接口、I2C接口、USB接口、SPI接口、PCI接口、I2S总线接口的基本原理、电路结构与编程方法; 第7章介绍了嵌入式系统网络接口,包含有以太网接口、CAN总线接口的基本原理、电路结构与编程...
硬件部件的使用及编程(囊括了常见硬件,比如UART、I*IC、LCD等),UBoot、Linux内核的分析、配置和移植,根文件系统的构造(包括移植busybox、glibc、制作映象文件等),内核调试技术(比如添加kgdb补丁、栈回溯等),...
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!
《嵌入式Linux应用程序开发标准教程(第2版)》主要分为3个部分,包括Linux基础、搭建嵌入式Linux环境和嵌入式Linux的应用开发。Linux基础部分从Linux基础、基本操作命令讲起,为Linux初学者能快速入门提供了保证。...
分析了ARM-Linux下IIC总线及其设备驱动的层次结构,指出了IIC设备添加与驱动实现的途径,详细阐述了如何采用通用i2c-dev.c驱动常规IIC设备、如何编写特定IIC设备的probe方式驱动、怎样设计动态加载的简易IIC“客服-...
6.2.3 S3C2410A的I2C接口应用实例 6.3 USB接口 6.3.1 USB接口基本原理与结构 6.3.2 S3C2410A的USB控制器 6.3.3 S3C2410A的USB接口电路与驱动程序 6.4 SPI接口 6.4.1 SPI接口基本原理与结构 6.4.2 S3C2410A 的 SPI...
3.14内部集成电路(I2C)接口 3.14.1简介 3.14.2主要特性 3.14.3总体描述 3.14.4功能描述 3.14.5中断请求 3.14.6I2C调试模式 3.14.7I2C寄存器描述 3.15串行外设接FI(SPI) 3.15.1简介 3.15.2主要特性 3.15.3功能描述 ...
4.2.2 安装ARM Linux 内核.................161 4.2.3 安装NFS 根文件系统.................162 4.3 构建嵌入式Linux 目标平台 ...............166 4.3.1 相关文件.......................................166 ...
NUC1xx 系列为32位单片机,内建ARM® Cortex™-M0内核...并内建有定时器,看门狗定时器,RTC,PDMA,UART,SPI/SSP,I2C, I2S ,PWM定时器, GPIO,LIN,CAN,USB全速设备,12位ADC,模拟比较器,低电压检测和节电侦测功能。