该篇文章记录了怎么使用 GD32F150 来驱动一个双色LED交替闪烁。首先我们要先搭建一个 GD32 的 MDK 项目,项目的创建很简单,首先通过 MDK 搭建一个空的 GD32 项目,然后把需要用到的 GD 库和一些头文件复制到项目的相关目录下,再在 MDK 中包含这些 头文件的路径即可。

先来看看 main.c 这个主文件:

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
#include "gd32f1x0.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32f1x0r_eval.h"

/*!
\brief LED 闪烁程序,该函数在 系统中断中重复调用(1ms)调用一次。
\param[in] none
\param[out] none
\retval none
*/
void led_spark(void)
{
static __IO uint32_t timingdelaylocal = 0;

// timingdelaylocal 不等于 0
if(timingdelaylocal){

if(timingdelaylocal < 500){
gd_eval_led_on(LED1);
gd_eval_led_off(LED2);
}else{
gd_eval_led_off(LED1);
gd_eval_led_on(LED2);
}

timingdelaylocal--;
}else{ // timingdelaylocal 等于 0
timingdelaylocal = 1000;
}
}

/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
gd_eval_led_init(LED1);
gd_eval_led_init(LED2);

systick_config();

while (1)
{

}
}

我们来看看 void gd_eval_led_init (led_typedef_enum lednum) 这个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* GD32F1x0 eval low layer private functions */
/*!
\brief 该函数的参数是一个枚举类型
\param[in] lednum: specify the Led to be configured
\arg LED1
\arg LED2
\arg LED3
\arg LED4
\param[out] none
\retval none
*/
void gd_eval_led_init (led_typedef_enum lednum)
{
/* enable the led clock */
rcu_periph_clock_enable(GPIO_CLK[lednum]); // 使能外设时钟
/* configure led GPIO port */
gpio_mode_set(GPIO_PORT[lednum], GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN[lednum]);
gpio_output_options_set(GPIO_PORT[lednum], GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN[lednum]);

GPIO_BC(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}

led_typedef_enum 枚举类型

1
2
3
4
5
6
7
8
/* exported types */
typedef enum
{
LED1 = 0,
LED2 = 1,
LED3 = 2,
LED4 = 3
} led_typedef_enum;

led_typedef_enum 为枚举类型,以便后边使用。

GPIO 模式设置

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
/*!
\brief set GPIO mode
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
only one parameter can be selected which is shown as below:
\arg GPIOx(x = A,B,C,D,F)
\param[in] mode: gpio pin mode
only one parameter can be selected which is shown as below:
\arg GPIO_MODE_INPUT: input mode
\arg GPIO_MODE_OUTPUT: output mode
\arg GPIO_MODE_AF: alternate function mode
\arg GPIO_MODE_ANALOG: analog mode
\param[in] pull_up_down: gpio pin with pull-up or pull-down resistor
only one parameter can be selected which is shown as below:
\arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
\arg GPIO_PUPD_PULLUP: with pull-up resistor
\arg GPIO_PUPD_PULLDOWN:with pull-down resistor
\param[in] pin: GPIO pin
one or more parameters can be selected which are shown as below:
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
\param[out] none
\retval none
*/
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
{
uint16_t i;
uint32_t ctl, pupd;

ctl = GPIO_CTL(gpio_periph); // GPIO 控制寄存器
pupd = GPIO_PUD(gpio_periph); // GPIO 上下拉寄存器

for(i = 0U;i < 16U;i++){
if((1U << i) & pin){
/* clear the specified pin mode bits */
ctl &= ~GPIO_MODE_MASK(i);
/* set the specified pin mode bits */
ctl |= GPIO_MODE_SET(i, mode);

/* clear the specified pin pupd bits */
pupd &= ~GPIO_PUPD_MASK(i);
/* set the specified pin pupd bits */
pupd |= GPIO_PUPD_SET(i, pull_up_down);
}
}

GPIO_CTL(gpio_periph) = ctl;
GPIO_PUD(gpio_periph) = pupd;
}

gd32f1x0_it.c

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
#include "gd32f1x0_it.h"
#include "main.h"
#include "systick.h"

/*!
\brief this function handles NMI exception
\param[in] none
\param[out] none
\retval none
*/
void NMI_Handler(void)
{
}

/*!
\brief this function handles HardFault exception
\param[in] none
\param[out] none
\retval none
*/
void HardFault_Handler(void)
{
/* if Hard Fault exception occurs, go to infinite loop */
while(1){
}
}

/*!
\brief this function handles MemManage exception
\param[in] none
\param[out] none
\retval none
*/
void MemManage_Handler(void)
{
/* if Memory Manage exception occurs, go to infinite loop */
while(1){
}
}

/*!
\brief this function handles BusFault exception
\param[in] none
\param[out] none
\retval none
*/
void BusFault_Handler(void)
{
/* if Bus Fault exception occurs, go to infinite loop */
while(1){
}
}

/*!
\brief this function handles UsageFault exception
\param[in] none
\param[out] none
\retval none
*/
void UsageFault_Handler(void)
{
/* if Usage Fault exception occurs, go to infinite loop */
while(1){
}
}

/*!
\brief this function handles SVC exception
\param[in] none
\param[out] none
\retval none
*/
void SVC_Handler(void)
{
}

/*!
\brief this function handles DebugMon exception
\param[in] none
\param[out] none
\retval none
*/
void DebugMon_Handler(void)
{
}

/*!
\brief this function handles PendSV exception
\param[in] none
\param[out] none
\retval none
*/
void PendSV_Handler(void)
{
}

/*!
\brief this function handles SysTick exception
\param[in] none
\param[out] none
\retval none
*/
void SysTick_Handler(void)
{
led_spark(); /* 处理 LED 程序 */
delay_decrement();
}

gd32f1x0r_eval.h

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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*!
\file gd32f1x0r_eval.h
\brief definitions for GD32f1x0_EVAL's leds, keys and COM ports hardware resources

\version 2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
\version 2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
\version 2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
\version 2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
\version 2019-11-20, V3.2.0, firmware update for GD32F1x0(x=3,5,7,9)
\version 2020-09-21, V3.3.0, firmware update for GD32F1x0(x=3,5,7,9)
*/

/*
Copyright (c) 2020, GigaDevice Semiconductor Inc.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#ifndef GD32F1X0R_EVAL_H
#define GD32F1X0R_EVAL_H

#ifdef __cplusplus
extern "C" {
#endif

#include "gd32f1x0.h"

/* exported types */
typedef enum
{
LED1 = 0,
LED2 = 1,
LED3 = 2,
LED4 = 3
} led_typedef_enum;

typedef enum
{
KEY_WAKEUP = 0,
KEY_TAMPER = 1,
#ifdef GD32F130_150
KEY_USER = 2
#endif
} key_typedef_enum;

typedef enum
{
KEY_MODE_GPIO = 0,
KEY_MODE_EXTI = 1
} keymode_typedef_enum;

/* define for GD32130_150 eval board */
#if defined(GD32F130_150)

/* GD32130_150 eval low layer led */
#define LEDn 4

#define LED1_PIN GPIO_PIN_7
#define LED1_GPIO_PORT GPIOA
#define LED1_GPIO_CLK RCU_GPIOA

#define LED2_PIN GPIO_PIN_6
#define LED2_GPIO_PORT GPIOA
#define LED2_GPIO_CLK RCU_GPIOA

#define LED3_PIN GPIO_PIN_5
#define LED3_GPIO_PORT GPIOA
#define LED3_GPIO_CLK RCU_GPIOA

#define LED4_PIN GPIO_PIN_2
#define LED4_GPIO_PORT GPIOD
#define LED4_GPIO_CLK RCU_GPIOD

/* GD32130_150 eval low layer button */
#define KEYn 3

/* tamper push-button */
#define TAMPER_KEY_PIN GPIO_PIN_13
#define TAMPER_KEY_GPIO_PORT GPIOC
#define TAMPER_KEY_GPIO_CLK RCU_GPIOC
#define TAMPER_KEY_EXTI_LINE EXTI_13
#define TAMPER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOC
#define TAMPER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN13
#define TAMPER_KEY_EXTI_IRQn EXTI4_15_IRQn

/* wakeup push-button */
#define WAKEUP_KEY_PIN GPIO_PIN_0
#define WAKEUP_KEY_GPIO_PORT GPIOA
#define WAKEUP_KEY_GPIO_CLK RCU_GPIOA
#define WAKEUP_KEY_EXTI_LINE EXTI_0
#define WAKEUP_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOA
#define WAKEUP_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN0
#define WAKEUP_KEY_EXTI_IRQn EXTI0_1_IRQn

/* user push-button */
#define USER_KEY_PIN GPIO_PIN_7
#define USER_KEY_GPIO_PORT GPIOF
#define USER_KEY_GPIO_CLK RCU_GPIOF
#define USER_KEY_EXTI_LINE EXTI_7
#define USER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOF
#define USER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN7
#define USER_KEY_EXTI_IRQn EXTI4_15_IRQn

/* GD32130_150 eval low layer COM */
#define COMn 1

/* definition for COM 1, connected to USART0 */
#define EVAL_COM0 USART0
#define EVAL_COM0_CLK RCU_USART0

#define EVAL_COM0_TX_PIN GPIO_PIN_9
#define EVAL_COM0_RX_PIN GPIO_PIN_10

#define EVAL_COM_GPIO_PORT GPIOA
#define EVAL_COM_GPIO_CLK RCU_GPIOA
#define EVAL_COM_AF GPIO_AF_1

/* define for GD32F170_190 eval board */
#elif defined(GD32F170_190)

/* GD32170_190 eval low layer led */
#define LEDn 4

#define LED1_PIN GPIO_PIN_11
#define LED1_GPIO_PORT GPIOA
#define LED1_GPIO_CLK RCU_GPIOA

#define LED2_PIN GPIO_PIN_12
#define LED2_GPIO_PORT GPIOA
#define LED2_GPIO_CLK RCU_GPIOA

#define LED3_PIN GPIO_PIN_6
#define LED3_GPIO_PORT GPIOB
#define LED3_GPIO_CLK RCU_GPIOB

#define LED4_PIN GPIO_PIN_7
#define LED4_GPIO_PORT GPIOB
#define LED4_GPIO_CLK RCU_GPIOB

/* GD32170_190 eval low layer button */
#define KEYn 2

/* tamper push-button */
#define TAMPER_KEY_PIN GPIO_PIN_13
#define TAMPER_KEY_GPIO_PORT GPIOC
#define TAMPER_KEY_GPIO_CLK RCU_GPIOC
#define TAMPER_KEY_EXTI_LINE EXTI_13
#define TAMPER_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOC
#define TAMPER_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN13
#define TAMPER_KEY_EXTI_IRQn EXTI4_15_IRQn

/* wakeup push-button */
#define WAKEUP_KEY_PIN GPIO_PIN_0
#define WAKEUP_KEY_GPIO_PORT GPIOA
#define WAKEUP_KEY_GPIO_CLK RCU_GPIOA
#define WAKEUP_KEY_EXTI_LINE EXTI_0
#define WAKEUP_KEY_EXTI_PORT_SOURCE EXTI_SOURCE_GPIOA
#define WAKEUP_KEY_EXTI_PIN_SOURCE EXTI_SOURCE_PIN0
#define WAKEUP_KEY_EXTI_IRQn EXTI0_1_IRQn

/* GD32170_190 eval low layer COM */
#define COMn 2

/* definition for COM 1, connected to USART0 */
#define EVAL_COM1 USART0
#define EVAL_COM1_CLK RCU_USART0
/* definition for COM 2, connected to USART1 */
#define EVAL_COM2 USART1
#define EVAL_COM2_CLK RCU_USART1

#define EVAL_COM1_TX_PIN GPIO_PIN_9
#define EVAL_COM1_RX_PIN GPIO_PIN_10
#define EVAL_COM2_TX_PIN GPIO_PIN_2
#define EVAL_COM2_RX_PIN GPIO_PIN_3

#define EVAL_COM_GPIO_PORT GPIOA
#define EVAL_COM_GPIO_CLK RCU_GPIOA
#define EVAL_COM_AF GPIO_AF_1

#else
#error "Please define GD32F130_150 or GD32F170_190"
#endif

/* function declarations */
/* configures led GPIO */
void gd_eval_led_init(led_typedef_enum lednum);
/* turn on selected led */
void gd_eval_led_on(led_typedef_enum lednum);
/* turn off selected led */
void gd_eval_led_off(led_typedef_enum lednum);
/* toggle the selected led */
void gd_eval_led_toggle(led_typedef_enum lednum);
/* configure key */
void gd_eval_key_init(key_typedef_enum keynum, keymode_typedef_enum key_mode);
/* return the selected button state */
uint8_t gd_eval_key_state_get(key_typedef_enum keynum);
/* configure COM port */
void gd_eval_com_init(uint32_t COM);

#ifdef __cplusplus
}
#endif

#endif /* GD32F1X0R_EVAL_H */