×
单片机 > 单片机程序设计 > 详情

STM32F051 I2C slave mode

发布时间:2020-06-01 发布时间:
|

用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: %08Xnr", 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: %dnr", Offset);

        ; // 指令解析

        ;

    }

    else

    {

        I2C_ClearITPendingBit(I2C1, 0x00003F38);

        printf("I2C1 Unknown event occurs!nr");

    }

}


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32单片机的复用端口初始化的步骤及方法