草帽王子 发表于 2021-7-31 19:36:21

第一百零六章:CH32V103应用教程——睡眠模式下串口数据传输

本章教程主要讲述如何通过按键控制进入/退出睡眠模式,同时演示正常模式下和睡眠模式下串口数据传输。注意,在睡眠模式下,进行串口数据传输时,当进入串口中断时,会唤醒退出睡眠模式,但不影响数据传输。本次教程所用中断是串口读数据寄存器非空时进入中断。

1、PWR-睡眠模式简介

CH32单片机进入睡眠模式后,所有的IO引脚都保持他们运行模式下的状态,所有的外设时钟,所以进入睡眠模式前,尽量关闭无用的外设时钟,以减低功耗。该模式唤醒所需时间最短。

进入:配置内核寄存器控制位 SLEEPDEEP=0,电源控制寄存器 PDDS=0,LPDS 决定内部调压器状态,执行 WFI 或 WFE,可选 SEVONPEND 和 SLEEPONEXIT。

退出:任意中断或者唤醒事件。

关于CH32V103 PWR睡眠模式具体信息,可参考CH32V103应用手册。

2、硬件设计

单片机长按PA1按键进入睡眠模式,PA0按键按下退出睡眠模式,同时进行串口2数据传输。

3、软件设计

本次实验具体程序如下,主要介绍main函数:
Main.c文件
/********************************** (C) COPYRIGHT*******************************

* File Name          : main.c

* Author             : WCH

* Version            : V1.0.0

* Date               : 2019/10/15

* Description      : Main program body.

*******************************************************************************/



/*

*@Note

低功耗,睡眠模式例程:

本例程演示 PA1按键长按 WFI 进入睡眠模式,PA0引脚输入低电平触发外部中断 EXTI_Line0 退出睡眠模式,

唤醒后程序继续执行。

*/



#include "debug.h"

#include "key.h"

#include "usart.h"



//用于检测按键是否被长时间按下

//1 :按键被长时间按下0 :按键没有被长时间按下

static uint8_t KEY_LongPress(void)

{

    uint8_t downCnt =0;                                       //记录按下的次数

    uint8_t upCnt =0;                                           //记录松开的次数



    while(1)                                                    //死循环,由return结束

    {

      Delay_Ms(10);                                           //延迟一段时间再检测



      if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == SET)      //检测到按下按键

      {

            downCnt++;                                          //记录按下次数

            upCnt=0;                                          //清除按键释放记录



            if(downCnt>=50)                                     //按下时间足够

            {

                return 1;                                       //检测到按键被时间长按下

            }

      }

      else

      {

            upCnt++;                                          //记录释放次数

            if(upCnt>5)                                       //连续检测到释放超过5次

            {

                return 0;                                       //按下时间太短,不是按键长按操作

            }

      }

    }

}





/*******************************************************************************

* Function Name: main

* Description    : Main program.

* Input          : None

* Return         : None

*******************************************************************************/

int main(void)

{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    Delay_Init();

    USART_Printf_Init(115200);



    KEY_GPIO_Init();

    EXTI0_INT_INIT();

    USARTx_CFG();



    Delay_Ms(100);

    USARTx_SendStr(USART2, "This is a test data.\n");



    Delay_Ms(100);

    printf("\r\nSystemClk:%d\r\n",SystemCoreClock);

    printf("\r\nSleep Mode Test\r\n");

    printf("\r\n 实验说明\r\n");

    printf("\r\n 1.程序正常运行时可通过长按PA1按键进入睡眠模式:\r\n");

    printf("\r\n 2.在睡眠模式下,可通过PA0唤醒\r\n");

    printf("\r\n 3.在睡眠状态下,通过Link无法下载程序,需要唤醒后才能下载\r\n");



    while(1)

    {

      //PA1 按键长按进入待机模式

      if(KEY_LongPress())

      {

            printf("\r\n 进入睡眠模式,可通过PA0唤醒\r\n");

            //进入睡眠模式

            __WFI();    //WFI指令进入睡眠

      }

    }

}Main.c文件主要包含三个函数:GPIO引脚全部拉低函数、按键长按检测函数、以及main函数。main函数包含函数初始化、相关状态信息显示。关于程序具体介绍,可见程序注释。

4、下载验证

将编译好的程序下载到开发板并复位,串口1主要打印相关提示信息,串口2主要进行数据传输,具体如下:



页: [1]
查看完整版本: 第一百零六章:CH32V103应用教程——睡眠模式下串口数据传输