STM32F051 I2C slave mode

用STM32F051的I2C从模式做某模块的控制接口,通过主机读状态和写控制命令。

Eclips 环境,gcc编译器,相关源码如下:

#ifdef DEBUG_I2C_EN
#define DEBUG_I2C(...)      printf(__VA_ARGS__)
#else
#define DEBUG_I2C(...)
#endif

void I2C_Config(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;
    I2C_InitTypeDef     I2C_InitStructure;
    NVIC_InitTypeDef    NVIC_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    // I2C port
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_1);

    // I2C config
    I2C_InitStructure.I2C_Timing               = 0x00731012;
    I2C_InitStructure.I2C_AnalogFilter         = I2C_AnalogFilter_Enable;
    I2C_InitStructure.I2C_DigitalFilter        = 0x00;
    I2C_InitStructure.I2C_Mode                 = I2C_Mode_I2C;
    I2C_InitStructure.I2C_OwnAddress1          = DEV_SLAVE_ADDR;
    I2C_InitStructure.I2C_Ack                  = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress  = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);

    I2C_StretchClockCmd(I2C1, DISABLE);

    NVIC_InitStructure.NVIC_IRQChannel         = I2C1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 2; // Low Medium Hight VeryHigh: 0 - 3
    NVIC_InitStructure.NVIC_IRQChannelCmd      = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    uint32_t temp = I2C_IT_STOPI |
                    I2C_IT_ADDRI |
                    I2C_IT_RXI   |
                    I2C_IT_TXI;
    I2C_ITConfig(I2C1, temp, ENABLE);
}


static uint8_t  Instruct = 0;
static uint8_t  Offset   = 0;
static uint8_t  MaxBytes = 0;

uint8_t *TxBuff;
uint8_t RxBuff[40];

void I2C1_IRQHandler(void)
{
    uint8_t  temp;
    uint32_t status = I2C1->ISR;

    DEBUG_I2C("I2C1->ISR: %08X\n\r", status);
    if(status & I2C_ISR_ADDR)
    {   // I2C1 Address match event occurs
        I2C_ClearITPendingBit(I2C1, I2C_ISR_ADDR);

        if(status & I2C_ISR_DIR)
        {   // I2C1: slave enters transmitter mode.
            ;
        }
        else
        {   // I2C1: slave enters receiver mode.
            Instruct = 1;
        }

        Offset = 0;
    }
    else if(status & I2C_ISR_RXNE)
    {
        I2C1->ISR |= I2C_ISR_TXE;
        temp = I2C_ReceiveData(I2C1);
        if(Instruct)
        {   // Host Instruct
            switch(temp)
            {
                case 0x00:  // Get DevInfo
                    TxBuff = (uint8_t *)&DevInfo;     // 24 bytes
                    MaxBytes = sizeof(DevInfo);
                    break;
                case 0x18:  // Get DevStatus
                    TxBuff = (uint8_t *)&DevStatus;   // 8 bytes
                    MaxBytes = sizeof(DevStatus);
                    break;
                default: break;
            }

            Instruct = 0;
        }

        RxBuff[Offset++] = temp;
    }
    else if(status & I2C_ISR_TXIS)
    {
        I2C1->ISR |= I2C_ISR_TXE;
        if(Offset < MaxBytes)
        {
            I2C_SendData(I2C1, TxBuff[Offset++]);
        }
        else
        {
            I2C_SendData(I2C1, 0xFF);
        }
    }
    else if(status & I2C_ISR_STOPF)
    {
        I2C_ClearITPendingBit(I2C1, I2C_ISR_STOPF);
        DEBUG_I2C("I2C1 Host stop, Bytes: %d\n\r", Offset);
        ; // 指令解析
        ;
    }
    else
    {
        I2C_ClearITPendingBit(I2C1, 0x00003F38);
        printf("I2C1 Unknown event occurs!\n\r");
    }
}



你可能感兴趣的:(STM32F051 I2C slave mode)