lks32mc07x 平台I2C使用心得

这是凌鸥创芯的一款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");
}

可利用以上几个函数作为通信,仅做参考,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值