打印

STM32F405待机冷启动与唤醒后再次待机状态为何不同?

[复制链接]
1622|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tangdga|  楼主 | 2017-8-28 10:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用stm32f405做了一个RTC进入待机2秒唤醒的程序,第一次由冷启动进入待机时一切正常,待机时指示灯能正常锁定,串口也很稳定,不发乱码,2秒后RTC唤醒,做完工作后再次进入待机,问题来了,串口不停的发乱码,GPIOC上的指示灯也不能正常闪烁了!请大侠帮忙找一找原因!

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include "led.h"
#include "rtc.h"

#define debug(...)


UART_HandleTypeDef huart1;

#define RTC_SET_INIT_TIME   (0x32F2)
uint8_t RTC_ReadFlag=0;    //一秒读一次时间  =1读取数据, =0不读



extern RTC_HandleTypeDef RtcHandle;
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;

void RTC_SetDate(uint8_t year, uint8_t month, uint8_t date, uint8_t week);
void RTC_SetTime(uint8_t hour, uint8_t minute, uint8_t second);


int fputc(int ch, FILE *f)
{
        size_t count =1;
        char chTemp = (char)ch;
        HAL_UART_Transmit(&huart1,(uint8_t*) &chTemp, count, HAL_MAX_DELAY);
               
        return count;
}

void MX_RTC_Init(void)
{
  RtcHandle.Instance = RTC;
  RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
  RtcHandle.Init.AsynchPrediv = 127;
  RtcHandle.Init.SynchPrediv = 255;
  RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
  RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  HAL_RTC_Init(&RtcHandle);


  if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != RTC_SET_INIT_TIME)
  {
    RTC_SetDate(15, 12, 28, 1);   // 设置日期 2015-12-28 星期1
    RTC_SetTime(22, 25, 45);      //  22:25:45

    /*##-3- Writes a data in a RTC Backup data Register0 #######################*/
    HAL_RTCEx_BKUPWrite(&RtcHandle,RTC_BKP_DR0, RTC_SET_INIT_TIME);  
  }

  else
  {
    /* Check if the Power On Reset flag is set */  
    if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
    {
      #if  RTC_DEBUG_SWITCH > 0u
          /* Initialization Error */
          printf("\r\nRTC Initialization Error 1 ...");
      #endif
    }
    /* Check if Pin Reset flag is set */
    if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
    {
      #if  RTC_DEBUG_SWITCH > 0u
          /* Initialization Error */
          printf("\r\nRTC Initialization Error 2 ...");
      #endif
    }

    /* Clear Reset Flag */
    __HAL_RCC_CLEAR_RESET_FLAGS();  
  }

  /**Enable the WakeUp
  */  
HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
        __HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);
        RTC->CR |= 0x00600000U;
        __HAL_RTC_WRITEPROTECTION_ENABLE(&RtcHandle);
        EXTI->PR |=0X00400000U;
        printf("after clear RTC_ISR    %08x\r\n",(uint32_t)RTC->ISR);
       
}

//设置时间后,保存时调用
void RTC_SetDate(uint8_t year, uint8_t month, uint8_t date, uint8_t week)
{
  //##-1- Configure the Date #################################################

  sDate.Year = year;
  sDate.Month = month;
  sDate.Date = date;
  sDate.WeekDay = week;

  if(HAL_RTC_SetDate(&RtcHandle,&sDate,RTC_FORMAT_BIN) != HAL_OK)
  {
    #if  RTC_DEBUG_SWITCH > 0u
    // Initialization Error
    printf("\r\nRTC Initialization Error 3 ...");
    #endif
  }
}

void disp_regist()
{
         printf("PWR_CR=    %08x",(uint32_t)PWR->CR);  //RTSR
         printf("EXTI_RTSR=  %08x\r\n",(uint32_t)EXTI->RTSR);
         printf("RCC_CSR=   %08x  ",(uint32_t)RCC->CSR);
         printf("RCC_BDCR=  %08x\r\n",(uint32_t)RCC->BDCR);       
         printf("RCC_CR=    %08x  ",(uint32_t)RCC->CR);       
         printf("RCC_CFGR=  %08x\r\n",(uint32_t)RCC->CFGR);       
         printf("RCC_PLLCFGR=   %08x  ",(uint32_t)RCC->PLLCFGR);       

         printf("RTC_TR     %08x\r\n",(uint32_t)RTC->TR);
         printf("RTC_DR     %08x  ",(uint32_t)RTC->DR);
         printf("RTC_CR     %08x\r\n",(uint32_t)RTC->CR);
         printf("RTC_ISR    %08x  ",(uint32_t)RTC->ISR);
         printf("RTC_PRER   %08x\r\n",(uint32_t)RTC->PRER);
         printf("RTC_WUTR   %08x  ",(uint32_t)RTC->WUTR);
         printf("RTC_TAFCR  %08x\r\n",(uint32_t)RTC->TAFCR);
         printf("EXTI_EMR   %08x  ",(uint32_t)EXTI->EMR );
         printf("EXTI_IMR   %08x\r\n",(uint32_t)EXTI->IMR );
         printf("EXTI_SWIER %08x  ",(uint32_t)EXTI->SWIER );
         printf("EXTI_PR    %08x\r\n",(uint32_t)EXTI->PR );
}

