外观
按键输入实验
电路分析
数控直流电源板上有三个按键,用户可以通过这三个按键来实现输出电压切换、输出电流保护以及控制输出等功能,从电路图中可以看到,按键的一端连接GND,另一端连接芯片IO引脚,当按键按下时,IO引脚连接GND为低电平,此时如果想检测按键按下的变化,需要将IO引脚默认上拉为高电平。这样按键按下就有一个从高到低的电平变化,从而可以检测按键是否按下。
功能实现
创建工程
- 打开cubemx软件,配置工程;在此之前需要确保你已经成功安装stm32cubemx软件以及keil软件并下载好对应的芯片支持包了。
注
固态继电器相关引脚默认要拉高,这是为了默认关断固态继电器,同时有一点,切勿把三个引脚都同时拉低,在同一时刻只能有一个固态继电器打开,否则高电压会影响低电压,这一点在配置以及后续代码编写过程中都非常重要。
ch224是电源诱骗芯片,我们可以通过控制对应的引脚来控制输出电压,配置的电平需参考数据手册,默认cfg为1输出5V电平比较合适。
机械按键在按下与松开时,不可避免会产生机械抖动,在进行按键判断时,需要进行消抖操作减少抖动的影响,抖动时间通常是10~30ms之间,最简单的消抖操作是通过延时死等的方式去除抖动。
代码实现
默认生成的代码编译是没有任何问题的,若有问题,基本上就是环境文件,需要重新检查安装,建议把错误信息复制到百度进行查找解决。
gpio.c实现相关的GPIO操作代码,注意需要有一点点c语言基础,hal库对于各类操作进行了抽象封装,可以在stm32f0xx_hal_gpio文件中找到相关的操作函数,这里仅使用:
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
对GPIO进行输入、输出高低电平操作。
按键输入实验部分代码
C
/*
函数内容:设置ch224引脚电平,以改变输出电压值
函数参数:设置输出电压值
*/
static void setch224(uint16_t setVol)
{
if(setVol == VOL_5V0){
HAL_GPIO_WritePin(CFG1_GPIO_Port,CFG1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(CFG2_GPIO_Port,CFG2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG3_GPIO_Port,CFG3_Pin,GPIO_PIN_RESET);
}
else if(setVol == VOL_9V0){
HAL_GPIO_WritePin(CFG1_GPIO_Port,CFG1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG2_GPIO_Port,CFG2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG3_GPIO_Port,CFG3_Pin,GPIO_PIN_RESET);
}
else if(setVol == VOL_12V){
HAL_GPIO_WritePin(CFG1_GPIO_Port,CFG1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG2_GPIO_Port,CFG2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG3_GPIO_Port,CFG3_Pin,GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(CFG1_GPIO_Port,CFG1_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(CFG2_GPIO_Port,CFG2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(CFG3_GPIO_Port,CFG3_Pin,GPIO_PIN_RESET);
}
}
/*
函数内容:控制VBUS也就是5V、9V、12V
函数参数:打开或关闭
*/
static void controlVBUS(uint8_t con)
{
if(con == OPENPOWER){
HAL_GPIO_WritePin(CON_IO1_GPIO_Port,CON_IO1_Pin,GPIO_PIN_RESET);
}
else if(con == CLOSEPOWER){
HAL_GPIO_WritePin(CON_IO1_GPIO_Port,CON_IO1_Pin,GPIO_PIN_SET);
}
}
/*
函数内容:控制3.3V
函数参数:打开或关闭
*/
static void control3V3(uint8_t con)
{
if(con == OPENPOWER){
HAL_GPIO_WritePin(CON_IO2_GPIO_Port,CON_IO2_Pin,GPIO_PIN_RESET);
}
else if(con == CLOSEPOWER){
HAL_GPIO_WritePin(CON_IO2_GPIO_Port,CON_IO2_Pin,GPIO_PIN_SET);
}
}
/*
函数内容:控制1.8V
函数参数:打开或关闭
*/
static void control1V8(uint8_t con)
{
if(con == OPENPOWER){
HAL_GPIO_WritePin(CON_IO3_GPIO_Port,CON_IO3_Pin,GPIO_PIN_RESET);
}
else if(con == CLOSEPOWER){
HAL_GPIO_WritePin(CON_IO3_GPIO_Port,CON_IO3_Pin,GPIO_PIN_SET);
}
}
/*
函数内容:打开电源开关,也就是固态继电器
函数参数:输出电压值
*/
void OpenPowerSwitch(uint8_t value)
{
switch(value)
{
case VOL_1V8:
{
setch224(VOL_5V0);
control1V8(OPENPOWER);
control3V3(CLOSEPOWER);
controlVBUS(CLOSEPOWER);
}
break;
case VOL_3V3:
{
setch224(VOL_5V0);
control1V8(CLOSEPOWER);
control3V3(OPENPOWER);
controlVBUS(CLOSEPOWER);
}
break;
case VOL_5V0:
{
setch224(VOL_5V0);
control1V8(CLOSEPOWER);
control3V3(CLOSEPOWER);
controlVBUS(OPENPOWER);
}
break;
case VOL_9V0:
{
setch224(VOL_9V0);
control1V8(CLOSEPOWER);
control3V3(CLOSEPOWER);
controlVBUS(OPENPOWER);
}
break;
case VOL_12V:
{
setch224(VOL_12V);
control1V8(CLOSEPOWER);
control3V3(CLOSEPOWER);
controlVBUS(OPENPOWER);
}
break;
default:
{
setch224(VOL_5V0);
control1V8(CLOSEPOWER);
control3V3(CLOSEPOWER);
controlVBUS(OPENPOWER);
}
break;
}
}
/*
函数内容:关闭电源开关
函数参数:无
*/
void ClosePowerSwitch(void)
{
setch224(VOL_5V0);
control1V8(CLOSEPOWER);
control3V3(CLOSEPOWER);
controlVBUS(CLOSEPOWER);
}
uint8_t keyScanf(void)
{
if(HAL_GPIO_ReadPin(SW1_GPIO_Port,SW1_Pin) == RESET)
{
HAL_Delay(20);
if(HAL_GPIO_ReadPin(SW1_GPIO_Port,SW1_Pin) == RESET)
{
while(HAL_GPIO_ReadPin(SW1_GPIO_Port,SW1_Pin) == RESET);
return SW1PRESS;
}
}
if(HAL_GPIO_ReadPin(SW2_GPIO_Port,SW2_Pin) == RESET)
{
HAL_Delay(20);
if(HAL_GPIO_ReadPin(SW2_GPIO_Port,SW2_Pin) == RESET)
{
while(HAL_GPIO_ReadPin(SW2_GPIO_Port,SW2_Pin) == RESET);
return SW2PRESS;
}
}
if(HAL_GPIO_ReadPin(SW3_GPIO_Port,SW3_Pin) == RESET)
{
HAL_Delay(20);
if(HAL_GPIO_ReadPin(SW3_GPIO_Port,SW3_Pin) == RESET)
{
while(HAL_GPIO_ReadPin(SW3_GPIO_Port,SW3_Pin) == RESET);
return SW3PRESS;
}
}
return NoPRESS;
}
void keyHandler(uint8_t keyValue)
{
static uint8_t sw1Num = 0;
switch(keyValue)
{
case SW1PRESS:
if(sw1Num == 0){
OpenPowerSwitch(VOL_3V3);
sw1Num++;
}
else{
ClosePowerSwitch();
sw1Num = 0;
}
break;
case SW2PRESS:
break;
case SW3PRESS:
break;
default:
break;
}
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
C
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
#define OPENPOWER 0x20
#define CLOSEPOWER 0x21
#define VOL_1V8 0x10
#define VOL_3V3 0x11
#define VOL_5V0 0x12
#define VOL_9V0 0x13
#define VOL_12V 0x14
#define NoPRESS 0xff
#define SW1PRESS 0x04
#define SW2PRESS 0x05
#define SW3PRESS 0x06
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
void OpenPowerSwitch(uint8_t value);
void ClosePowerSwitch(void);
uint8_t keyScanf(void);
void keyHandler(uint8_t keyValue);
/* USER CODE END Prototypes */
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
36
37
38
39
40
41
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
36
37
38
39
40
41
C
#include "main.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t keyValue = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
keyValue = keyScanf();
keyHandler(keyValue);
}
/* USER CODE END 3 */
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
TIP
当代码烧录进去后,使用万用表测试输出接口电压,默认是关闭状态的,此时可以按下按键1,也就是设置按键,此时输出接口会有3.3V输出,再按以下关闭输出。
一定注意不可同时打开多个继电器,这里再三强调。
若发现输出9V、12V失败,可以看看自己的充电头或充电线是不是不支持该电压输出。