Usé DMA para transferir datos I2C, pero siempre pierdo los últimos datos. La configuración del hardware se muestra a continuación:
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)I2C1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)I2C1_Buffer_Tx;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
Los datos a transferir son:
I2C1_Buffer_Tx[0] = 0xF0;
I2C1_Buffer_Tx[1] = 0x55;
Cuando se envía un marco de datos, se genera una interrupción de DMA:
void DMA1_Channel6_IRQHandler(void)
{
if (DMA_GetFlagStatus(DMA1_IT_TC6) != RESET)
{
DMA_Cmd(DMA1_Channel6, DISABLE);
DMA1_Channel6->CNDTR = 2;
DMA_ClearFlag(DMA1_IT_TC6);
switch (mode)
{
case 1:
I2C_GenerateSTART(I2C1, ENABLE);
mode = 2;
break;
case 2:
I2C_GenerateSTOP(I2C1, ENABLE);
mode = 3;
break;......
Cuando establezco un punto de interrupción en I2C_GenerateSTART(I2C1, ENABLE)
:
RecibolaseñalSDAdelosciloscopioenestepatrón:
Muestra que se han enviado dos datos a través de SDA: 0xF0 y 0x55, sin embargo, cuando establezco un punto de interrupción después de ese código:
yobtuvelossiguientesdatos:
muestra que solo se ha enviado un dato a través de SDA: 0xF0 y luego una condición de reinicio. así, perderé los últimos datos si dejo que todo el programa se ejecute como de costumbre.
Solo puedo explicar el fenómeno de esta manera: DMA ya ha enviado dos datos (0xF0 0x55), y luego genera una interrupción. Sin embargo, esos dos datos todavía están en el búfer de I2C, luego, en la interrupción de DMA, se genera una condición de inicio. Por alguna razón, rompe los datos finales.
¿Alguien puede dar alguna sugerencia para solucionar este problema o solo puedo configurar el tamaño de DMA n + 1 si quiero enviar n datos?