GPIO模拟i2c时序
2016-11-28 09:26
405 查看
#define DELAY 1
/******************************start*****************************************/
void i2c_start(void)
{
gpio_direction_output(SDA, 1);
gpio_direction_output(SCL, 1);
udelay(DELAY);
gpio_set_value(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
}
/**********************************************stop****************************************/
void i2c_stop(void)
{
gpio_set_value(SCL, 0);
gpio_set_value(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SDA, 1);
udelay(DELAY);
}
/********************************send_ack****************************************/
void i2c_send_ack(u8 ack)
{
if(ack)
gpio_direction_output(SDA, 1);
else
gpio_direction_output(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
}
/********************************receive_ack*********************************/
u8 i2c_receive_ack(void)
{
u8 rc = 0;
gpio_direction_input(SDA);
gpio_set_value(SCL, 1);
udelay(DELAY);
if(gpio_get_value(SDA)) {
rc = 1;
}
gpio_set_value(SCL, 0);
gpio_direction_output(SDA, 1);
return rc;
}
/********************************send****************************************/
u8 i2c_send_byte(u8 send_byte)
{
u8 rc = 0;
u8 out_mask = 0x80;
u8 value;
u8 count = 8;
while(count > 0) {
value = ((send_byte & out_mask) ? 1 : 0);
if (value == 1) {
gpio_set_value(SDA, 1);
}
else {
gpio_set_value(SDA, 0);
}
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
out_mask >>= 1;
count--;
}
gpio_set_value(SDA, 1);
rc = i2c_receive_ack();
return rc;
}
/**********************************************receive*************************************/
void i2c_read_byte(u8 *buffer, u8 ack)
{
u8 count = 0x08;
u8 data = 0x00;
u8 temp = 0;
gpio_direction_input(SDA);
while(count > 0) {
gpio_set_value(SCL, 1);
udelay(DELAY);
temp = gpio_get_value(SDA);
data <<= 1;
if (temp)
data |= 0x01;
gpio_set_value(SCL, 0);
udelay(DELAY);
count--;
}
i2c_send_ack(ack);//0 = ACK 1 = NACK
*buffer = data;
}
//向client的某个寄存器写入多个字节,len是要写入的数据的长度
/***********************************************write_bytes********************************/
u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)
{
u8 rc = 0;
u8 i;
i2c_start();
rc |= i2c_send_byte( (device_id << 1) | 0x00 );
rc |= i2c_send_byte(reg_address);
if(data==NULL ||0==len) {
i2c_stop();
return rc;
}
for(i=0; i<len; i++) {
rc |= i2c_send_byte(*data);
data++;
}
i2c_stop();
return rc;
}
//从某个register中读取len个字节放在长度为len的缓冲区buffer中
/***********************************************read_bytes********************************/
u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u16 len)
{
u8 rc = 0;
u16 i;
i2c_start();
rc |= i2c_send_byte( (device_id << 1) | 0x00 );
rc |= i2c_send_byte(reg_address);
i2c_start();//restart I2C
rc |= i2c_send_byte( (device_id << 1) | 0x01 );
for(i=0;i<len;i++) {
i2c_read_byte(buffer++, !(len-i-1));// !(len-i-1) 这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK
}
i2c_stop();
return rc;
}
#define DELAY 1
/******************************start*****************************************/
void i2c_start(void)
{
gpio_direction_output(SDA, 1);
gpio_direction_output(SCL, 1);
udelay(DELAY);
gpio_set_value(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
}
/**********************************************stop****************************************/
void i2c_stop(void)
{
gpio_set_value(SCL, 0);
gpio_set_value(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SDA, 1);
udelay(DELAY);
}
/********************************send_ack****************************************/
void i2c_send_ack(u8 ack)
{
if(ack)
gpio_direction_output(SDA, 1);
else
gpio_direction_output(SDA, 0);
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
}
/********************************receive_ack*********************************/
u8 i2c_receive_ack(void)
{
u8 rc = 0;
gpio_direction_input(SDA);
gpio_set_value(SCL, 1);
udelay(DELAY);
if(gpio_get_value(SDA)) {
rc = 1;
}
gpio_set_value(SCL, 0);
gpio_direction_output(SDA, 1);
return rc;
}
/********************************send****************************************/
u8 i2c_send_byte(u8 send_byte)
{
u8 rc = 0;
u8 out_mask = 0x80;
u8 value;
u8 count = 8;
while(count > 0) {
value = ((send_byte & out_mask) ? 1 : 0);
if (value == 1) {
gpio_set_value(SDA, 1);
}
else {
gpio_set_value(SDA, 0);
}
udelay(DELAY);
gpio_set_value(SCL, 1);
udelay(DELAY);
gpio_set_value(SCL, 0);
udelay(DELAY);
out_mask >>= 1;
count--;
}
gpio_set_value(SDA, 1);
rc = i2c_receive_ack();
return rc;
}
/**********************************************receive*************************************/
void i2c_read_byte(u8 *buffer, u8 ack)
{
u8 count = 0x08;
u8 data = 0x00;
u8 temp = 0;
gpio_direction_input(SDA);
while(count > 0) {
gpio_set_value(SCL, 1);
udelay(DELAY);
temp = gpio_get_value(SDA);
data <<= 1;
if (temp)
data |= 0x01;
gpio_set_value(SCL, 0);
udelay(DELAY);
count--;
}
i2c_send_ack(ack);//0 = ACK 1 = NACK
*buffer = data;
}
//向client的某个寄存器写入多个字节,len是要写入的数据的长度
/***********************************************write_bytes********************************/
u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)
{
u8 rc = 0;
u8 i;
i2c_start();
rc |= i2c_send_byte( (device_id << 1) | 0x00 );
rc |= i2c_send_byte(reg_address);
if(data==NULL ||0==len) {
i2c_stop();
return rc;
}
for(i=0; i<len; i++) {
rc |= i2c_send_byte(*data);
data++;
}
i2c_stop();
return rc;
}
//从某个register中读取len个字节放在长度为len的缓冲区buffer中
/***********************************************read_bytes********************************/
u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u16 len)
{
u8 rc = 0;
u16 i;
i2c_start();
rc |= i2c_send_byte( (device_id << 1) | 0x00 );
rc |= i2c_send_byte(reg_address);
i2c_start();//restart I2C
rc |= i2c_send_byte( (device_id << 1) | 0x01 );
for(i=0;i<len;i++) {
i2c_read_byte(buffer++, !(len-i-1));// !(len-i-1) 这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK
}
i2c_stop();
return rc;
}
相关文章推荐
- linux i2c-gpio 模拟i2c时序出现oops错误
- 18、基于 STM32 的 I2C 时序 - GPIO 模拟方式
- GPIO模拟I2C快速入门 与程序实现+软件模拟I2C时序
- GPIO模拟I2C程序实现
- GPIO模拟I2C程序实现.
- linux gpio模拟i2c的使用/用GPIO模拟I2C总线-1
- I2C、I2S、SPI、GPIO模拟I2C学习笔记
- GPIO模拟I2C操作调试注意事项
- linux2.4 GPIO模拟实现I2C数据传输-DS1302
- gpio模拟I2C,驱动pcf8574T
- davinci平台的I2C驱动(非GPIO口模拟i2c)
- STM32模拟I2C时序读写EEPROM精简版
- linux gpio模拟i2c的使用/用GPIO模拟I2C总线-2
- I2C总线时序模拟(二)-加深理解总线协议
- I2C学习之 STC15F204EA---GPIO端口模拟--简单控制PCF8574AT
- 深入理解I2C总线时序的模拟
- I2C总线概要及用GPIO模拟I2C
- Linux I2C子系统分析之(一) ----- 用GPIO模拟I2C总线
- linux gpio模拟i2c的使用/用GPIO模拟I2C总线-3