GPIO模拟I2C-1
2011-08-29 11:57
260 查看
GPIO模拟I2C是嵌入式中较为常用的一种应用。各个地方有各种不同的做法,按照我自己的个人理解,最好是把I2C的各种状态分割开来,比如起始条件终止条件,读数据和写数据,然后根据具体的使用场合组合起来。 这里需要注意两点:一是SCL的波形并不规律,不能将它理解为方波,它本身只是一段段独立的波形。二是每段操作时,之前和之后的SCL和SDA波形是可以不用计较的;通常情况下I2C开始之前和I2C结束之后,两者都是高电平,而在正常工作时两者不受控制的情况下都是默认低电平。 (1)基础宏定义 #define GPIO_SCL S3C2410_GPF3 #define GPIO_SDA S3C2410_GPF0 #define GPIO_SDA_OUTP S3C2410_GPF0_OUTP //设定SDA输出 #define GPIO_SDA_INP S3C2410_GPF0_INP //设定SDA输入 #define GPIO_SCL_OUTP S3C2410_GPF3_OUTP //设定SCL输出 void I2C_SCL_OUTP( void ) { s3c2410_gpio_cfgpin(GPIO_SCL,GPIO_SCL_OUTP); } void I2C_SCL_Output(u8 value) { if(value) { s3c2410_gpio_setpin(GPIO_SCL,value); } else { s3c2410_gpio_setpin(GPIO_SCL,value ); } } void I2C_SDA_Mode(u8 v_mode) //SDA输出方向 { if(v_mode) { s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_OUTP); } else { s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_INP); } } void I2C_SDA_Output(u8 value) { if(value) { s3c2410_gpio_setpin(GPIO_SDA,value); } else { s3c2410_gpio_setpin(GPIO_SDA,value ); } } u8 I2C_SDA_Read(void) //SDA读数据 { return s3c2410_gpio_getpin(GPIO_SDA); } (2)基础段 void I2C_Init(void) { I2C_SDA_Output(1); I2C_SCL_Output(1); //默认拉高 } void I2C_Wait(void) { u16 i; for(i=0;i<200;i++); } void I2C_Start(void) { I2C_SDA_Output(1); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(0); } void I2C_Stop(void) { I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(1); }
(3)读写单个字节的段 u8 I2C_Send_Byte(u8 bytedata) { u8 i,ack; I2C_SDA_Mode(1); //SDA输出 I2C_SCL_OUTP(); for (i = 0; i < 8; i++) { if (bytedata & 0x80) { I2C_SDA_Output(1); } else { I2C_SDA_Output(0); } bytedata <<= 1; I2C_SCL_Output(1); udelay(3); I2C_SCL_Output(0); udelay(1); } I2C_SDA_Output(1); //release udelay(3); I2C_SDA_Mode(0); //设定SDA输入 I2C_SCL_Output(1); udelay(3); ack = I2C_SDA_Read(); //读应答 I2C_SDA_Mode(1); I2C_SCL_Output(0); udelay(3); return ack; } u8 I2C_Receive_Byte(void) { u8 i; u8 bytedata = 0x00; u8 temp; I2C_SDA_Mode(0); for ( i = 0; i < 8; i++) { I2C_SCL_Output(1); udelay(3); bytedata <<= 1; temp = I2C_SDA_Read(); printk("reda SDA'value is:%d\n",temp); if (temp) bytedata |= 0x01; printk(" bytedata is:%x\n",bytedata); I2C_SCL_Output(0); udelay(1); } I2C_SDA_Mode(1); return bytedata; } (4)读写单个字节的I2C应用函数 u8 I2C_Byte_Write(u8 device_ID,u8 address,u8 bytedata) { u8 ack; printk("device_ID is:%x\n",device_ID); printk("address is:%x\n",address); printk("date is:%x\n",bytedata); I2C_Start(); ack=I2C_Send_Byte(device_ID); printk("ack is:%d\n",ack); if(ack) I2C_Stop(); I2C_Send_Byte(address); I2C_Send_Byte(bytedata); I2C_Stop(); I2C_Wait(); return 0; } u8 I2C_Byte_Read(u8 device_ID,u8 address) { u8 bytedata; I2C_Start(); I2C_Send_Byte(device_ID); I2C_Send_Byte(address); I2C_Start(); I2C_Send_Byte(device_ID+1); bytedata = I2C_Receive_Byte(); //读单个字节,不需要再发应答 I2C_Stop(); return bytedata; } (5)类似可以完成读写多个字节的函数,暂不补充。
相关文章推荐
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
- 高通gpio模拟i2c
- stm32_GPIO模拟I2c读写EEPROM
- GPIO模拟I2C程序实现
- linux平台上GPIO模拟I2C
- ARM linux 内核gpio模拟I2C
- linux平台上GPIO模拟I2C
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
- linux平台上GPIO模拟I2C
- I2C、I2S、SPI、GPIO模拟I2C学习笔记
- GPIO模拟I2C-1
- GPIO模拟I2C快速入门 与程序实现+软件模拟I2C时序
- ARM Linux 内核gpio模拟I2C
- GPIO模拟I2C操作
- GPIO模拟I2C程序实现.
- GPIO模拟I2C程序实现
- linux gpio模拟i2c的使用/用GPIO模拟I2C总线-1
- Linux 内核gpio模拟I2C
- 调试gpio模拟i2c的TP中碰到的问题