串口初始化(注意USART1时钟源要选择HSI):文章来源:https://www.toymoban.com/news/detail-549832.html
void usart_init(int baud_rate)
{
GPIO_Config_T gpio;
USART_Config_T usart;
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_9, GPIO_AF_PIN1);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_10, GPIO_AF_PIN1);
gpio.mode = GPIO_MODE_AF;
gpio.outtype = GPIO_OUT_TYPE_PP;
gpio.pin = GPIO_PIN_9 | GPIO_PIN_10;
gpio.pupd = GPIO_PUPD_PU;
gpio.speed = GPIO_SPEED_2MHz;
GPIO_Config(GPIOA, &gpio);
RCM_ConfigUSARTCLK(RCM_USART1CLK_HSI);
USART_ConfigStructInit(&usart);
usart.baudRate = (uint32_t)baud_rate;
USART_Config(USART1, &usart);
USART_ConfigOverrunDetection(USART1, USART_OVER_DETECTION_DISABLE);
USART_Enable(USART1);
}
使用power_init函数初始化RTC,然后调用power_enter_stop_mode(n)函数进入STOP模式,n秒后自动唤醒,或由USART1接收唤醒:文章来源地址https://www.toymoban.com/news/detail-549832.html
#include <apm32f0xx_eint.h>
#include <apm32f0xx_pmu.h>
#include <apm32f0xx_rcm.h>
#include <apm32f0xx_rtc.h>
#include <apm32f0xx_usart.h>
#include <stdio.h>
#include "bc3602.h"
#include "common.h"
#include "power.h"
static void power_rtc_init(void);
static void power_rtc_wakeup_init(void);
static void power_usart_wakeup_init(void);
void power_enter_stop_mode(uint16_t seconds)
{
// enable the wakeup timer
RTC_SetWakeUpValue(seconds - 1);
RTC_EnableWakeUp();
// enter STOP mode with two WFE instructions
printf("Enter STOP mode\n");
fflush(stdout);
bc3602_suspend();
PMU_EnterSTOPMode(PMU_REGULATOR_LowPower, PMU_STOPENTRY_WFE); // clear the event register
PMU_EnterSTOPMode(PMU_REGULATOR_LowPower, PMU_STOPENTRY_WFE); // enter stop mode
bc3602_resume();
printf("Wakeup\n");
// disable the wakeup timer
RTC_DisableWakeUp();
if (RTC_ReadIntFlag(RTC_INT_FLAG_WT) != RESET)
{
RTC_ClearIntFlag(RTC_INT_FLAG_WT);
printf("RTC wakeup timer event\n");
}
// clear USART wakeup flag
if (USART_ReadIntFlag(USART1, USART_INT_FLAG_WAKEUP) != RESET)
{
USART_ClearIntFlag(USART1, USART_INT_FLAG_WAKEUP);
printf("USART event\n");
}
}
void power_init(void)
{
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
PMU_EnableBackupAccess();
power_rtc_init();
power_rtc_wakeup_init();
power_usart_wakeup_init();
}
static void power_rtc_init(void)
{
uint32_t freq, interval, synch;
uint32_t last, now;
RTC_Config_T rtc;
if (RCM_ReadStatusFlag(RCM_FLAG_LSIRDY) == RESET)
{
printf("LSI is OFF\n");
RCM_EnableLSI();
while (RCM_ReadStatusFlag(RCM_FLAG_LSIRDY) == RESET);
printf("LSI is ready\n");
}
else
{
printf("LSI is ON\n");
}
if (!RCM->BDCTRL_B.RTCCLKEN)
{
RCM_ConfigRTCCLK(RCM_RTCCLK_LSI);
RCM_EnableRTCCLK();
rtc.format = RTC_HourFormat_12;
rtc.AsynchPrediv = 124;
rtc.SynchPrediv = 319;
RTC_Config(&rtc);
printf("RTC is configured\n");
// CAUTION: Once the wakeup timer is started, it does NOT stop until the MCU loses power supply
RTC_ConfigWakeUpClock(RTC_WAKEUP_CLOCK_CK_SPRE_16B);
RTC_SetWakeUpValue(0);
RTC_EnableWakeUp();
while (RTC_ReadStatusFlag(RTC_FLAG_WTF) == RESET);
last = sys_now();
RTC_ClearStatusFlag(RTC_FLAG_WTF);
while (RTC_ReadStatusFlag(RTC_FLAG_WTF) == RESET);
now = sys_now();
RTC_ClearStatusFlag(RTC_FLAG_WTF);
RTC_DisableWakeUp();
interval = now - last;
freq = 40000000 / interval;
synch = (10 * freq) / (rtc.AsynchPrediv + 1) - 10; // 10*(freq/(asynch+1)-1)
synch = (synch + 5) / 10; // round off the number
printf("RTC calibration: interval=%u, freq=%u, synch=%u\n", interval, freq, synch);
if (synch != rtc.SynchPrediv)
{
rtc.SynchPrediv = synch;
RTC_Config(&rtc);
printf("RTC is calibrated\n");
}
}
}
static void power_rtc_wakeup_init(void)
{
EINT_Config_T eint;
// configure EINT20 (RTC wakeup interrupt) as event mode
eint.line = EINT_LINE20;
eint.lineCmd = ENABLE;
eint.mode = EINT_MODE_EVENT;
eint.trigger = EINT_TRIGGER_RISING;
EINT_Config(&eint);
RTC_EnableInterrupt(RTC_INT_WT);
}
static void power_usart_wakeup_init(void)
{
EINT_Config_T eint;
// configure EINT25 (USART1 wakeup interrupt) as event mode
eint.line = EINT_LINE25;
eint.lineCmd = ENABLE;
eint.mode = EINT_MODE_EVENT;
eint.trigger = EINT_TRIGGER_RISING;
EINT_Config(&eint);
while (USART_ReadStatusFlag(USART1, USART_FLAG_TXC) == RESET);
USART_Disable(USART1);
USART_ConfigStopModeWakeUpSource(USART1, USART_WAKEUP_SOURCE_RXNE);
USART_Enable(USART1);
USART_EnableStopMode(USART1);
USART_EnableInterrupt(USART1, USART_INT_WAKEUP);
}
到了这里,关于APM32F072单片机进入STOP模式,并通过RTC Wakeup Timer和USART1串口接收事件唤醒的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!