这是凌鸥创芯的一款mcu,有客户在使用做电机控制,但i2c之前没有使用过,最近在调试一款产品,需使用i2c通信,
翻看平台demo没有合适的参考代码,仅有如下代码段
文件名为:I2cEEPROM.c
#include "lks32mc07x_lib.h"
#define I2C I2C0
uint8_t *txdata;
uint8_t txdatap = 0;
uint8_t *rxdata;
uint8_t rxdatap = 0;
volatile uint8_t state = 0; // 0 无动作 1接收 2发送
volatile uint8_t nackflg = 0; // 0 通信正常 1 发生nack事件
void i2c_tx(u8 taddr, u8 *data, u8 len)
{
nackflg = 0;
while (state != 0)
;
I2C->SCR = 0;
txdata = data;
txdatap = len;
state = 2;
I2C->DATA = taddr;
I2C->MSCR = 1; // 触发I2C发送数据
}
void i2c_rx(u8 taddr, u8 *data, u8 len)
{
nackflg = 0;
while (state != 0)
;
I2C->SCR = 0;
rxdata = data;
rxdatap = len;
state = 1;
I2C->DATA = taddr | 1;
I2C->MSCR = 1; // 触发I2C发送数据
}
void WriteData(u8 taddr, u16 data)
{
int i;
uint8_t txdata[3];
txdata[0] = taddr;
txdata[1] = data >> 8;
txdata[2] = data;
for (i = 0; i < 10; i++) // 如果收到nack 则最多尝试发送10次
{
i2c_tx(0x24, txdata, 3);
while (state != 0)
; // 等待发送完成
if (nackflg == 0)
{
return;
}
}
return;
}
u16 ReadData(u8 taddr)
{
uint8_t txdata[2];
int i;
uint16_t val;
for (i = 0; i < 10; i++) // 如果收到nack 则最多尝试发送10次
{
txdata[0] = taddr;
i2c_tx(0x24, txdata, 1);
i2c_rx(0x24, txdata, 2);
while (state != 0)
; // 等待发送完成
if (nackflg == 0) // 收到ack响应
{
val = ((uint16_t)(txdata[0]) << 8) | txdata[1];
return val;
}
}
return 0;
}
void I2C0_IRQHandler(void)
{
if (I2C->SCR & BIT1)
{
nackflg = 1;
}
if (I2C->SCR & BIT5)
{
state = 0;
I2C->SCR = 0;
}
else if (state == 1)
{
if (I2C->SCR & BIT3)
{
I2C->SCR = 0;
}
else
{
I2C->DATA = 0xff;
*rxdata = I2C->DATA;
rxdatap--;
if (rxdatap != 0)
{
rxdata++;
I2C->SCR = BIT4;
}
else
{
I2C->SCR = 0;
}
}
}
else if (state == 2)
{
if (txdatap != 0)
{
I2C->DATA = *txdata;
txdata++;
txdatap--;
I2C->SCR = BIT2;
}
else
{
I2C->SCR = 0;
}
}
else
{
I2C->SCR = 0;
}
}
对于普通的i2c接口没有视频,现做一下适配
u8 ic_address = 0x24;//从机地址
u8 MCU_ReadData(u8 reg)
{
uint8_t txdata[1];
int i;
uint8_t val;
for (i = 0; i < 1; i++) // 如果收到nack 则最多尝试发送1次
{
txdata[0] = reg;
i2c_tx(ic_address, txdata, 1);
i2c_rx(ic_address, txdata, 1);
while (state != 0)
; // 等待发送完成
if (nackflg == 0) // 收到ack响应
{
val = (uint8_t)txdata[0];
return val;
}
}
return 0;
}
void MCU_WriteData(u8 reg, u8 data)
{
int i;
uint8_t txdata[2];
txdata[0] = reg;
txdata[1] = data;
for (i = 0; i < 1; i++) // 如果收到nack 则最多尝试发送1次
{
i2c_tx(ic_address, txdata, 2);
while (state != 0)
; // 等待发送完成
if (nackflg == 0)
{
return;
}
}
return;
}
void MCU_WriteMultipleData(u8 start_reg, u8 *data, u8 len)
{
int i;
uint8_t *txdata = (uint8_t *)malloc(len + 1);
if (txdata == NULL)
{
return;
}
txdata[0] = start_reg;
for (i = 0; i < len; i++)
{
txdata[i + 1] = data[i];
}
for (i = 0; i < 1; i++)
{
i2c_tx(ic_address, txdata, len + 1);
while (state != 0);
if (nackflg == 0)
{
free(txdata);
return;
}
}
free(txdata);
return;
}
void MCU_ReadMultipleData(u8 start_reg, u8 *data, u8 len)
{
int i;
uint8_t txdata[1];
txdata[0] = start_reg;
for (i = 0; i < 10; i++)
{
i2c_tx(ic_address, txdata, 1);
if (nackflg == 0)
{
break;
}
}
if (nackflg != 0)
{
return;
}
// 读取数据
for (i = 0; i < 10; i++)
{
i2c_rx(ic_address, data, len);
if (nackflg == 0)
{
return;
}
}
return;
}
器件扫描函数如下:
#define I2C_MIN_ADDRESS 0x01
#define I2C_MAX_ADDRESS 0x7F
void I2C_ScanDevices()
{
printf("Scanning I2C bus...\n");
for (uint8_t address = I2C_MIN_ADDRESS; address <= I2C_MAX_ADDRESS; address++)
{
uint8_t dummy_data = 0;
if (i2c_tx(address, &dummy_data, 0) == 0) // 发送0字节数据作为探测
{
printf("I2C device found at address: 0x%02X\n", address);
}
}
printf("Scan complete.\n");
}
可利用以上几个函数作为通信,仅做参考,