STM32用GPIO模拟I2C主机程序库

一、基础信息

1.1、简介

基于STM32单片机HAL库,用GPIO模拟I2C主机时序,可作为程序库使用。

1.2、说明

1)根据硬件连接的I2C从机设备的地址字节数,对应定义DataAddressSizeof的值,仅支持1个字节和2个字节。

2)调用I2C_Typedef,定义I2C设备结构体;调用I2CInit,通过结构体传参的方式,设置I2C设备结构体的参数。

3)I2C设备结构体的ICTE为时序时间参数,单位为NOP,需基于单片机主频和I2C从机设备时序要求进行设置。

4)I2C设备结构体的ICGO为GPIO引脚端口号和引脚号参数。

5)调用函数I2CWriteData,往I2C设备写入数据;调用函数I2CReadData,从I2C设备读取数据。

二、头文件定义

2.1、读写地址的字节数

定义I2C从机读写地址的字节数。定义为1,表示地址为1个字节,取值范围为0~255;定义为2,表示地址为2个字节,取值范围0~65535。若定义为其他值,则编译程序会报错。


/*
 * DataAddressSizeof:读写地址的字节数
 * 取值:1和2
 */
#define DataAddressSizeof 2

2.2、函数执行结果

未具体说明的函数,参照此处定义;若函数注释有具体说明,则以注释内容为准。


typedef enum
{
    I2CResult_NULL,             //未执行
    I2CResult_OK,               //执行成功
    I2CResult_ERROR,            //执行出错
}
I2CResult_Typedef;              //函数执行结果

2.3、I2C结构体

使用时,只调用I2C_Typedef定义I2C结构体。


typedef struct
{
    uint8_t read;                //读取
    uint8_t write;                //写入
}
I2CControlByte_Typedef;            //控制字节

typedef struct
{
    uint16_t scl_high_hold;        //SCL高电平保持时间,单位:nop
    uint16_t scl_low_hold;        //SCL低电平保持时间,单位:nop
    uint16_t sda_high_hold;        //SDA高电平保持时间,单位:nop
    uint16_t sda_low_hold;        //SDA低电平保持时间,单位:nop

    uint16_t wait_ack;            //等待ACK,单位:nop。到达等待时间,仍未接收到ACK,则判定为Not ACK。
}
I2CTime_Typedef;                //I2C时间设置

typedef struct
{
    GPIO_TypeDef* scl_port;        //SCL端口
    GPIO_TypeDef* sda_port;        //SDA端口

    uint16_t scl_pin;            //SCL引脚
    uint16_t sda_pin;            //SDA引脚
}
I2C_GPIO_Typedef;                //I2C的GPIO

typedef struct
{
    I2CControlByte_Typedef ICCB;//ControlByte
    I2CTime_Typedef ICTE;        //TIME
    I2C_GPIO_Typedef ICGO;        //GPIO
}
I2C_Typedef;

2.4、接口函数声明

供其他工程文件调用的函数。包含I2CInit、I2CWriteData、I2CReadData。


/*
 * 功能:初始化I2C
 * 输入:@p_I2C:I2C结构体指针
 *         @SetI2C:设置参数结构体
 * 输出:无
 * 备注:
 */
void I2CInit(I2C_Typedef* p_I2C,I2C_Typedef SetI2C);

#if DataAddressSizeof == 1

/*
 * 功能:I2C写数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:写入地址
 *         @p_data:写入数据缓存
 *         @size:写入数据大小
 * 输出:I2CResult_OK:写入成功
 *         I2CResult_ERROR:写入失败
 * 备注:
 */
I2CResult_Typedef I2CWriteData(I2C_Typedef* p_I2C,uint8_t address,uint8_t* p_data,uint8_t size);

/*
 * 功能:I2C读数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:读取地址
 *         @p_data:读取数据缓存
 *         @size:读取数据大小
 * 输出:I2CResult_OK:读取成功
 *         I2CResult_ERROR:读取失败
 * 备注:
 */
I2CResult_Typedef I2CReadData(I2C_Typedef* p_I2C,uint8_t address,uint8_t* p_data,uint8_t size);

#elif DataAddressSizeof == 2

