Estoy tratando de configurar un proyecto simple que hace lo siguiente:
Ingrese al modo de suspensión y en el ciclo principal, espera la interrupción - __WFI().
Transmite datos desde un búfer[4] a la PC, a través de UART.
Idealmente, el segundo punto del programa se haría a través de DMA, para que la MCU no se despertara del modo de suspensión.
En ese sentido, estaba pensando en conectar una transferencia DMA en modo circular. Entonces, cada vez que un temporizador (por ejemplo, timer1) se desborda, activa automáticamente una transferencia UART. Cuando el DMA transfiera el cuarto byte del búfer, comenzará de nuevo desde el principio.
¿Puedo activar un DMA cuando la CPU está en modo de suspensión?
Entonces, generé un proyecto CubeMX estándar. Usé USART1 y TIMER1.
hdma_tim1_up.Instance = DMA2_Channel2;
hdma_tim1_up.Init.Request = DMA_REQUEST_TIM1_UP;
hdma_tim1_up.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim1_up.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim1_up.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim1_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tim1_up.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tim1_up.Init.Mode = DMA_CIRCULAR;
hdma_tim1_up.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_tim1_up) != HAL_OK)
{
Error_Handler();
}
En la función principal, después de la inicialización de los periféricos, simplemente llamo
HAL_DMA_Start(htim1.hdma[TIM_DMA_ID_UPDATE], (uint32_t)&testPWM, (uint32_t)&huart1.Instance->TDR, 4);
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
__WFI();
/* USER CODE BEGIN 3 */
}
testPWM es una matriz de 4 bytes {0, 1, 2, 3}
El bucle principal está vacío, no se utilizan devoluciones de llamada en el código. El controlador DMA envía 0 1 2 3 a la PC a través de UART, en cada evento de desbordamiento del temporizador. Cuando llega a 3, vuelve a 0.
DKNguyen
PaulEfecto
DKNguyen
PaulEfecto
DKNguyen
PaulEfecto