STM32L0停止模式无法正常工作

时间:2017-09-23 18:38:56

标签: embedded stm32 hal

目前,我正致力于通过使用STM32L053C6T6处理器的STOP模式来优化电流消耗。 我遇到了一个我无法解决的问题,如果你能提供帮助,我会很高兴。 首先,我想以非常简单的方式解释算法。 在while循环中,我通过UART-Serial转换器打印到Pc“STARTED”。接下来,我将RTC警报设置为10秒钟。最后我通过STOP MODE使MCU休眠。 10秒后,MCU正常唤醒。一切都很正常。 MCU唤醒后,我调用系统时钟配置功能。我通过UART在PC屏幕上打印“woken-up”。我可以永远这样工作但是我不喜欢电路消耗的电流。

为降低功耗,我在进入睡眠模式之前将所有引脚设置为模拟。这种方法在降低电流消耗方面效果很好。但是,在所有引脚都是模拟的并且MCU进入休眠状态并唤醒之后,MCU无法发送到字符串到PC。我认为UART模块无法正常工作...... 但I / O和systick计时器正在运行。我可以通过在一定延迟内切换LED来理解这一点(使用HAL_DELAY) 为什么我无法重新启动所有外围设备?

这是我的主要代码

int main(void){
HAL_Init();
SystemClock_Config();

MX_GPIO_Init();
MX_ADC_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_TIM22_Init();
MX_USART1_UART_Init()
MX_USART2_UART_Init();;
Init_RTC();
HAL_Delay(500);
while(1)
{
    printf("Started\n\r");                      
    for(uint16_t count1 = 0;count1<25;count1++){
        HAL_GPIO_TogglePin(STATE_LED0_GPIO_Port,STATE_LED0_Pin);
        HAL_Delay(25);
    }
    SetAlarm(10);                           
    EnterStopMode();                        
    printf("Woken-Up\n\r");
    HAL_Delay(1000);    
}
}

void EnterStopMode(void){
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();                           
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_All;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();

// STOP Moda girme komutu
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HAL_Delay(1000);
SystemClock_Config();

HAL_Delay(500);
MX_GPIO_Init();
MX_USART2_UART_Init();  

解决

好吧,我逐行检查了Hal功能。我在第一次外设初始化(uart,i2c,adc等)之后看到,Hal函数不允许通过检查特定外设的即时状态再次重新初始化。 例如,在HAL_UART_Init(&amp; huart2)函数中,为了初始化低级硬件:(GPIO,CLOCK),即时uart模块状态必须为UART_STATE_RESET。 在这里

if(huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;

/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
}

为了解决这个问题,我重置了外设init的特定状态。因为没有清除那些标志,uart init函数不会进入HAL_UART_MspInit(huart);

我知道这是一个庞大的解决方案,但它现在有效。

void EnterStopMode(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

 /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
 GPIO_InitStruct.Pin = GPIO_PIN_All;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /* Disable GPIOs clock */
 __HAL_RCC_GPIOA_CLK_DISABLE();
 __HAL_RCC_GPIOB_CLK_DISABLE();

 HAL_TIM_Base_Stop_IT(&htim22);
 HAL_ADC_Stop_IT(&hadc);

 /* Enter Stop Mode */

 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

 /* init the SYS Clocks */
 SystemClock_Config();

 /*Init IO's */
 MX_GPIO_Init();

 /* Clear Peripheral States for MspInit *7
 huart1.gState = HAL_UART_STATE_RESET;
 huart2.gState = HAL_UART_STATE_RESET;
 hi2c1.State   = HAL_I2C_STATE_RESET;
 hadc.State    = HAL_ADC_STATE_RESET;

 MX_USART2_UART_Init();  
 MX_USART1_UART_Init();    
 MX_I2C1_Init();
 MX_RTC_Init();
 MX_TIM22_Init();
 MX_ADC_Init();
 HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);   
 }

0 个答案:

没有答案