您的位置:首页 > 其它

I2C总线相关_4

2017-03-28 20:33 253 查看
I2C会话分为两种

一种是读会话,一种是写会话

这两种会话都有固定的格式,按照数据手册上的时序写就行了

下面提供的是标准的I2C时序

特别注意下面的DELAY(x) 宏,你可以定义为你需要的时间.

时间可以从芯片手册中得知.

注意:I2C可以由内核中I2C框架实现,也可以用GPIO模拟I2C来实现.

两者的切换需要配置复用寄存器

//写会话
EXPORT_SYMBOL(gpio_i2c_write);
void gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char data)
{
i2c_start_bit();
i2c_send_byte(devaddress);
i2c_receive_ack();
i2c_send_byte(address);
i2c_receive_ack();
i2c_send_byte(data);
i2c_receive_ack();
i2c_stop_bit();
}


//这是标准i2c的流程

/*
* sends a start bit via I2C rountine.
*
*/
static void i2c_start_bit(void)
{
DELAY(1);
i2c_set(SDA | SCL);
DELAY(1);
i2c_clr(SDA);
DELAY(1);
}

//一般起始位都是在SDA与SCL同时高的时候,拉低SDA,这就开始了.


/*
* sends a character over I2C rountine.
*
* @param  c: character to send
*
*/
static void i2c_send_byte(unsigned char c)
{
int i;
local_irq_disable();
for (i=0; i<8; i++)
{
DELAY(1);
i2c_clr(SCL);
DELAY(1);
if (c & (1<<(7-i)))
i2c_set(SDA);
else
i2c_clr(SDA);
DELAY(1);
i2c_set(SCL);
DELAY(1);
i2c_clr(SCL);
}
DELAY(1);
local_irq_enable();
}
//一般发送字节,要不是发送的地址,就是发送的数据,起始都是一样的,都是将字节的字节发送,从最高位到最低位.


/*  receives an acknowledge from I2C rountine.
*
*  @return value: 0--Ack received; 1--Nack received
*
*/
static int i2c_receive_ack(void)
{
int nack;
unsigned char regvalue;

DELAY(1);

regvalue = HW_REG(GPIO_0_DIR);
regvalue &= (~SDA);
HW_REG(GPIO_0_DIR) = regvalue;

DELAY(1);
i2c_clr(SCL);
DELAY(1);
i2c_set(SCL);
DELAY(1);
nack = i2c_data_read();

DELAY(1);
i2c_clr(SCL);
DELAY(1);
//  i2c_set(SDA);
//  DELAY(1);
if (nack == 0)
return 1;

return 0;
}
//在往总线上发送一个字节之后,从机设备会发回一个ack,也就是回应,我们需要捕获这个回应.然后鉴别是否正确


/*
* sends a stop bit via I2C rountine.
*
*/
static void i2c_stop_bit(void)
{
/* clock the ack */
DELAY(1);
i2c_set(SCL);
DELAY(1);
i2c_clr(SCL);

/* actual stop bit */
DELAY(1);
i2c_clr(SDA);
DELAY(1);
i2c_set(SCL);
DELAY(1);
i2c_set(SDA);
DELAY(1);
}
//停止位,一般是在SDA和SCL同时为高的时候拉低SDA,然后代表依次会话结束.


//读会话
EXPORT_SYMBOL(gpio_i2c_read);
unsigned char gpio_i2c_read(unsigned char devaddress, unsigned char address)
{
int rxdata;

i2c_start_bit();
i2c_send_byte(devaddress);
i2c_receive_ack();
i2c_send_byte(address);
i2c_receive_ack();
i2c_start_bit();
i2c_send_byte((unsigned char)(devaddress) | 1);
i2c_receive_ack();
rxdata = i2c_receive_byte();
i2c_send_ack();//注意,这里是读ack
i2c_stop_bit();
return rxdata;
}
//读的周期一般比较长.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: