APM32F072单片机进入STOP模式,并通过RTC Wakeup Timer和USART1串口接收事件唤醒

这篇具有很好参考价值的文章主要介绍了APM32F072单片机进入STOP模式,并通过RTC Wakeup Timer和USART1串口接收事件唤醒。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

串口初始化(注意USART1时钟源要选择HSI):

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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【雅特力】单片机AT32F421系列入门资料

    AT32 全系列MCU选型手册.PDF AT32F421F8P7 AT32F421C8T7 (雅特力厂商送样的两个芯片版本) 【 数据手册】AT32F421系列引脚定义、电气特性与封装特性.PDF 【技术手册】AT32F421系列各外设(Peripheral)完整说明与各寄存器(Register)定义说明.PDF 【教程】AT32F421入门使用指南.PDF AT-START-F421 及 AT-Link

    2024年02月13日
    浏览(44)
  • 【单片机】STM32单片机频率计程序,外部脉冲计数程序,基于脉冲计数的频率计程序,STM32F103

    两种方法用于在单片机中实现频率计的功能。 第一种方法是通过定时器来衡量信号的周期,然后将周期转换为频率。在这种方法中,你可以使用单片机的定时器模块来测量输入信号的周期,定时器会产生一个计数值,你可以根据这个计数值来推算出输入信号的周期,并通过简

    2024年02月11日
    浏览(52)
  • 【单片机】STM32单片机,RTC实时时钟,STM32F103C8T6,程序,万年历,数字时钟

    我以STM32F103C8T6为例,但STM32F103的RTC是通用的,STM32F103C8T6有一个原理图: https://qq742971636.blog.csdn.net/article/details/131288390 用纽扣电池给VBAT供电(要共地),即可实现掉电后依旧走时的能力。 主要特性(来源于STM32中文参考手册V10.pdf): 记得加标准库文件: 串口接收:

    2024年02月11日
    浏览(56)
  • PY32F003F18P单片机概述

    PY32F003F18P单片机是普冉的一款ARM微控制器,内核是Cortex-M0。这个单片机的特色,就是价格便宜,FLASH和SRAM远远超过8位单片机,市场竞争力很强大。 一、硬件资源: 1)、FLASH为64K字节; 2)、SRAM为8K字节; 3)、定时器: 高级定时器有1个,为TIM1;通用定时器有4个,分别为TIM3,

    2024年02月10日
    浏览(37)
  • 关于两个STM32F103系列单片机的蓝牙通信

       毕设做的是掌控小车,因此采用蓝牙通信作为小车和手部通信,前段时间做出实物,对其遇到的问题以及解决的方法做一些总结。一个主控芯片采用STM32F103ZET6,另一个主控芯片采用STM32F103C8T6,原因是本来准备了两个主控C8T6,不小心烧了一个。 1.两个蓝牙的配对  需要准

    2024年02月13日
    浏览(63)
  • 32位M0核单片机XL32F003芯片特征和功能介绍

    XL32F003 系列微控制器采用高性能的 32 位 ARM®Cortex®- M0+ 内核,宽电压工作范围的MCU。嵌入高达64 Kbytes flash和8 Kbytes SRAM存储器,最高工作频率32 MHz。包含多种不同封装类型多款产品。芯片集成多路I2C、SPI、 USART等通讯外设,1路12 bit ADC,5个16bit定时器,以及2路比较器。 XL32F00

    2024年02月14日
    浏览(43)
  • STM32F103ZE单片机呼吸灯源代码

    本实验采用的系统频率SYSTIM为8MHZ,如果频率改变需要修改一个数值

    2024年02月09日
    浏览(53)
  • stm32f1xx单片机拦截中断源代码

    这个是实现后的效果,可以看到已经没有中断的效果了 这个是拦截前的效果可以看到电平是在变化的 实现原理非常简单:一句话搞定: 以下是完整的代码:是用来补充说明和筹字数的 这就表明了,单片机里面是可以植入病毒的,或者不算病毒,里面的代码也是具有修改破坏

    2024年02月10日
    浏览(48)
  • JDY-31蓝牙模块远程控制STM32F103单片机

       手机app通过蓝牙模块发送指令实时控制单片机的外设功能,比如发送衣柜开关门指令(舵机旋转),衣架上升降落(步进电机正转反转),远程开启去污除湿功能(继电器控制打开关闭小风扇+加热片)。 本次例子:手机APP连接蓝牙模块远程控制SG90舵机正转(0-180°)和反

    2024年02月01日
    浏览(73)
  • 32 位 ARM® Cortex®-M0+ 单片机,PY32F002B 系列微控制器

    PY32F002B 系列微控制器采用高性能的 32 位 ARM® Cortex®-M0+内核,宽电压工作范围的 MCU。嵌入24Kbytes Flash 和 3Kbytes SRAM 存储器,最高工作频率 24MHz。包含多种不同封装类型多款产品。 芯片集成I2C、SPI、USART 等通讯外设,1 路 12bit ADC,2 个 16bit 定时器,以及 2 路比较器。PY32F002B 系

    2024年02月05日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包