STM32F0 (maestro) escribiendo múltiples bytes por I2C a MCP4728 (esclavo) usando StdPeriphLibrary

0

void I2C_Config (void) {     I2C_InitTypeDef I2C_InitStructure;

I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Timing = (PRESC << 28) | (SCLDEL << 20)
        | (SDADEL << 16) | (SCLH << 8) | SCLL;      // 100kHz
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;      // I2C mode
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // enable acknowledge when reading (can be changed later on)
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
I2C_Init(I2C_PERIPH, &I2C_InitStructure);       // init I2C peripheral
I2C_Cmd(I2C_PERIPH, ENABLE);

}

void I2C_HW_tx (uint8_t i2cAddr, uint8_t * dataTx, uint8_t longitud,         uint8_t stopOrNotWhenSent) {

if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, 1, I2C_Reload_Mode,
    I2C_Generate_Start_Write);
    PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length - 1; i++) {
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TCR) == RESET)
            ;
        PRINTF("\nI2C_tx - 3\n");
    }
    I2C_AutoEndCmd(I2C_PERIPH, ENABLE);
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    I2C_SendData(I2C_PERIPH, *(dataTx + length - 1));
    I2C_ReloadCmd(I2C_PERIPH, DISABLE);
} else {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_SoftEnd_Mode,
    I2C_Generate_Start_Write);
    PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TC) == RESET)
            ;
        PRINTF("\nI2C_tx - 3\n");
    }
}
if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
        ;
    I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);
}
PRINTF("\nI2C_tx - 4\n");

}

void I2C_HW_rx (uint8_t i2cAddr, uint8_t * dataRx, uint8_t length) {

PRINTF("\nI2C_rx - 1\n");
I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_AutoEnd_Mode,
I2C_Generate_Start_Read);

for (uint8_t i = 0; i < length; i++) {
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_RXNE) == RESET)
        ;
    PRINTF("\nI2C_rx - 2\n");
    *(dataRx + i) = I2C_ReceiveData(I2C_PERIPH);
}
while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
    ;
PRINTF("\nI2C_rx - 3\n");
I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);

}

He leído bytes de MCP4728 utilizando I2C_HW_rx con éxito. El problema es con I2C_HW_tx: se detiene cuando se intenta enviar:

uint8_t dataTx[8];
for (uint8_t i = 0; i < 4; i++) {
    *(dataTx + i * 2) =
            FASTWRITE
                    | (((channelData->powerMode << 4)
                            | (channelData->dacValue >> 8)) & 0x3F);
    *(dataTx + i * 2 + 1) = channelData->dacValue & 0xFF;
    if (i < 3) {
        channelData++;
    }
}
I2C_HW_tx(DEVICE_CODE | (mcp4728WholeData[mcp4728Id].currI2CAddr << 1),
        dataTx, 8, STOP_WHEN_SENT);

}

Entonces, mi pregunta para usted: ¿cómo enviar varios bytes mediante STM32F0 (maestro) al bus I2C, usando StdPeriphLibrary? Estaba buscando en Google, pero los pocos ejemplos con StdPeriphLibrary para STM32F0 son con el envío de I2Caddr, el registro y el valor (tres bytes), pero debo enviar, por ejemplo, I2Caddr y diez bytes.

    
pregunta Sibą

1 respuesta

0

OK, me las arreglé para solucionar este problema: la comprobación del indicador TCR en el bucle fue un error. El código de trabajo es el siguiente:

void I2C_HW_tx (uint8_t i2cAddr, uint8_t * dataTx, uint8_t longitud,         uint8_t stopOrNotWhenSent) {

if (stopOrNotWhenSent == STOP_WHEN_SENT) {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length,
    I2C_AutoEnd_Mode,
    I2C_Generate_Start_Write);
    //PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    //PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXE) == RESET)
            ;
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        //PRINTF("\nI2C_tx - 3\n");
    }
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_STOPF) == RESET)
        ;
    I2C_ClearFlag(I2C_PERIPH, I2C_FLAG_STOPF);
} else {
    I2C_TransferHandling(I2C_PERIPH, i2cAddr, length, I2C_SoftEnd_Mode,
    I2C_Generate_Start_Write);
    //PRINTF("\nI2C_tx - 1\n");
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXIS) == RESET)
        ;
    //PRINTF("\nI2C_tx - 2\n");
    for (uint8_t i = 0; i < length; i++) {
        while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TXE) == RESET)
            ;
        I2C_SendData(I2C_PERIPH, *(dataTx + i));
        //PRINTF("\nI2C_tx - 3\n");
    }
    while (I2C_GetFlagStatus(I2C_PERIPH, I2C_FLAG_TC) == RESET)
        ;
    //PRINTF("\nI2C_tx - 4\n");
}
//PRINTF("\nI2C_tx - 5\n");

}

Lo único que no sé cómo hacer es WriteI2CAddress to MCP4728 slave device ( enlace - página 42). La línea LDAC debería bajar desde el estado alto durante el octavo bit de comando. ¿Sabe cómo hacerlo utilizando el hardware I2C en STM32?

    
respondido por el Sibą

Lea otras preguntas en las etiquetas