/*
 * 功能:I2C写数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:写入地址
 *         @p_data:写入数据缓存
 *         @size:写入数据大小
 * 输出:I2CResult_OK:写入成功
 *         I2CResult_ERROR:写入失败
 * 备注:
 */
I2CResult_Typedef I2CWriteData(I2C_Typedef* p_I2C,uint16_t address,uint8_t* p_data,uint16_t size);

/*
 * 功能:I2C读数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:读取地址
 *         @p_data:读取数据缓存
 *         @size:读取数据大小
 * 输出:I2CResult_OK:读取成功
 *         I2CResult_ERROR:读取失败
 * 备注:
 */
I2CResult_Typedef I2CReadData(I2C_Typedef* p_I2C,uint16_t address,uint8_t* p_data,uint16_t size);

#else

ERROR:The value of DataAddressSizeof can only be 1 or 2; //DataAddressSizeof的值只能为1或2

#endif

三、工程文件

3.1、空操作延时


/*
 * 功能:I2C软件延时
 * 输入:@nop_number:空操作次数
 * 输出:无
 * 备注:
 */
static void I2CDelay(uint16_t nop_number)
{
    uint16_t i;

    for(i = 0;i < nop_number;i ++)
    {
        __NOP();
    }
}

3.2、GPIO操作函数

非HAL库,没有函数HAL_GPIO_WritePin,可以替换为对应功能的程序。


/*
 * 功能:拉高SDA
 * 输入:@p_I2C:I2C结构体指针
 * 输出:无
 * 备注:
 */
static void I2CSetSDA(I2C_Typedef* p_I2C)
{
    HAL_GPIO_WritePin(p_I2C->ICGO.sda_port, p_I2C->ICGO.sda_pin, GPIO_PIN_SET);        //拉高:SDA

    I2CDelay(p_I2C->ICTE.sda_high_hold);
}

/*
 * 功能:拉低SDA
 * 输入:@p_I2C:I2C结构体指针
 * 输出:无
 * 备注:
 */
static void I2CResetSDA(I2C_Typedef* p_I2C)
{
    HAL_GPIO_WritePin(p_I2C->ICGO.sda_port, p_I2C->ICGO.sda_pin, GPIO_PIN_RESET);        //拉高:SDA

    I2CDelay(p_I2C->ICTE.sda_low_hold);
}

/*
 * 功能:拉高SCL
 * 输入:@p_I2C:I2C结构体指针
 * 输出:无
 * 备注:
 */
static void I2CSetSCL(I2C_Typedef* p_I2C)
{
    HAL_GPIO_WritePin(p_I2C->ICGO.scl_port, p_I2C->ICGO.scl_pin, GPIO_PIN_SET);        //拉高:SDA

    I2CDelay(p_I2C->ICTE.scl_high_hold);
}

/*
 * 功能:拉低SCL
 * 输入:@p_I2C:I2C结构体指针
 * 输出:无
 * 备注:
 */
static void I2CResetSCL(I2C_Typedef* p_I2C)
{
    HAL_GPIO_WritePin(p_I2C->ICGO.scl_port, p_I2C->ICGO.scl_pin, GPIO_PIN_RESET);        //拉高:SDA

    I2CDelay(p_I2C->ICTE.scl_low_hold);
}

3.3、I2C协议函数

I2C协议函数主体,包含I2CStart、I2CStop、I2CWaitAck、I2CSendAck、I2CSendNotAck、I2CWriteByte和I2CReadByte。


/*
 * 功能:开始I2C
 * 输入:@p_I2C:I2C结构体指针
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CStart(I2C_Typedef* p_I2C)
{
    I2CSetSDA(p_I2C);        //拉高:SDA
    I2CSetSCL(p_I2C);        //拉高:SCL

    I2CResetSDA(p_I2C);        //拉低:SDA
    I2CResetSCL(p_I2C);        //拉低:SCL

    return I2CResult_OK;
}

/*
 * 功能:结束I2C
 * 输入:@p_I2C:I2C结构体指针
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CStop(I2C_Typedef* p_I2C)
{
    I2CResetSCL(p_I2C);        //拉低:SCL
    I2CResetSDA(p_I2C);        //拉低:SDA

    I2CSetSCL(p_I2C);        //拉高:SCL
    I2CSetSDA(p_I2C);        //拉高:SDA

    return I2CResult_OK;
}

/*
 * 功能:等待应答
 * 输入:@p_I2C:I2C结构体指针
 * 输出:I2CResult_OK:应答成功
 *         I2CResult_ERROR:应答失败
 * 备注:
 */
