STM32-寄存器实现软件模拟IIC

I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。


实现函数

void Dri_I2C_Init(void);
void Dri_I2C_Start(void);
void Dri_I2C_Stop(void);
void Dri_I2C_SendByte(uint8_t byte);
uint8_t Dri_I2C_ReceiveByte(void);
uint8_t Dri_I2C_ReceiveAck(void);
void Dri_I2C_SendAck(uint8_t ack);

初始化

宏定义

#define SCL_LOW     (GPIOB->ODR &=~ GPIO_ODR_ODR10)
#define SCL_HIGH    (GPIOB->ODR |=  GPIO_ODR_ODR10)
#define SDA_LOW     (GPIOB->ODR &=~ GPIO_ODR_ODR11)
#define SDA_HIGH    (GPIOB->ODR |=  GPIO_ODR_ODR11)
#define READ_SDA    (GPIOB->IDR & GPIO_IDR_IDR11)
#define I2C_DELAY   Delay_us(10)

初始化

参考:

void Dri_I2C_Init(void){
    RCC->APB2ENR |= RCC_APB2ENR_IOPBEN ;
    GPIOB->CRH |= (GPIO_CRH_MODE10 | GPIO_CRH_MODE11 | GPIO_CRH_CNF10_0 | GPIO_CRH_CNF11_0 );
    GPIOB->CRH &=~(GPIO_CRH_CNF10_1 | GPIO_CRH_CNF11_1) ;
    SDA_HIGH ;
    SCL_HIGH ;
    I2C_DELAY;
}

在本STM32开发板中,IIC对应引脚为PB10与PB11,由于IIC协议需要,引脚需被配置为开漏输出模式

开始

参考:

void Dri_I2C_Start(void){
    SCL_HIGH;
    SDA_HIGH;
    I2C_DELAY;
    SDA_LOW;

    SCL_LOW;
    I2C_DELAY;
}

停止

参考:

void Dri_I2C_Stop(void){
    SDA_LOW;
    I2C_DELAY;
    SCL_HIGH;
    I2C_DELAY;
    SDA_HIGH;
    I2C_DELAY;
}

发送字节

参考:

void Dri_I2C_SendByte(uint8_t byte){
    for (uint8_t i = 0; i < 8; i++){
        ((byte & 0x80)==0) ? SDA_LOW : SDA_HIGH ;
        I2C_DELAY;
        SCL_HIGH;
        I2C_DELAY;

        SCL_LOW;
        I2C_DELAY;
        byte<<=1;
    }
}

接收字节

参考:

uint8_t Dri_I2C_ReceiveByte(void){
    uint8_t byte = 0 ;

    SDA_HIGH ;
    I2C_DELAY ;

    for (uint8_t i = 0; i < 8; i++){
        byte <<= 1 ;

        SCL_HIGH;
        I2C_DELAY;

        if(READ_SDA){
            byte |= 0x01;
        }

        SCL_LOW;
        I2C_DELAY ;
    }
    return byte ;
}

接收确认(ACK)信号

参考:

uint8_t Dri_I2C_ReceiveAck(){
    uint8_t ack = 0 ;
    SDA_HIGH ;
    I2C_DELAY;

    SCL_HIGH;
    I2C_DELAY;

    ack = READ_SDA ? 1 : 0 ;

    SCL_LOW ;
    I2C_DELAY ;

    return ack ;
}

发送确认(ACK)信号

void Dri_I2C_SendAck(uint8_t ack){
    ack ? SDA_HIGH : SDA_LOW ;
    SCL_HIGH ;
    I2C_DELAY ;

    SCL_LOW;
    I2C_DELAY ;
}
posted @ 2026-05-11 10:44  ZiYyun_Offical  阅读(26)  评论(0)    收藏  举报