Ich versuche, ein einfaches Projekt einzurichten, das Folgendes tut:
Wechseln Sie in den Schlafmodus und warten Sie in der Hauptschleife auf den Interrupt - __WFI().
Überträgt Daten von einem Puffer[4] über UART an den PC.
Der zweite Punkt des Programms würde idealerweise über DMA erfolgen, damit die MCU nicht aus dem Ruhezustand aufwacht.
Zu diesem Zweck dachte ich daran, eine DMA-Übertragung im Zirkularmodus anzuschließen. Jedes Mal, wenn ein Timer (z. B. Timer1) überläuft, löst er automatisch eine UART-Übertragung aus. Wenn der DMA das 4. Byte des Puffers überträgt, würde er von vorne beginnen.
Kann ich einen DMA auslösen, wenn sich die CPU im Ruhemodus befindet?
Also habe ich ein Standard-CubeMX-Projekt generiert. Ich habe USART1 & TIMER1 verwendet.
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();
}
In der Hauptfunktion rufe ich nach der Initialisierung der Peripherie einfach auf
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 ist ein 4-Byte-Array {0, 1, 2, 3}
Die Hauptschleife ist leer, im Code werden keine Rückrufe verwendet. Der DMA-Controller sendet bei jedem Timer-Überlaufereignis 0 1 2 3 über UART an den PC. Wenn es 3 erreicht, springt es zurück auf 0.
DKNguyen
PauLEffect
DKNguyen
PauLEffect
DKNguyen
PauLEffect