초보의 아웅다웅 설계하기/STM32

STM32F Sleep Mode에서 Uart로 Wakeup하기

로망와니 2018. 12. 6. 00:21

STM32F091 기준으로 하였습니다.

다른 시리즈와는 라이브러리가 달라 변경이 필요합니다.


main.c 파일에서 

int main(void)

{

  HAL_Init();


  /* Configure the system clock to 48 MHz */

  SystemClock_Config();

  /* Configure LED2 */

  BSP_LED_Init(LED2);


  /*##-1- Configure the UART peripheral ######################################*/

  /* Put the USART peripheral in the Asynchronous mode (UART Mode) */

  /* UART configured as follows:

      - Word Length = 8 Bits

      - Stop Bit = One Stop bit

      - Parity = None

      - BaudRate = 9600 baud

      - Hardware flow control disabled (RTS and CTS signals) */

  UartHandle.Instance        = USARTx;


  UartHandle.Init.BaudRate   = 9600;

  UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

  UartHandle.Init.StopBits   = UART_STOPBITS_1;

  UartHandle.Init.Parity     = UART_PARITY_NONE;

  UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;

  UartHandle.Init.Mode       = UART_MODE_TX_RX;

  UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; 

  if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

  {

    Error_Handler();

  }  

  if(HAL_UART_Init(&UartHandle) != HAL_OK)

  {

    Error_Handler();

  }

__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);


  

UART1_printf("Start\r\n");

  /* Configure User push-button in Interrupt mode */

  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

  

  /* Wait for User push-button press before starting the Communication.

     In the meantime, LED2 is blinking */

  while(UserButtonStatus == 0)

  {

      /* Toggle LED2*/

      BSP_LED_Toggle(LED2); 

      HAL_Delay(100);

  }

  

  BSP_LED_Off(LED2); 

  

UART1_printf("HAL_PWR_EnterSTANDBYMode");

//HAL_PWR_DisableSEVOnPend();

//HAL_PWR_DisableSleepOnExit();

//HAL_PWR_DeInit();

HAL_SuspendTick();

HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);//PWR_MAINREGULATOR_ON, PWR_LOWPOWERREGULATOR_ON

HAL_ResumeTick();

  

  /* Turn on LED2 if test passes then enter infinite loop */

  BSP_LED_On(LED2); 

  /* Infinite loop */

  while (1)

  {

UART1_printf("HAL_PWR_Wakeup");

HAL_Delay(1000);

  }

}


/**

  * @brief  System Clock Configuration

  *         The system Clock is configured as follow : 

  *            System Clock source            = PLL (HSI48)

  *            SYSCLK(Hz)                     = 48000000

  *            HCLK(Hz)                       = 48000000

  *            AHB Prescaler                  = 1

  *            APB1 Prescaler                 = 1

  *            HSI Frequency(Hz)              = 48000000

  *            PREDIV                         = 2

  *            PLLMUL                         = 2

  *            Flash Latency(WS)              = 1

  * @param  None

  * @retval None

  */

void SystemClock_Config(void)

{

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitTypeDef RCC_OscInitStruct;

  

  /* Select HSI48 Oscillator as PLL source */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;

  RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI48;

  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2;

  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;

  if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)

  {

    /* Initialization Error */

    while(1); 

  }


  /* Select PLL as system clock source and configure the HCLK and PCLK1 clocks dividers */

  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1);

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1)!= HAL_OK)

  {

    /* Initialization Error */

    while(1); 

  }

}


stm32f0xx_it.c 파일에서

extern void UART1_PutChar(char data);

void USARTx_IRQHandler(void)

{

uint8_t ch;

// HAL_UART_IRQHandler(&UartHandle); // HAL 드라이버가 제공하는 IRQ 핸들러

if ((__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&UartHandle, UART_IT_RXNE) != RESET)) { 

ch = 0x41;

UART1_PutChar(ch);

}

__HAL_UART_CLEAR_IT(&UartHandle, UART_CLEAR_PEF);

__HAL_UART_CLEAR_IT(&UartHandle, UART_FLAG_RXNE);

/* Disable the UART Parity Error Interrupt and RXNE interrupt*/

CLEAR_BIT(UartHandle.Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));

/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */

CLEAR_BIT(UartHandle.Instance->CR3, USART_CR3_EIE);

}


stm32f0xx_hal_msp.c 파일에서

void HAL_UART_MspInit(UART_HandleTypeDef *huart)

{  

  GPIO_InitTypeDef  GPIO_InitStruct;

  

  /*##-1- Enable peripherals and GPIO Clocks #################################*/

  /* Enable GPIO TX/RX clock */

  USARTx_TX_GPIO_CLK_ENABLE();

  USARTx_RX_GPIO_CLK_ENABLE();



  /* Enable USARTx clock */

  USARTx_CLK_ENABLE(); 

  

  /*##-2- Configure peripheral GPIO ##########################################*/  

  /* UART TX GPIO pin configuration  */

  GPIO_InitStruct.Pin       = USARTx_TX_PIN;

  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull      = GPIO_PULLUP;

  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;

  GPIO_InitStruct.Alternate = USARTx_TX_AF;


  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);


  /* UART RX GPIO pin configuration  */

  GPIO_InitStruct.Pin = USARTx_RX_PIN;

  GPIO_InitStruct.Alternate = USARTx_RX_AF;


  HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

    

  /*##-3- Configure the NVIC for UART ########################################*/

  /* NVIC for USART */

  HAL_NVIC_SetPriority(USARTx_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(USARTx_IRQn);

}


/**

  * @brief UART MSP De-Initialization 

  *        This function frees the hardware resources used in this example:

  *          - Disable the Peripheral's clock

  *          - Revert GPIO and NVIC configuration to their default state

  * @param huart: UART handle pointer

  * @retval None

  */

void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)

{

  /*##-1- Reset peripherals ##################################################*/

  USARTx_FORCE_RESET();

  USARTx_RELEASE_RESET();


  /*##-2- Disable peripherals and GPIO Clocks #################################*/

  /* Configure UART Tx as alternate function  */

  HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);

  /* Configure UART Rx as alternate function  */

  HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);

  

  /*##-3- Disable the NVIC for UART ##########################################*/

  HAL_NVIC_DisableIRQ(USARTx_IRQn);

}