void RTC_SetTime(uint8_t hour, uint8_t minute, uint8_t second)
{
  /*##-2- Configure the Time #################################################*/
  sTime.Hours = hour;
  sTime.Minutes = minute;
  sTime.Seconds = second;
  sTime.TimeFormat = RTC_HOURFORMAT12_AM;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;

  if(HAL_RTC_SetTime(&RtcHandle,&sTime,RTC_FORMAT_BIN) != HAL_OK)
  {
//    #if  RTC_DEBUG_SWITCH > 0u
        /* Initialization Error */
        printf("\r\nRTC Initialization Error 4 ...");
//    #endif
  }
}



// rtc 时间 显示,使用lcd
void RTC_Display(void)
{

                        if(GPIOC->ODR & ledMode)
                                ledOn(ledMode);
                        else
                                ledOff(ledMode);

         
}



void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{
  RTC_ReadFlag = 1;   // 时钟读取标志位 置 1
        HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
}



/**
* @brief This function handles RTC wake-up interrupt through EXTI line 22.
*/
void RTC_WKUP_IRQHandler(void)
{
  HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle);
}


/** System Clock Configuration
*/


int errornum;

void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

  __PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
        RCC_OscInitStruct.LSIState = RCC_LSI_ON;
        RCC_OscInitStruct.HSIState = RCC_HSI_ON;
       
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;   // 8M
        RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLM = 8;           //  VCO输入=1M  默认 16  默认主频= 16M*(192/16)=192M
  RCC_OscInitStruct.PLL.PLLN = 336;         //VCO=336M      默认192
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;  //主频=168M  默认0
  RCC_OscInitStruct.PLL.PLLQ = 7;           //usb=48M  默认 4
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_HCLK  
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;      
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;       //42M
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;      //84M
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);  //设置FLASH等待周期=FLASH_LATENCY_5,设置时钟源



  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  // SysTick_IRQn interrupt configuration
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}




void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOH_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();

  /*Configure GPIO pin : PB0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PC10 PC11 PC12 */
  GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PA4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

}


/* USART2 init function */
void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
        huart1.gState = HAL_UART_STATE_RESET;
  errornum=HAL_UART_Init(&huart1);

}

void set_pwr_sleep()
{

        __HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);  //将RTC的写保护禁用        SET_BIT(RTC->ISR,RTC_ISR_INIT);
       
        CLEAR_BIT(RTC->ISR,RTC_ISR_WUTF);  //1<<10);  //唤醒定时器标志               
        CLEAR_BIT(RTC->ISR,RTC_ISR_INIT);
       
       
        __HAL_RTC_WRITEPROTECTION_ENABLE(&RtcHandle);  //再次保护RTC
       
        HAL_PWR_EnterSTOPMode(PWR_CR_LPDS|PWR_CR_PDDS,PWR_STOPENTRY_WFI);  //低功耗,进入待机模式
}

void rest_rtc()
{
        RtcHandle.Instance = RTC;
        //HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
        PWR->CR |= 0X020CU;      //停机模式flash掉电
        __HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);  //将RTC的写保护禁用
       
        SET_BIT(RTC->ISR,RTC_ISR_INIT);       
        SET_BIT(RCC->CIR,0x10000);
        CLEAR_BIT(RTC->ISR,RTC_ISR_INIT);
       
        __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RtcHandle, RTC_FLAG_WUTF);  //清除中断
        __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();

        EXTI->RTSR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT;
        __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();

}

int main(void)
{
        uint32_t ledTick;
        uint32_t maxtick;
        bool hotrun;  //指示是否是热启动
        errornum=0;
if((PWR->CSR & 2)        ==2)  //是热启动
{
        hotrun=true;
        RtcHandle.Instance = RTC;
}
else
                hotrun=false;
HAL_Init();
       
SystemClock_Config();
       
MX_GPIO_Init();
       
        MX_USART1_UART_Init();
        LED_init();
        ledOff(ledRanging);
        ledOff(ledSync);
        ledOff(ledMode);


if(hotrun)
        printf("HOT RUN ");
else
        printf("COLD RUN ");
        printf("init RTC..errornum=%d\r\n",errornum);
if(hotrun==false)       
        MX_RTC_Init();
else
        rest_rtc();       

        ledTick=0;

  maxtick=1;

printf("init RTC..errornum=%d\r\n",errornum);

disp_regist();

        //maxtick=0xffffe;       
  while(1)
{


                if(ledTick>=maxtick)        {
                        ledTick=0;
                        if(GPIOC->ODR & ledSync)
                                ledOn(ledSync);
                        else
                                ledOff(ledSync);
                        if(hotrun)
                                set_pwr_sleep();       
                }
                else
                        ledTick++;

        if(RTC_ReadFlag)
    {
      RTC_Display();
      RTC_ReadFlag = 0;
                        set_pwr_sleep();
                        maxtick=1;
    }

}
}

相关帖子

沙发
tangdga|  楼主 | 2017-8-28 11:31 | 只看该作者
找到原因了:
UART发乱码的解决办法是:TX接一个10K上拉电阻就OK了!指示灯第一次没有进入待机状态,直接因中断才进入的待机状态,所以IO指示灯能亮起,待机后IO口全处于悬空无电状态。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