外观
长按开关机
电路分析
整体万用表仅有一个EC11旋转编码器作为功能按键,当EC11旋转编码器按下时,DE引脚导通,+5V输入电源连接到LDO的使能引脚,使整体系统上电;
同时,当按键按下时,+5V电源会使Q2-AO3400导通,此时PC2引脚被下拉到GND,通过检测PC2引脚低电平时间来判断按键按下的时间,当到达指定时间时,PC2引脚输出高电平,此时不管EC11是否按下,单片机引脚都有输出高电平使LDO的使能引脚保持高电平,此时系统正常开机。后续也是同样的通过判断按下的时间来使PC2引脚输出低电平,断开系统电源,从而实现长按开关机功能。
功能实现
创建工程
- 点击左上方文件,旋转新建,选择新建MounRiver工程;
- 对工程进行修改,修改完成后点击“完成”按键,系统会自动生成好工程;
- 创建自己的工程库文件夹,分别创建头文件与源文件;
- 对工程库路径进行包含;
代码实现
- 包含头文件,在头文件中包含ch32相关的头文件,方便对库函数进行调用;
C
#ifndef MYLIB_INC_POWERSWITCH_H_
#define MYLIB_INC_POWERSWITCH_H_
#include "ch32v20x.h"
#include "debug.h"
#endif /* MYLIB_INC_POWERSWITCH_H_ */
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 在源文件中创建四个函数,用于实现长按开关机功能;
初始化电源控制引脚函数--使能对应的引脚;默认将电源控制引脚关闭输出,只有当检查到长按时,才进行输出高电平。长按检测引脚是输入功能,不是输出功能,这点需要注意;
打开电源控制引脚函数--就是将电源控制引脚拉高;
关闭电源控制引脚函数--就是将电源控制引脚拉低;
C
/*
* 函数内容:初始化电源控制引脚
* 函数参数:无
* 返回值:无
*/
void Init_Power_Con_GPIO(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_WriteBit(GPIOC,GPIO_Pin_3,Bit_RESET);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
C
/*
* 函数内容:打开电源控制引脚
* 函数参数:无
* 返回值:无
*/
void Open_Power(void)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_3,Bit_SET);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
C
/*
* 函数内容:关闭电源控制引脚
* 函数参数:无
* 返回值:无
*/
void Close_Power(void)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_3,Bit_RESET);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
扫描电源按下检查引脚函数--用于判断是否长按开关机,注意要加一个标志位,用于检测是长按开机还是长按关机。当按键按下时,在1.5s内不断检测按键是否松手,如果不到1.5s就检测到松手,此时不是长按,无效;如果超过1.5s,此时是长按,再判断是开机还是关机。
在主函数中对函数进行调用,测试实现功能;
C
/*
* 函数内容:扫描电源按下检测引脚,用于判断是否是长按开机
* 函数参数:无
* 返回值:无
*/
static uint8_t first_press_flag = 0;
void Scanf_Power_Key(void)
{
uint16_t i = 0;
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == Bit_RESET)
{
Delay_Ms(10);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == Bit_RESET)
{
for(i = 0;i < 1500; i++)
{
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2) == Bit_SET){
break;
}
Delay_Ms(1);
}
if(i < 1500 ){
return;
}
if(first_press_flag == 0){
Open_Power();
first_press_flag = 1;
}else {
Close_Power();
first_press_flag = 0;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
C
#include "debug.h"
#include "powerswitch.h"
/* Global typedef */
/* Global define */
/* Global Variable */
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SystemCoreClockUpdate();
Delay_Init();
Init_Power_Con_GPIO();
while(1)
{
Scanf_Power_Key();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
源码下载(使用USB下载方式)
- 第一次给万用表项目下载代码时,首先需要使用万用表测试是否有短路现象,确认没有短路后再进行上电;
- 上电后,默认LDO引脚是关闭状态;若使用USB进行下载;需要同时按住下载按键与EC11;随后按一下复位;此时USB下载软件会检查到单片机信息,即可开始下载程序;(选择通用Risc-V系列)
- 若使用下载器进行下载,插入Typec线进行供电;并将下载器连接好;同时按住下载按键与EC11,随后在编译器中,选择下载选项进行下载。
TIP
源码&USB下载工具等软件,均在gitee资料中