static I2CResult_Typedef I2CWaitAck(I2C_Typedef* p_I2C)
{
    uint16_t i;

    I2CSetSDA(p_I2C);        //拉高:SDA
    I2CSetSCL(p_I2C);        //拉高:SCL

    for(i = 0;i < p_I2C->ICTE.wait_ack;i ++)
    {
        if(HAL_GPIO_ReadPin(p_I2C->ICGO.sda_port, p_I2C->ICGO.sda_pin) == GPIO_PIN_RESET)    //判定:应答成功
        {
            I2CResetSCL(p_I2C);        //拉低:SCL

            return I2CResult_OK;
        }
    }

    I2CStop(p_I2C);

    return I2CResult_ERROR;
}

/*
 * 功能:输出应答
 * 输入:@p_I2C:I2C结构体指针
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CSendAck(I2C_Typedef* p_I2C)
{
    I2CResetSDA(p_I2C);        //拉低:SDA
    I2CSetSCL(p_I2C);        //拉高:SCL

    I2CResetSCL(p_I2C);        //拉低:SCL

    return I2CResult_OK;
}

/*
 * 功能:输出非应答
 * 输入:@p_I2C:I2C结构体指针
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CSendNotAck(I2C_Typedef* p_I2C)
{
    I2CSetSDA(p_I2C);        //拉高:SDA
    I2CSetSCL(p_I2C);        //拉高:SCL

    I2CResetSCL(p_I2C);        //拉低:SCL

    return I2CResult_OK;
}

/*
 * 功能:写一个字节
 * 输入:@p_I2C:I2C结构体指针
 *         @data:写入的数据
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CWriteByte(I2C_Typedef* p_I2C,uint8_t data)
{
    uint8_t i;

    for(i = 0;i < 8;i ++)
    {
        I2CResetSCL(p_I2C);            //拉低:SCL

        if((data & 0x80) == 0x80)
        {
            I2CSetSDA(p_I2C);        //拉高:SDA
        }
        else
        {
            I2CResetSDA(p_I2C);        //拉低:SDA
        }

        I2CSetSCL(p_I2C);            //拉高:SCL

        data <<= 1;
    }

    I2CResetSCL(p_I2C);                //拉低:SCL

    return I2CResult_OK;
}

/*
 * 功能:读一个字节
 * 输入:@p_I2C:I2C结构体指针
 *         @p_data:读取数据的缓存
 * 输出:I2CResult_OK
 * 备注:
 */
static I2CResult_Typedef I2CReadByte(I2C_Typedef* p_I2C,uint8_t* p_data)
{
    uint8_t i;

    *p_data = 0;

    I2CSetSDA(p_I2C);            //拉高:SDA

    for(i = 0;i < 8;i ++)
    {
        I2CSetSCL(p_I2C);        //拉高:SCL

        *p_data <<= 1;

        if(HAL_GPIO_ReadPin(p_I2C->ICGO.sda_port, p_I2C->ICGO.sda_pin) == GPIO_PIN_SET)        //判定:SDA为高
        {
            *p_data += 1;
        }

        I2CResetSCL(p_I2C);        //拉低:SCL
    }

    return I2CResult_OK;
}

3.4、接口函数

“2.4、接口函数声明”的函数主体。


/*
 * 功能:初始化I2C
 * 输入:@p_I2C:I2C结构体指针
 *         @SetI2C:设置参数结构体
 * 输出:无
 * 备注:
 */
void I2CInit(I2C_Typedef* p_I2C,I2C_Typedef SetI2C)
{
    *p_I2C = SetI2C;

    I2CSetSDA(p_I2C);        //拉高:SDA
    I2CSetSCL(p_I2C);        //拉高:SCL
}

