找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1038|回复: 3
打印 上一主题 下一主题
收起左侧

PY32F0单片机LPTIM中断唤醒stop模式源程序

[复制链接]
跳转到指定楼层
楼主
==================================================
                                                                                  样例使用说明
==================================================
功能描述:
此样例演示了外部触发LPTIM,由LPTIM中断唤醒stop模式,每次唤醒后再次进入stop模式,每6s唤醒一次,并在中断中翻转LED灯。
stop模式下,测得功耗8.96uA
==================================================
测试环境:
测试用板:PY32F030_STK
MDK版本: 5.28
==================================================
使用步骤:
1. 编译下载程序到MCU,并运行;
2. 按下按键进入stop模式;
3. 6s后唤醒stop模式并循环进入stop模式再唤醒;
4. 中断中LED保持频率闪烁;
==================================================
注意事项:
每次唤醒后再次进入Stop模式前,必须增加延时,用于LSI和APB时钟同步
==================================================

#include "main.h"
#include "tim.h"
#include "gpio.h"
#include "exti.h"
#include "lptim.h"

void APP_SystemClockConfig(void);
int main(void)
{
      /* 初始化所有外设,Flash接口,SysTick */
      HAL_Init();            
       /* 系统时钟配置 */
       APP_SystemClockConfig();
       /* 初始化GPIO */
       APP_GpioConfig();
        /* 初始化Exti */
       APP_ConfigureExti();
        /* 初始化Time */
       APP_Tim1Config();               
        /* 时钟设置 */
        APP_RCCOscConfig();        
        /* LPTIM初始化 */
        APP_LPTIMInit();
        /* 使能PWR */
        __HAL_RCC_PWR_CLK_ENABLE();
        /* 关闭Systick中断 */
        HAL_SuspendTick();        

        while (1)
       {

                                if(KEY_down_up==Down_KEY)//检测到一次下降沿到来
                                {
                                                KEY_down_up=Up_KEY;

                                                /* 关闭Systick中断 */
                                                HAL_SuspendTick();        
                                                /* 失能 LPTIM */
                                                __HAL_LPTIM_DISABLE(&LPTIMConf);                        
                                                /* 使能LPTIM和中断,并开启单次计数模式 */
                                                APP_LPTIMStart(6);//6秒后自动唤醒
                                                /* 进入STOP模式,使用中断唤醒 */
                                                HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);        
                                }

       }
}

/**
  * @brief  系统时钟配置函数
  * @param  无
  * @retval 无
  */
void APP_SystemClockConfig(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /* 选择振荡器HSI,LSI */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;                          /* 开启HSI */
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;                          /* HSI 1分频 */
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz; /* 配置HSI时钟16MHz */
  RCC_OscInitStruct.HSEState = RCC_HSE_OFF;                         /* 关闭HSE */
  RCC_OscInitStruct.LSIState = RCC_LSI_OFF;                           /* 关闭LSI */
  RCC_OscInitStruct.LSEState = RCC_LSE_OFF;                          /* 关闭LSE */
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;                     /* 关闭PLL */
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;       /* 选择时钟源为HSI */
  /* 配置振荡器 */
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    APP_ErrorHandler();
  }
  /* 时钟源配置    选择配置时钟 HCLK,SYSCLK,PCLK1 */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;        /* AHB时钟 1分频 */
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;         /* APB时钟 1分频 */
  /* 配置时钟源 */
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    APP_ErrorHandler();
  }
}

/**
  * @brief  错误执行函数
  * @param  无
  * @retval 无
  */
void APP_ErrorHandler(void)
{
  while (1)
  {
  }
}

#include "lptim.h"
#include "gpio.h"


LPTIM_HandleTypeDef       LPTIMConf;

/**
  * @brief   时钟配置函数
  * @param   无
  * @retval  无
  */
