[RISC-V MCU 应用开发] 第一百零五章、CH32V103应用教程——按键控制进入/退出待...

[复制链接]
 楼主| RISCVLAR 发表于 2021-7-14 20:51 | 显示全部楼层 |阅读模式
CH32V103应用教程——按键控制进入/退出待机模式

本章教程主要讲述如何通过按键控制进入/退出待机模式,同时通过串口打印显示不同状态。

1、PWR-待机模式简介
CH32待机模式和STM32待机模式有所区别,CH32待机模式对比其停止模式,唯一的差别在于:在某些指定的唤醒条件下退出后,微控制器将被复位,并且执行的是电源复位,因此,CH32在待机模式下IO口保持原来状态。而STM32在待机模式下,所有IO口引脚状态都处于高阻态,除了以下引脚:
● 复位引脚(始终有效)
● 当被设置为防侵入或校准输出时的TAMPER引脚
● 被使能的唤醒引脚
关于CH32V103 PWR待机模式具体信息,可参考CH32V103应用手册。

2、硬件设计
单片机长按PA1按键进入待机模式,PA0按键按下退出待机模式,不通状态下串口打印信息显示。

3软件设计
本次实验具体程序如下,主要介绍main函数:
Main.c文件
  1. /********************************** (C) COPYRIGHT  *******************************
  2. * File Name          : main.c
  3. * Author             : WCH
  4. * Version            : V1.0.0
  5. * Date               : 2019/10/15
  6. * Description        : Main program body.
  7. *******************************************************************************/

  8. /*
  9. *@Note
  10. 低功耗,待机模式例程:
  11. 本例程演示长按PA1按键进入待机模式,WKUP(PA0)引脚上升沿,退出待机模式, 唤醒后程序复位。
  12. 注:为尽可能的降低功耗,建议将不用的GPIO设置成上拉、下拉、模拟输入或设置成输出模式。
  13. */

  14. #include "debug.h"
  15. #include "key.h"

  16. void GPIO_ALL_Init(void)
  17. {
  18.     GPIO_InitTypeDef GPIO_InitStructure;

  19.     //为降低功耗,需将不用的GPIO设置成上拉或下拉输入
  20.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
  21.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  22.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

  23.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  24.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  25.     GPIO_Init(GPIOC, &GPIO_InitStructure);
  26. }

  27. //用于检测按键是否被长时间按下
  28. //1 :按键被长时间按下  0 :按键没有被长时间按下
  29. static uint8_t KEY_LongPress(void)
  30. {
  31.     uint8_t downCnt =0;                                         //记录按下的次数
  32.     uint8_t upCnt =0;                                           //记录松开的次数

  33.     while(1)                                                    //死循环,由return结束
  34.     {
  35.         Delay_Ms(10);                                           //延迟一段时间再检测

  36.         if(GPIO_ReadInputDataBit ( GPIOA, GPIO_Pin_1 ) == SET)  //检测到按下按键
  37.         {
  38.             downCnt++;                                          //记录按下次数
  39.             upCnt=0;                                            //清除按键释放记录

  40.             if(downCnt>=100)                                    //按下时间足够
  41.             {
  42.                 return 1;                                       //检测到按键被时间长按下
  43.             }
  44.         }
  45.         else
  46.         {
  47.             upCnt++;                                            //记录释放次数
  48.             if(upCnt>5)                                         //连续检测到释放超过5次
  49.             {
  50.                 return 0;                                       //按下时间太短,不是按键长按操作
  51.             }
  52.         }
  53.     }
  54. }

  55. /*******************************************************************************
  56. * Function Name  : main
  57. * Description    : Main program.
  58. * Input          : None
  59. * Return         : None
  60. *******************************************************************************/
  61. int main(void)
  62. {

  63.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);
  64.     GPIO_ALL_Init();
  65.     Delay_Init();
  66.     USART_Printf_Init(115200);
  67.     KEY_GPIO_Init();

  68.     printf("SystemClk:%d\r\n",SystemCoreClock);
  69.     printf("Standby Mode Test\r\n");

  70.     printf("\r\n 实验说明\r\n");
  71.     printf("\r\n 1.长按 PA1 按键进入待机模式 \r\n");
  72.     printf("\r\n 2.在待机模式下,PA0 接 VCC 可唤醒,唤醒后系统会进行复位,程序从头开始执行 \r\n");
  73.     printf("\r\n 3.可通过检测WU标志位确定复位来源 \r\n");
  74.     printf("\r\n 4.在待机状态下,通过Link无法下载程序,需要唤醒后才能下载 \r\n");

  75.     //检测复位来源
  76.     if(PWR_GetFlagStatus(PWR_FLAG_WU) == SET)        //若检测到唤醒事件,PA0引脚上升沿
  77.     {
  78.         printf("\r\n Standby wake up reset \r\n");
  79.     }
  80.     else
  81.     {
  82.         printf("\r\n Power on reset \r\n");
  83.     }

  84.     while(1)
  85.     {
  86.         //PA1 按键长按进入待机模式
  87.         if(KEY_LongPress())
  88.         {

  89.             printf("\r\n 即将进入待机模式,进入待机模式后可按PA0唤醒,唤醒后会进行复位,程序从头开始执行\r\n");

  90.             Delay_Ms(10);

  91.             //清除WU状态位
  92.             PWR_ClearFlag (PWR_FLAG_WU);

  93.             //使能WKUP引脚的唤醒功能 ,使能PA0*
  94.             PWR_WakeUpPinCmd (ENABLE);

  95.             //进入待机模式
  96.             PWR_EnterSTANDBYMode();
  97.         }

  98.         //正常模式
  99.         Delay_Ms(1000);
  100.         printf("Run in main\r\n");
  101.     }
  102. }
Main.c文件主要包含三个函数:GPIO引脚全部拉低函数、按键长按检测函数、以及main函数。main函数包含函数初始化、相关状态信息显示。代码理解见注释。

4下载验证
将编译好的程序下载到开发板并复位,串口打印情况具体如下:
图片1.png
长按PA1按键,进入待机模式,串口打印信息如下:
图片2.png
由打印信息可知,提示进入待机模式,可按PA0(WK_UP)按键唤醒退出待机模式,如下图:
图片3.png

104、通过按键控制进入和退出待机模式.rar

468.04 KB, 下载次数: 4

xdqfc 发表于 2021-7-15 10:55 | 显示全部楼层
楼主有没有具体测量一下,待机模式下的静态电流是多少啊??希望提供一下,以备参考。
 楼主| RISCVLAR 发表于 2021-7-16 15:58 | 显示全部楼层
xdqfc 发表于 2021-7-15 10:55
楼主有没有具体测量一下,待机模式下的静态电流是多少啊??希望提供一下,以备参考。
...

可以看沁恒官方提供的CH32V103DSO这个手册,电气特性那一章有提供官方数据
xdqfc 发表于 2021-7-19 17:43 | 显示全部楼层
RISCVLAR 发表于 2021-7-16 15:58
可以看沁恒官方提供的CH32V103DSO这个手册,电气特性那一章有提供官方数据

这个回复等于没有说,资料咱早就拜读过了,就是在调试的时候,跟官方数据有出入,才想问你一下,你那边调试下来的数据究竟是多少。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

44

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