K210自带的i2c有个不好的地方,就是当你读取数据的时候,若因为地址问题没有通讯上的话,是没有办法通过示波器来测试这个设备是否应答的,只发一次若不应答就会把程序给卡死,所以有些时候还是需要用到模拟的i2c来测试,但模拟的i2c也有一个不好的地方就是速率比较慢,若是一些寄存器相对较少的可以,但多起来了不排除有错误的风险。
整理一下相关代码,如下,这里随便找了一个设备来做这个例子代码,大同小异,根据需求来改即可,代码写得不够精简,请见谅:
#ifndef _I2C_GM7122_H
#define _I2C_GM7122_H
#include
#include
#include
#include
#include
#define GM7122_SLAVE_ADDRESS 0x44
void GM7122_i2c_master_init(void);
uint8_t GM7122_i2c_write_reg(uint8_t reg, uint8_t *data_buf, size_t length);
uint8_t GM7122_i2c_read_reg(uint8_t reg, uint8_t *data_buf, size_t length);
uint8_t GM7122_init(void);
#endif
#include
#include
#include "i2c_GM7122.h"
#define DELAY_TIME 10
static handle_t piohs;
static handle_t pwm1;
#define GM7122_SCL 8
#define GM7122_SDA 9
void GM7122_i2c_master_init(void)
{
piohs = io_open("/dev/gpio0");
gpio_set_drive_mode(piohs, GM7122_SCL, GPIO_DM_OUTPUT);
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_OUTPUT);
gpio_set_drive_mode(piohs, 10, GPIO_DM_OUTPUT);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_HIGH);
gpio_set_pin_value(piohs, 10, GPIO_PV_HIGH);
}
void GM7122_i2c_start(void)
{
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_OUTPUT);
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_HIGH);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_LOW);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_LOW);
}
void GM7122_i2c_stop(void)
{
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_OUTPUT);
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_LOW);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_HIGH);
}
uint8_t GM7122_i2c_send_byte(uint8_t data)
{
uint8_t index;
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_OUTPUT);
for (index = 0; index < 8; index++)
{
if (data & 0x80)
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_HIGH);
else
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_LOW);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_LOW);
data <<= 1;
}
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_INPUT);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
data = gpio_get_pin_value(piohs, GM7122_SDA);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_LOW);
return data;
}
uint8_t GM7122_i2c_receive_byte(uint8_t ack)
{
uint8_t index, data = 0;
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_INPUT);
for (index = 0; index < 8; index++)
{
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
data <<= 1;
if (gpio_get_pin_value(piohs, GM7122_SDA))
data++;
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_LOW);
}
gpio_set_drive_mode(piohs, GM7122_SDA, GPIO_DM_OUTPUT);
if (ack)
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_HIGH);
else
gpio_set_pin_value(piohs, GM7122_SDA, GPIO_PV_LOW);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_HIGH);
usleep(DELAY_TIME);
gpio_set_pin_value(piohs, GM7122_SCL, GPIO_PV_LOW);
return data;
}
uint8_t GM7122_i2c_write_reg(uint8_t reg, uint8_t *data_buf, size_t length)
{
GM7122_i2c_start();
GM7122_i2c_send_byte(GM7122_SLAVE_ADDRESS << 1);
GM7122_i2c_send_byte(reg);
while (length--)
GM7122_i2c_send_byte(*data_buf++);
GM7122_i2c_stop();
return 0;
}
uint8_t GM7122_i2c_read_reg(uint8_t reg, uint8_t *data_buf, size_t length)
{
GM7122_i2c_start();
GM7122_i2c_send_byte(GM7122_SLAVE_ADDRESS << 1);
GM7122_i2c_send_byte(reg);
GM7122_i2c_start();
GM7122_i2c_send_byte((GM7122_SLAVE_ADDRESS << 1) + 1);
while (length > 1L)
{
*data_buf++ = GM7122_i2c_receive_byte(0);
length--;
}
*data_buf++ = GM7122_i2c_receive_byte(1);
GM7122_i2c_stop();
return 0;
}
uint8_t GM7122_init(void)
{
uint8_t GM7122_init_reg[17] = {0x28, 0x29, 0x3A, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x6B, 0x6C, 0x6D};
uint8_t GM7122_init_buf[17] = {0x21, 0x1D, 0x03, 0x00, 0x6D, 0x9F, 0x0E, 0x1C, 0x06, 0x3B, 0xCB, 0x8A, 0x09, 0x2A, 0x00, 0x51, 0x11};
uint8_t temp[17] ;
uint8_t i;
printf("GM7122 i2c init start\r\n");
GM7122_i2c_master_init();
for(i=0 ; i<17 ; i++){
GM7122_i2c_write_reg(GM7122_init_reg[i],&GM7122_init_buf[i],1);
GM7122_i2c_read_reg(GM7122_init_reg[i] ,&temp[i],1);
printf("[GM7122]0x%x -> 0x%x\r\n",GM7122_init_reg[i],temp[i]);
}
printf("GM7122 i2c init is ok\r\n");
return 0;
}