S5PV210下gpio模拟i2c

简单的示例,根据各自的情况修改~

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/gpio.h>


#define GPIO_W_ADDR     0x6a
#define GPIO_R_ADDR    (GPIO_W_ADDR | 0x1)

#define GPIO_SDA S5PV210_GPH3(3)                                        //随便写的gpio
#define GPIO_SCL S5PV210_GPH3(4)

#define GPIO_SDA_OUTP s3c_gpio_cfgpin(GPIO_SDA, S3C_GPIO_OUTPUT) 	//设定SDA输出
#define GPIO_SDA_INP  s3c_gpio_cfgpin(GPIO_SDA, S3C_GPIO_INPUT)  	//设定SDA输入

#define GPIO_SCL_OUTP s3c_gpio_cfgpin(GPIO_SCL, S3C_GPIO_OUTPUT) 	//设定SCL输出

#define GPIO_SDA_H gpio_set_value(GPIO_SDA, 1)
#define GPIO_SDA_L gpio_set_value(GPIO_SDA, 0)

#define GPIO_SCL_H gpio_set_value(GPIO_SCL, 1)
#define GPIO_SCL_L gpio_set_value(GPIO_SCL, 0)


/************************************
         GPIO  初始化
*************************************/
void gpio_init(void)
{
	s3c_gpio_setpull(GPIO_SCL, S3C_GPIO_PULL_NONE);		//disable pull up&down
	s3c_gpio_setpull(GPIO_SDA, S3C_GPIO_PULL_NONE);

	GPIO_SDA_OUTP;
	GPIO_SCL_OUTP;
}

/************************************
         总线初始化
*************************************/
void i2c_init(void)
{
    GPIO_SCL_L;
    udelay(5);			
    GPIO_SDA_H;
    udelay(5);			
    GPIO_SCL_H;
    udelay(5);			
}

/************************************
         接收ACK
*************************************/
void receive_ack(void)
{
     unsigned long ack;

     GPIO_SDA_INP;            		// Function <- Input (SDA)

     GPIO_SCL_L;
     udelay(5);
     GPIO_SCL_H;
     udelay(5);
     ack = gpio_get_value(GPIO_SDA);
     GPIO_SCL_H;
     udelay(5);

     while(ack!=0)			      //接收到非应答信号,等待!这里最好不要写成死循环的形式,因为是示例,我就随意了!
	 {
	 	GPIO_SCL_L;
     	udelay(5);
     	GPIO_SCL_H;
     	udelay(5);
     	ack = gpio_get_value(GPIO_SDA);
	printk("++++++++there is no ack +++++++++\n");
	 }

	 GPIO_SCL_L;
	 udelay(5);

	 GPIO_SDA_OUTP;                // Function <- Output (SDA)
}

/************************************
         起始信号
*************************************/
void i2c_start(void)
{
     GPIO_SCL_L;
     udelay(5);
     GPIO_SDA_H;
     udelay(5);
     GPIO_SCL_H;
     udelay(5);
     GPIO_SDA_L;
     udelay(5);
}

/************************************
         停止信号
*************************************/
void i2c_stop(void)
{
     GPIO_SCL_L;
     udelay(5);
     GPIO_SDA_L;
     udelay(5);
     GPIO_SCL_H;
     udelay(5);
     GPIO_SDA_H;
     udelay(5);  
}

/************************************
         写一个字节
*************************************/
void i2c_byte_write(unsigned char dat)
{
     unsigned long i;
     
     for(i = 8; i > 0; i--)
     {
          GPIO_SCL_L;                                //SCL拉低,使SDA变化有效
          udelay(5);
          if((dat >> (i-1)) & 0x0001)
          	GPIO_SDA_H;                              //SDA变化
          else
          	GPIO_SDA_L;
          udelay(5);
          GPIO_SCL_H;                               //SCL拉高, 从机读取SDA
          udelay(5);
     }
     GPIO_SCL_L; 
     udelay(5);
     GPIO_SDA_H;                                    //主机释放SDA,等待从机发送ACK或者NOACK
     udelay(5);
     receive_ack();
}

/************************************
         读一个字节
*************************************/
unsigned char i2c_byte_read(void)
{
     unsigned long i, dat = 0;
     
     GPIO_SDA_H;					 				//释放SDA
     udelay(5);
     
     GPIO_SDA_INP;                              // Function <- Input

     for(i = 0; i < 8; i++)
     {
          GPIO_SCL_H;                            //SCL拉高,等待从机发出SDA
          udelay(5);
          dat = (dat<<1)|(gpio_get_value(GPIO_SDA));   //读取从机发出的SDA
          udelay(5);                      
          GPIO_SCL_L;                           //SCL拉低,使从机改变或者SDA
          udelay(5);
     }
     
     GPIO_SCL_H;
     udelay(5);
     GPIO_SCL_L;
     udelay(5);
     GPIO_SCL_L;
     udelay(5);
     GPIO_SCL_H;
     udelay(5);

     GPIO_SDA_OUTP;                              // Function <- Output (SDA)

     return (unsigned char)dat;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章