`
sony-soft
  • 浏览: 1019468 次
文章分类
社区版块
存档分类
最新评论

ARM linux 内核gpio模拟I2C

 
阅读更多

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

    内核gpio模拟i2c,代码为项目抽离代码,请注意排查代码

    LPC2300系列ARM-I2C接口(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    Linux驱动开发:Linux内核模块、字符设备驱动、IO模型、设备树、GPIO子系统、中断子系统.zip

    Linux驱动开发:Linux内核模块、字符设备驱动、IO模型、设备树、GPIO子系统、中断子系统、platform总线驱动、I2C总线驱动、SPI总线驱动 Linux项目是一个开放源代码的操作系统项目,由林纳斯·托瓦兹(Linus Torvalds...

    ARM9嵌入式Linux开发 ppt——周卫老师

     I2C总线接口和SPI总线接口  LCD控制器  ADC和触摸屏接口 分析U-Boot的代码结构,并介绍如何移植到开发板上。  分析Linux内核的代码结构以及启动过程,并介绍如何移植到开发板上。  介绍嵌入式Linux文件...

    LPC2300系列ARM-I2S(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    linux驱动由入门到精通代码

    具体内容包括Linux驱动开发入门基础知识,Linux操作系统下驱动开发核心技术,并对ARM系统的各类接口的原理、驱动开发与应用层开发进行逐一分析,其中包括GPIO、CAN、I2C、LCD、USB、触摸屏、网络、块设备、红外、SD...

    ARM嵌入式系统设计基础教程课件

    第6章介绍了嵌入式系统的串行接口、I2C接口、USB接口、SPI接口、PCI接口、I2S总线接口的基本原理、电路结构与编程方法; 第7章介绍了嵌入式系统网络接口,包含有以太网接口、CAN总线接口的基本原理、电路结构与编程...

    嵌入式Linux应用开发完全手册.pdf

    硬件部件的使用及编程(囊括了常见硬件,比如UART、I*IC、LCD等),UBoot、Linux内核的分析、配置和移植,根文件系统的构造(包括移植busybox、glibc、制作映象文件等),内核调试技术(比如添加kgdb补丁、栈回溯等),...

    LPC2300系列ARM-USB(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    LPC2300系列ARM-DMA(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    LPC2300系列ARM-以太网(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    LPC2300系列ARM-SPI(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    LPC2300系列ARM-定时器计数器(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    LPC2300系列ARM-看门狗定时器(周立功价值2600元的ARM学习课件PPT)

    买的周立功价值两千6百元的工控产品资料...如I2C,SPI,CAN,USB,UART,AD,DA,GPIO,SD,SSP,I2S等,绝对超值,是深入学习ARM的好资料 另外本资料是外部不能单独买的,只有购买周立功指定的开发板才能拥有的,强烈推荐!!!

    嵌入式Linux应用程序开发标准教程(第2版全)

    《嵌入式Linux应用程序开发标准教程(第2版)》主要分为3个部分,包括Linux基础、搭建嵌入式Linux环境和嵌入式Linux的应用开发。Linux基础部分从Linux基础、基本操作命令讲起,为Linux初学者能快速入门提供了保证。...

    ARM-Linux-IIC设备的添加与驱动实现

    分析了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...

    STM32系列ARM Cortex-M3微控制器原理与实践_清晰版

    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功能描述 ...

    Magic ARM 2410

    4.2.2 安装ARM Linux 内核.................161 4.2.3 安装NFS 根文件系统.................162 4.3 构建嵌入式Linux 目标平台 ...............166 4.3.1 相关文件.......................................166 ...

    NuMicro系列32-位Cortex™-M0 单片机应用指南

    NUC1xx 系列为32位单片机,内建ARM® Cortex™-M0内核...并内建有定时器,看门狗定时器,RTC,PDMA,UART,SPI/SSP,I2C, I2S ,PWM定时器, GPIO,LIN,CAN,USB全速设备,12位ADC,模拟比较器,低电压检测和节电侦测功能。

Global site tag (gtag.js) - Google Analytics