簡單的示例,根據各自的情況修改~
#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;
}