void APP_RCCOscConfig(void)
{

  RCC_PeriphCLKInitTypeDef LPTIM_RCC;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* LSI时钟配置 */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;  /* 选择配置LSI */
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;          /* LSI开启 */  
  /*时钟初始化*/
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
  }
        
  /* LPTIM时钟配置 */
  LPTIM_RCC.PeriphClockSelection = RCC_PERIPHCLK_LPTIM;     /* 选择配置外设时钟:LPTIM */
  LPTIM_RCC.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSI;   /* 选择LPTIM时钟源:LSI */
  /* 外设时钟初始化 */
  if (HAL_RCCEx_PeriphCLKConfig(&LPTIM_RCC) != HAL_OK)
  {

  }

  /*使能LPTIM时钟*/
  __HAL_RCC_LPTIM_CLK_ENABLE();
}

/**
  * @brief   初始化LPTIM
  * @param   无
  * @retval  无
  */
void APP_LPTIMInit(void)
{
  /*LPTIM配置*/
  LPTIMConf.Instance = LPTIM;                         /* LPTIM */
  LPTIMConf.Init.Prescaler = LPTIM_PRESCALER_DIV128;  /* 128分频 */
  LPTIMConf.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE; /* 立即更新模式 */
  /*初始化LPTIM*/
  if (HAL_LPTIM_Init(&LPTIMConf) != HAL_OK)
  {

  }

}

/**
  * @brief   使能LPTIM和中断,并开启单次计数模式
  * @param   无
  * @retval  无
  */
void APP_LPTIMStart(uint8_t i)
{
  /* 使能重载中断 */
  __HAL_LPTIM_ENABLE_IT(&LPTIMConf, LPTIM_IT_ARRM);

  /* 使能LPTIM */
  __HAL_LPTIM_ENABLE(&LPTIMConf);

  /*加载重载值*/
  __HAL_LPTIM_AUTORELOAD_SET(&LPTIMConf, 51*5*i);

  /* 延时65us */
  APP_delay_us(65);

  /* 开启单次计数模式 */
  __HAL_LPTIM_START_SINGLE(&LPTIMConf);
        
}

void LPTIM1_IRQHandler(void)
{
  HAL_LPTIM_IRQHandler(&LPTIMConf);
}

/**
  * @brief   LPTIM重装载中断回调函数
  * @param   无
  * @retval  无
  */
void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
    /* LED翻转 */
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);  
}


/**
  * @brief   微秒延时函数
  * @param   nus:延时时间
  * @retval  无
  * @note    此函数会关闭SysTick中断,如需要使用请重新初始化SysTick
  */
void APP_delay_us(uint32_t nus)
{
  HAL_SuspendTick();
  uint32_t temp;
  SysTick->LOAD=nus*(SystemCoreClock/1000000);
  SysTick->VAL=0x00;
  SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
  do
  {
    temp=SysTick->CTRL;
  }
  while((temp&0x01)&&!(temp&(1<<16)));
  SysTick->CTRL=0x00;
  SysTick->VAL =0x00;
}

#ifndef _LPTIM_H
#define _LPTIM_H
#include "main.h"


extern LPTIM_HandleTypeDef       LPTIMConf;

void APP_RCCOscConfig(void);
void APP_LPTIMInit(void);
void APP_LPTIMStart(uint8_t i);
void APP_delay_us(uint32_t nus);


#endif


Keil代码下载: PY32F0_LPTIM.7z (1.03 MB, 下载次数: 10)

1.png (93.45 KB, 下载次数: 83)

1.png

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:146878 发表于 2023-5-11 23:15 | 只看该作者
这测电流的是什么东西?
回复

使用道具 举报

板凳
ID:1110945 发表于 2024-3-4 20:28 | 只看该作者
有没有直接操作寄存器的例程?这种库操作太占用代码空间了。
回复

使用道具 举报

地板
ID:1110945 发表于 2024-3-8 13:21 | 只看该作者
我手上有XL32F001,设好端口模式,再几代码就进入stop模式了,
我测到的是1.6微安@3.0V,比手册上的1.1微安多一点。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表