#if DataAddressSizeof == 1

/*
 * 功能:I2C写数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:写入地址
 *         @p_data:写入数据缓存
 *         @size:写入数据大小
 * 输出:I2CResult_OK:写入成功
 *         I2CResult_ERROR:写入失败
 * 备注:
 */
I2CResult_Typedef I2CWriteData(I2C_Typedef* p_I2C,uint8_t address,uint8_t* p_data,uint8_t size)
{
    uint8_t i = 0;

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.write);                    //执行:写入I2C写指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address);                            //执行:写入地址
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    for(i = 0;i < size;i ++)
    {
        I2CWriteByte(p_I2C,*(p_data + i));                    //执行:写入1个字节
        if(I2CWaitAck(p_I2C) != I2CResult_OK)                //判定:I2C非应答
        {
            return I2CResult_ERROR;
        }
    }

    I2CStop(p_I2C);                                            //执行:停止I2C

    return I2CResult_OK;
}

/*
 * 功能:I2C读数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:读取地址
 *         @p_data:读取数据缓存
 *         @size:读取数据大小
 * 输出:I2CResult_OK:读取成功
 *         I2CResult_ERROR:读取失败
 * 备注:
 */
I2CResult_Typedef I2CReadData(I2C_Typedef* p_I2C,uint8_t address,uint8_t* p_data,uint8_t size)
{
    uint8_t i = 0;

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.write);                    //执行:写入I2C写指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address);                            //执行:写入地址高字节
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.read);                    //执行:写入I2C读指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C应答
    {
        return I2CResult_ERROR;
    }

    for(i = 0;i < size;i ++)
    {
        I2CReadByte(p_I2C,(p_data + i));                    //执行:读取1个字节

        if(i < (size - 1))                                    //判定:未读取完成
        {
            I2CSendAck(p_I2C);                                //执行:正应答
        }
        else
        {
            I2CSendNotAck(p_I2C);                            //执行:负应答
        }
    }

    I2CStop(p_I2C);                                            //执行:停止I2C

    return I2CResult_OK;
}

#elif DataAddressSizeof == 2

/*
 * 功能:I2C写数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:写入地址
 *         @p_data:写入数据缓存
 *         @size:写入数据大小
 * 输出:I2CResult_OK:写入成功
 *         I2CResult_ERROR:写入失败
 * 备注:
 */
I2CResult_Typedef I2CWriteData(I2C_Typedef* p_I2C,uint16_t address,uint8_t* p_data,uint16_t size)
{
    uint16_t i = 0;

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.write);                    //执行:写入I2C写指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address / 256);                        //执行:写入地址高字节
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address % 256);                        //执行:写入地址低字节
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    for(i = 0;i < size;i ++)
    {
        I2CWriteByte(p_I2C,*(p_data + i));                    //执行:写入1个字节
        if(I2CWaitAck(p_I2C) != I2CResult_OK)                //判定:I2C非应答
        {
            return I2CResult_ERROR;
        }
    }

    I2CStop(p_I2C);                                            //执行:停止I2C

    return I2CResult_OK;
}

/*
 * 功能:I2C读数据
 * 输入:@p_I2C:I2C结构体指针
 *         @address:读取地址
 *         @p_data:读取数据缓存
 *         @size:读取数据大小
 * 输出:I2CResult_OK:读取成功
 *         I2CResult_ERROR:读取失败
 * 备注:
 */
I2CResult_Typedef I2CReadData(I2C_Typedef* p_I2C,uint16_t address,uint8_t* p_data,uint16_t size)
{
    uint16_t i = 0;

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.write);                    //执行:写入I2C写指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address / 256);                        //执行:写入地址高字节
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CWriteByte(p_I2C,address % 256);                        //执行:写入地址低字节
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C非应答
    {
        return I2CResult_ERROR;
    }

    I2CStart(p_I2C);                                        //执行:开启I2C

    I2CWriteByte(p_I2C,p_I2C->ICCB.read);                    //执行:写入I2C读指令
    if(I2CWaitAck(p_I2C) != I2CResult_OK)                    //判定:I2C应答
    {
        return I2CResult_ERROR;
    }

    for(i = 0;i < size;i ++)
    {
        I2CReadByte(p_I2C,(p_data + i));                    //执行:读取1个字节

        if(i < (size - 1))                                    //判定:未读取完成
        {
            I2CSendAck(p_I2C);                                //执行:正应答
        }
        else
        {
            I2CSendNotAck(p_I2C);                            //执行:负应答
        }
    }

    I2CStop(p_I2C);                                            //执行:停止I2C

    return I2CResult_OK;
}

