[Xianji HPM6750 Review] GPIO lighting and button control
[Copy link]
This post was last edited by xusiwei1236 on 2022-5-22 20:12
[Xianji HPM6750 Review] GPIO lighting and button control
In the previous post, we introduced how to install and activate SEGGER Embedded Studio, and use Embedded Studio for compilation and debugging. This post will introduce how to light up the three-color LED on the development board, and how to use the LED on the development board to control the three-color LED.
GPIO lighting
Create a flashing light program
Create a gpio_led directory in the hpm_sdk/samples subdirectory, copy the src directory and CMakeLists.txt in the hello_world directory to the gpio_led directory (of course, you can modify it directly based on hello_world if you don’t want to bother), rename src/hello_world.c to gpio_led.c, and modify the file content to:
#include <stdio.h>
#include "board.h"
#include "hpm_gpio_drv.h"
#define LED_FLASH_PERIOD_IN_MS 500
int main(void)
{
int u;
board_init();
board_init_led_pins();
//board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 0);
gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, 0);
gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, 0);
printf("gpio_led start...\\n");
while(1)
{
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 0);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 1);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
}
return 0;
}
The content of the CMakeLists.txt file is modified as follows:
# Copyright 2021 hpmicro
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.13)
find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(gpio_led)
sdk_compile_definitions(-DBOARD_SHOW_CLOCK=0)
sdk_app_src(src/gpio_led.c)
generate_ses_project()
Compile and run the flashing program
In the hpm_sdk\samples\gpio_led directory, run the generate_project -b hpm6750evkmini -t flash_xip -f command to generate the project file.
Use SEGGER Embedded Studio to open the produced project file, as shown below:
After compiling and running, you can see the red LED flashing:
led_red_blink
Analysis of the three-color LED schematic
By consulting the schematic diagram, you can find the schematic diagram related to the three-color LED as follows:
You can see the control pin information of the three colors as follows:
- Red is controlled by PWM1.P0 and lights up at high level;
- Green is controlled by PWM1.P1 and lights up at high level;
- Blue is controlled by PWM0.P7 and lights up at high level;
Continue searching for PWM1.P0, PWM1.P1, and PWM0.P7 in the schematic and you will find:
Here, the chip labeled U1 is the HPM6750. The corresponding relationship between PWM1.P0, PWM1.P1 and PWM0.P7 and the pin numbers is as follows:
- PWM1.P0 corresponds to PB19, controlling red;
- PWM1.P1 corresponds to PB18, controlling green;
- PWM9.P7 corresponds to PB20, controlling blue;
The above analysis is consistent with the code in the board.h file:
#define BOARD_R_GPIO_CTRL HPM_GPIO0
#define BOARD_R_GPIO_INDEX GPIO_DI_GPIOB
#define BOARD_R_GPIO_PIN 19
#define BOARD_G_GPIO_CTRL HPM_GPIO0
#define BOARD_G_GPIO_INDEX GPIO_DI_GPIOB
#define BOARD_G_GPIO_PIN 18
#define BOARD_B_GPIO_CTRL HPM_GPIO0
#define BOARD_B_GPIO_INDEX GPIO_DI_GPIOB
#define BOARD_B_GPIO_PIN 20
Make three colors flash in sequence
Modify gpio_led.c to:
#include <stdio.h>
#include "board.h"
#include "hpm_gpio_drv.h"
#define LED_FLASH_PERIOD_IN_MS 500
int main(void)
{
int u;
board_init();
board_init_led_pins();
//board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 0);
gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, 0);
gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, 0);
printf("gpio_led start...\\n");
while(1)
{
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 1);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, 0);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, 1);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, 0);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, 1);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, 0);
board_delay_ms(LED_FLASH_PERIOD_IN_MS);
}
return 0;
}
Recompile and run.
You can see red, green and blue flashing in sequence:
led_rgb_blink
GPIO reads button status
Next, we try to use GPIO to read the status of the two buttons PBUTN and WBUTN and output them to the serial port.
First, you need to find the button-related schematics in the schematic diagram:
The code snippet for looping and printing the PBUTN and WBUTN button status:
uint32_t count = 0;
while (1)
{
count++;
uint8_t pbutn_value = gpio_read_pin(HPM_BGPIO, GPIO_DI_GPIOZ, 2);
uint8_t wbutn_value = gpio_read_pin(HPM_BGPIO, GPIO_DI_GPIOZ, 3);
printf("[%d] pbutn_value=%d, wbutn_value=%d\\n", count, pbutn_value, wbutn_value);
board_delay_ms(500);
}
Set the PZ02/PZ03 pin function
After testing, it was found that by default, these two buttons have the functions of long pressing to shut down and long pressing to sleep respectively.
You can use the following code snippet to set the functions of these two pins to normal GPIO and set them to internal pull-up state:
static void init_butn_as_gpio()
{
uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
// 设置PZ02、PZ03为GPIO功能
HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_BGPIO_Z_02;
HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = IOC_PZ03_FUNC_CTL_BGPIO_Z_03;
// 设置PZ02、PZ03为GPIO的模式为 内部上拉
HPM_IOC->PAD[IOC_PAD_PZ02].PAD_CTL = pad_ctl;
HPM_IOC->PAD[IOC_PAD_PZ03].PAD_CTL = pad_ctl;
}
Use the PBUTN and WBUTN buttons to control the color of the three-color LED
This section implements switching the colors of the three-color LED through the two buttons PBUTN and WBUTN:
- Press the PBUTN button, the color switching order is red, green, blue
- Press the WBUTN button, the color switching order is blue, green, red
- Long press, the colors will switch in turn
- Release, switching stops
Full code:
#include <stdio.h>
#include "board.h"
#include "hpm_gpio_drv.h"
static void init_butn_as_gpio()
{
uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
// 设置PZ02、PZ03为GPIO功能
HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_BGPIO_Z_02;
HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = IOC_PZ03_FUNC_CTL_BGPIO_Z_03;
// 设置PZ02、PZ03为GPIO的模式为 内部上拉
HPM_IOC->PAD[IOC_PAD_PZ02].PAD_CTL = pad_ctl;
HPM_IOC->PAD[IOC_PAD_PZ03].PAD_CTL = pad_ctl;
}
void app_led_write(uint32_t index, uint8_t state)
{
switch (index)
{
case 0:
gpio_write_pin(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, state);
break;
case 1:
gpio_write_pin(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, state);
break;
case 2:
gpio_write_pin(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, state);
break;
default:
/* Suppress the toolchain warnings */
break;
}
}
uint32_t app_led_next(uint32_t index)
{
return (index + 1) % 3;
}
uint32_t app_led_prev(uint32_t index)
{
return (index + 3 - 1) % 3;
}
int main(void)
{
uint32_t current = 0, next = 0;
board_init();
board_init_led_pins();
init_butn_as_gpio();
while (1)
{
// 读取按键状态
uint8_t pbutn_value = gpio_read_pin(HPM_BGPIO, GPIO_DI_GPIOZ, 2);
uint8_t wbutn_value = gpio_read_pin(HPM_BGPIO, GPIO_DI_GPIOZ, 3);
// 按键状态处理
if (pbutn_value == 0) {
printf("pbutn_value=%d, wbutn_value=%d\\n", pbutn_value, wbutn_value);
next = app_led_next(current);
app_led_write(current, 0);
// app_led_write(next, 1);
current = next;
} else if (wbutn_value == 0) {
printf("pbutn_value=%d, wbutn_value=%d\\n", pbutn_value, wbutn_value);
next = app_led_prev(current);
app_led_write(current, 0);
// app_led_write(next, 1);
current = next;
}
app_led_write(current, 1); // 放这里,第一次能够点亮红色
// 延时,控制扫描频率
board_delay_ms(100);
}
return 0;
}
Effect demonstration:
led_with_btn
Additional Notes
During the lighting process, I found that the high and low levels of the LED on and off of the hpm5760evkmini in SDK 0.9.0 (sdk 0.10.0 also has this problem). I have reported this problem to Xianji, and learned from them that the HPM6750EVKMINI board has been revised. The old version is lit with a low level, and the new version is lit with a high level. The code for this has not been updated. They said that this problem will be fixed in the next version. At present, several code changes are required to solve this problem. The changes are very simple. For details, please refer to my submission record:
Code warehouse
The code repository of the submission link above:
This is a project I created to test the HPM6750 SDK. Star support is welcome.
In addition, I have created an organization named HPM6750 in Code Cloud. There are other code repositories under this organization, which will be set to public as new posts are released. Stay tuned~
|