用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;
}
}
} |
|