#endif

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是简单的I2C驱动程序,可以参考: ```c #include "stm32l1xx.h" /* I2C GPIO Configuration */ #define I2C_SCL_PIN GPIO_Pin_6 #define I2C_SDA_PIN GPIO_Pin_7 #define I2C_GPIO GPIOB #define I2C_RCC_AHB RCC_AHBPeriph_GPIOB /* I2C Configuration */ #define I2C_SPEED 100000 #define I2C_SLAVE_ADDRESS 0xA0 /* Private function prototypes */ static void I2C_GPIO_Configuration(void); static void I2C_Configuration(void); static void I2C_Read_Buffer(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead); int main(void) { uint8_t buffer[10]; /* GPIO Configuration */ I2C_GPIO_Configuration(); /* I2C Configuration */ I2C_Configuration(); /* Read data from I2C device */ I2C_Read_Buffer(buffer, 0x00, 10); while(1) { /* Do something */ } } static void I2C_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOB clock */ RCC_AHBPeriphClockCmd(I2C_RCC_AHB, ENABLE); /* Configure I2C SCL pin */ GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(I2C_GPIO, &GPIO_InitStructure); /* Configure I2C SDA pin */ GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN; GPIO_Init(I2C_GPIO, &GPIO_InitStructure); /* Connect I2C pins to AF */ GPIO_PinAFConfig(I2C_GPIO, GPIO_PinSource6, GPIO_AF_I2C1); GPIO_PinAFConfig(I2C_GPIO, GPIO_PinSource7, GPIO_AF_I2C1); } static void I2C_Configuration(void) { I2C_InitTypeDef I2C_InitStructure; /* Enable I2C clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); /* I2C configuration */ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS; I2C_InitStructure.I2C_Speed = I2C_SPEED; I2C_Init(I2C1, &I2C_InitStructure); /* Enable I2C */ I2C_Cmd(I2C1, ENABLE); } static void I2C_Read_Buffer(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead) { /* While the bus is busy */ while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); /* Send start condition */ I2C_GenerateSTART(I2C1, ENABLE); /* Wait for EV5 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send slave address */ I2C_Send7bitAddress(I2C1, I2C_SLAVE_ADDRESS, I2C_Direction_Transmitter); /* Wait for EV6 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); /* Send register address */ I2C_SendData(I2C1, ReadAddr); /* Wait for EV8 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); /* Send start condition again */ I2C_GenerateSTART(I2C1, ENABLE); /* Wait for EV5 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); /* Send slave address again */ I2C_Send7bitAddress(I2C1, I2C_SLAVE_ADDRESS, I2C_Direction_Receiver); /* Wait for EV6 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* Receive data */ while(NumByteToRead) { if(NumByteToRead == 1) { /* Disable ACK */ I2C_AcknowledgeConfig(I2C1, DISABLE); /* Send stop condition */ I2C_GenerateSTOP(I2C1, ENABLE); } /* Wait for EV7 */ while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* Read data */ *pBuffer = I2C_ReceiveData(I2C1); /* Next byte */ pBuffer++; NumByteToRead--; } /* Enable ACK */ I2C_AcknowledgeConfig(I2C1, ENABLE); } ``` 这是一个简单的I2C读取程序,使用了STM32L1xx标准库,可以读取从机地址为0xA0,寄存器地址为0x00,连续读取10个字节的数据并存储到buffer中。要使用此程序,需要将GPIOB的6、7号引脚配置为I2C模式,然后将I2C1的时钟使能,最后调用I2C_Read_Buffer函数即可。需要注意的是,此程序仅供参考,具体的I2C读写流程和错误处理需要根据具体情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洪恒远

感君意气无所惜,一为歌行歌主客

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值