Передать / получить строку по i2 c на STM32F103 - PullRequest
0 голосов
/ 10 апреля 2020

Я пишу код для передачи и получения строки в формате массива. Я подключаю I2C1 к I2C2, оба на STM32F103 (синяя таблетка). I2C2 является ведущим, а I2C1 - ведомым, используя для получения прерывания. Однако, когда я проверяю, отправляя полученный массив в USART, он не работает. USART ничего не показывает. Смотри нравится, как-то застревает. Может кто-нибудь мне помочь? Это моя инициализация I2 C.

volatile uint8_t Tx_Index, Rx_Index;
uint8_t I2C_Buffer_Rx[64], I2C_Buffer_Tx[64] = "Hello World from I2C!\n";

void i2c_init(){

    /* I2C initialize */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

    I2C_InitTypeDef i2c_Init;
    // i2c_Init.I2C_DutyCycle = I2C_DutyCycle_2;
    i2c_Init.I2C_ClockSpeed = 100000;   // Standard mode
    i2c_Init.I2C_Mode = I2C_Mode_I2C;   // configure CR1 (SMBTYPE, SMBUS or normal mode)
    i2c_Init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    i2c_Init.I2C_OwnAddress1 = 0x02;
    i2c_Init.I2C_Ack = I2C_Ack_Disable;       
    I2C_Init(I2C2, &i2c_Init);

    I2C_Cmd(I2C2, ENABLE);

    /* Initialize GPIO as open drain alternate function */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitTypeDef gpio_Init;    
    gpio_Init.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 |
                         GPIO_Pin_6 | GPIO_Pin_7; // SCL & SDA
    gpio_Init.GPIO_Mode = GPIO_Mode_AF_OD;   
    gpio_Init.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOB, &gpio_Init);


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    i2c_Init.I2C_ClockSpeed = 100000;
    i2c_Init.I2C_Mode = I2C_Mode_I2C;
    i2c_Init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    i2c_Init.I2C_OwnAddress1 = 0x08;
    i2c_Init.I2C_Ack = I2C_Ack_Enable;
    I2C_Init(I2C1, &i2c_Init);

    I2C_Cmd(I2C1, ENABLE);
    I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT, ENABLE);

    Tx_Index = 0;
    Rx_Index = 0;
}

Функция передачи для мастера:

void i2c_start(){

    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY));

    // Generate start condition
    I2C_GenerateSTART(I2C2, ENABLE);

    while(!(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)));
}

void i2c_stop(){

    I2C_GenerateSTOP(I2C2, ENABLE);

    while (I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF));
}

void i2c_SendAddress(uint8_t address, bool read){

    address = address << 1;
    if (read != false) {
        I2C_AcknowledgeConfig(I2C2, ENABLE);
    } else {
        I2C_AcknowledgeConfig(I2C2, DISABLE);
    }

    I2C_Transmit(address);
    while (!READ_BIT(I2C2->SR1, I2C_SR1_ADDR)); // Make sure address matched or 
                                                // address transmission finished
    while (READ_BIT(I2C2->SR2, I2C_SR2_TRA) != read);// Make sure in right mode
                                                     // transmiter/receiver
}

void I2C_Transmit(uint8_t byte){

    MODIFY_REG(I2C2->DR, I2C_DR_DR, byte);
}

void I2C_Write(uint8_t address, uint8_t *data){

    i2c_start();
    i2c_SendAddress(address, false);    

    for (uint8_t i = 0; i < 64; i++){

        while (!(READ_BIT(I2C2->SR1, I2C_SR1_TXE) ||// Check if buffer is empty
                 READ_BIT(I2C2->SR1, I2C_SR1_BTF)));// Check if data transmission haven't done

        I2C_Transmit(*data++); // I2C_Transmit(data);
    }

    while (!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

    i2c_stop();
}

А вот прерывание подчиненного устройства:

void I2C1_EV_IRQHandler(void){

    switch (I2C_GetLastEvent(I2C1)){
        // Slave Receiver
        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:

            Rx_Index = 0;
            break;
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:

            // reading received data
            I2C_Buffer_Rx[Rx_Index++] = (uint8_t) READ_REG(I2C1->DR);
            break;
        case I2C_EVENT_SLAVE_STOP_DETECTED:

            (void)(I2C_GetITStatus(I2C1, I2C_IT_STOPF));            

            I2C_Cmd(I2C1, ENABLE);         

            Rx_Index = 0;
            break;
        default:
            break;
    }
}
...