【GD32450I-EVAL】+ 03 Basic usage of library functions - taking key interrupt as an example
[Copy link]
This post was last edited by DDZZ669 on 2020-9-18 22:05
The previous article " 【GD32450I-EVAL】+ 02 Software Development Environment Configuration (KEIL 5) and Running Light Test " introduced the configuration of the software development environment. In this article, let's take a look at the basic usage of GD32 library functions.
I have used STM32 microcontrollers before. Compared with the current GD32, the programming ideas are basically the same when using library functions for development, except that the names of the library functions used are different.
The following uses " 03_GPIO_KeyBoard_Interrupt_mode " in the CD-ROM as an example to analyze how to use the library function.
1 Program Analysis
First, let’s look at the main function in the example:
int main(void)
{
gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI);
gd_eval_led_init(LED1);
while(1)
{
}
}
The logic is very simple, which is to initialize the buttons and LEDs, and then enter the while(1) infinite loop to monitor the occurrence of interrupts.
1.1 Button Configuration
Let's take a look at the initialization part of the button first:
void gd_eval_key_init(key_typedef_enum key_num, keymode_typedef_enum key_mode)
{
/* enable the key clock */
rcu_periph_clock_enable(KEY_CLK[key_num]);
rcu_periph_clock_enable(RCU_SYSCFG);
/* configure button pin as input */
gpio_mode_set(KEY_PORT[key_num], GPIO_MODE_INPUT, GPIO_PUPD_NONE,KEY_PIN[key_num]);
if (key_mode == KEY_MODE_EXTI)
{
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(KEY_IRQn[key_num], 2U, 0U);
/* connect key EXTI line to key GPIO pin */
syscfg_exti_line_config(KEY_PORT_SOURCE[key_num], KEY_PIN_SOURCE[key_num]);
/* configure key EXTI line */
exti_init(KEY_EXTI_LINE[key_num], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(KEY_EXTI_LINE[key_num]);
}
}
1.1.1 Clock Configuration
The first step is to enable the clock source of the button pin, including GPIO clock and RCU clock, by calling the rcu_periph_clock_enable() function.
This function operates the register:
void rcu_periph_clock_enable(rcu_periph_enum periph)
{
RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph));
}
1.1.2 GPIO Configuration
Then the mode configuration of the key GPIO is completed by calling the gpio_mode_set() function, which is declared as:
void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin);
parameter:
gpio_periph:GPIO peripheral selection
GPIOx (x = A,B,C,D,E,F,G,H,I)
mode: GPIO pin mode
GPIO_MODE_INPUT: input mode
GPIO_MODE_OUTPUT: output mode
GPIO_MODE_AF: Alternate function mode
GPIO_MODE_ANALOG: Analog signal mode
pull_up_dowm: GPIO pin "pull up/down" setting
GPIO_PUPD_NONE: No pull-up/pull-down
GPIO_PUPD_PULLUP: pull-up mode
GPIO_PUPD_PULLDOWN: pull-down mode
pin: GPIO pin selection
GPIO_PIN_x (x=0..15), GPIO_PIN_ALL
In addition, the GPIO peripherals and pins are managed using arrays and macro definitions, such as:
gpio_mode_set(KEY_PORT[key_num], GPIO_MODE_INPUT, GPIO_PUPD_NONE,KEY_PIN[key_num]);
Find the definition of KEY_PORT[key_num] and KEY_PIN[key_num] in this sentence (key_num passed in when calling the function is KEY_TAMPER), which are in "gd32f450i_eval.h" and "gd32f450i_eval.c":
#define TAMPER_KEY_PIN GPIO_PIN_13
#define TAMPER_KEY_GPIO_PORT GPIOC
static uint32_t KEY_PORT[KEYn] = {WAKEUP_KEY_GPIO_PORT,
TAMPER_KEY_GPIO_PORT,
USER_KEY_GPIO_PORT};
static uint32_t KEY_PIN[KEYn] = {WAKEUP_KEY_PIN, TAMPER_KEY_PIN,USER_KEY_PIN};
Therefore, the PC13 pin corresponding to the Tamper user button on the board is defined in this way.
1.1.3 Interrupt Configuration
Next is the interrupt configuration, including NVIC configuration and EXTI configuration:
nvic_irq_enable(KEY_IRQn[key_num], 2U, 0U);
syscfg_exti_line_config(KEY_PORT_SOURCE[key_num], KEY_PIN_SOURCE[key_num]);
After configuration, initialize the set parameters to take effect:
exti_init(KEY_EXTI_LINE[key_num], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(KEY_EXTI_LINE[key_num]);
1.2 LED Configuration
Let's take a look at the LED initialization part:
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];
}
First, call the rcu_periph_clock_enable() function to enable the clock, and then call the gpio_mode_set() function to set the mode.
In addition, the control pin of the LED is used as an output mode, and the gpio_output_options_set() function is called to set the output configuration:
void gpio_output_options_set(uint32_t gpio_periph,uint8_t otype,uint32_t speed,uint32_t pin);
parameter:
gpio_periph : GPIO peripheral selection
GPIOx (x = A,B,C,D,E,F,G,H,I)
otype : GPIO pin output mode
GPIO_OTYPE_PP: push pull mode
GPIO_OTYPE_OD: open drain mode
speed : GPIO pin maximum output speed (frequency)
GPIO_OSPEED_2MHZ: 2MHz
GPIO_OSPEED_25MHZ: 25MHz
GPIO_OSPEED_50MHZ: 50MHz
GPIO_OSPEED_200MHZ: 200MHz
pin : GPIO pin selection
GPIO_PIN_x (x=0..15), GPIO_PIN_ALL
The program uses: push-pull mode output, speed 50MHz. LED
Finally, use GPIO_BC() to clear the GPIO pin to zero (Bit Clear), that is, low level, so that the LED is off by default.
1.3 Interrupt Handling Function
The interrupt function is in the "gd32f4xx_it.c" file:
void EXTI10_15_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_13))
{
gd_eval_led_toggle(LED1);
}
exti_interrupt_flag_clear(EXTI_13);
}
When a button is pressed, the interrupt handler is triggered. At this time, gd_eval_led_toggle() is called to flip the level to turn on the LED.
This function actually calls the GPIO_TG() function in the library function:
void gd_eval_led_toggle(led_typedef_enum lednum)
{
GPIO_TG(GPIO_PORT[lednum]) = GPIO_PIN[lednum];
}
After toggling the LED, call exti_interrupt_flag_clear() to clear the interrupt flag.
2 Program compilation and download
Compile it and you can see the following compilation information:
...省略若干行
compiling gd32f450i_eval.c...
assembling startup_gd32f450.s...
linking...
Program Size: Code=1564 RO-data=460 RW-data=100 ZI-data=1028
FromELF: creating hex file...
".\output\GD32450I_EVAL.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:14
Here are some Program Sizes :
Code is the space occupied by the code. Code=1564, that is, 1564 bytes, more than 1K.
RO-data is the size of a Read Only constant , such as a const type. RO-data = 460, which means 460 bytes.
RW-data is the size of the Read Write variable , which is assigned during initialization. RW-data=100, which means 100 bytes.
ZI-data is the size of the readable and writable variables that are not initialized by Zero Initialize. Uninitialized variables are assigned a value of 0. ZI-data = 1028, which is 1028 bytes, a little more than 1K.
in:
RW + ZI is the total number of bytes of RAM used by the program.
RAM is the kind that is lost when the power is off (analogous to the computer's memory, which always stores data when the program is running). This board has 256KB of RAM (internal SRAM).
Code + RO + RW is the number of bytes of the program downloaded into Flash.
Flash is the kind that will not be lost after power failure. This board has 3MB of internal Flash.
Note :
Although RW and ZI variable data are stored in RAM, RW must also be stored in Flash because the data will be lost when RAM loses power, while Flash does not need to include ZI because ZI data is all 0. All you need to do is clear the area where the ZI data is located to 0 before the program runs. Including it will waste storage space.
3 Effect display
Press the button and the LED turns on, press it again and the LED turns off.
|