GD32L233RB 驱动数码管
1.数码管有8段A、B、C、D、E、F、G 和 H小数点 以及片选信号(DIG)
DIG用来选择那一位,A-G 用来显示段
静态显示每次只能一次显示单个位
动态显示(动态扫描)所有的位显示结束要在10ms左右 显示2ms 消光1ms
实现动态显示面板数据
NumLED.c
#include "NumLED.h"
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
// 定义GPIO引脚宏
#define DIGIT_1_PIN GPIO_PIN_8
#define DIGIT_2_PIN GPIO_PIN_9
#define DIGIT_3_PIN GPIO_PIN_11
#define DIGIT_4_PIN GPIO_PIN_10
#define SEGMENT_A_PIN GPIO_PIN_8
#define SEGMENT_B_PIN GPIO_PIN_7
#define SEGMENT_C_PIN GPIO_PIN_6
#define SEGMENT_D_PIN GPIO_PIN_15
#define SEGMENT_E_PIN GPIO_PIN_14
#define SEGMENT_F_PIN GPIO_PIN_13
#define SEGMENT_G_PIN GPIO_PIN_12
// 公共关闭所有段的函数
static void closeAllSegments() {
GPIO_BC(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BC(GPIOB) = SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN;
// 拉高所有DIG引脚,确保完全消隐
GPIO_BOP(GPIOA) = DIGIT_1_PIN;
GPIO_BOP(GPIOC) = DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN;
}
// 公共设置单个数码管显示的函数
static void setDigit(int digitPin, int number) {
closeAllSegments();
switch (number) {
case 0:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN;
break;
case 1:
GPIO_BOP(GPIOC) = SEGMENT_B_PIN | SEGMENT_C_PIN;
break;
case 2:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_G_PIN;
break;
case 3:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_G_PIN;
break;
case 4:
GPIO_BOP(GPIOC) = SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_F_PIN | SEGMENT_G_PIN;
break;
case 5:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN;
break;
case 6:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN;
break;
case 7:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
break;
case 8:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN;
break;
case 9:
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN;
break;
default:
// 处理无效数字,这里可以添加日志记录等
break;
}
// 拉低对应的DIG引脚
GPIO_BC(GPIOC) = digitPin;
}
// 初始化函数
void numled_init(void) {
// 使能 GPIOA 时钟
rcu_periph_clock_enable(RCU_GPIOA);
// 配置 PA8 为推挽输出,无上拉下拉
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, DIGIT_1_PIN);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, DIGIT_1_PIN);
// 使能 GPIOB 时钟
rcu_periph_clock_enable(RCU_GPIOB);
// 配置 PB12 - PB15 为推挽输出,无上拉下拉
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEGMENT_D_PIN | SEGMENT_E_PIN | SEGMENT_F_PIN | SEGMENT_G_PIN);
// 使能 GPIOC 时钟
rcu_periph_clock_enable(RCU_GPIOC);
// 配置 PC6 - PC11 为推挽输出,无上拉下拉
gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN | DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN);
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEGMENT_A_PIN | SEGMENT_B_PIN | SEGMENT_C_PIN | DIGIT_2_PIN | DIGIT_3_PIN | DIGIT_4_PIN);
// 初始状态:关闭所有显示
closeAllSegments();
}
// 显示电量百分比函数
void showpercentage(uint8_t lv) {
closepercentage();
switch (lv) {
case 0:
// 拉高 PC8, PC9
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN;
// 拉低 DIG1
GPIO_BC(GPIOA) = DIGIT_1_PIN;
break;
case 1:
// 拉高 PC6, PB15
GPIO_BOP(GPIOC) = SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN;
// 拉低 DIG1
GPIO_BC(GPIOA) = DIGIT_1_PIN;
break;
case 2:
// 拉高 PB13, PB14
GPIO_BOP(GPIOB) = SEGMENT_E_PIN | SEGMENT_F_PIN;
// 拉低 DIG1
GPIO_BC(GPIOA) = DIGIT_1_PIN;
break;
default:
// 处理无效电量等级,这里可以添加日志记录等
break;
}
}
// 关闭电量百分比显示函数
void closepercentage() {
// DIG 拉高
GPIO_BOP(GPIOA) = DIGIT_1_PIN;
// SEG 拉低
closeAllSegments();
}
// 显示数字的函数
void shownum(uint8_t dig, uint8_t n) {
if (dig == 2) {
setDigit(DIGIT_2_PIN, n);
} else if (dig == 3) {
setDigit(DIGIT_3_PIN, n);
} else {
// 处理无效的 dig 值,这里可以添加日志记录等
}
}
// 显示蓝牙图标函数
void showblue() {
closeblue();
// 拉高
GPIO_BOP(GPIOC) = SEGMENT_A_PIN | SEGMENT_B_PIN;
// 拉低 DIG4
GPIO_BC(GPIOC) = DIGIT_4_PIN;
}
// 关闭蓝牙图标函数
void closeblue() {
closeAllSegments();
// 拉高 DIG4
GPIO_BOP(GPIOC) = DIGIT_4_PIN;
}
// 显示温度图标函数
void showtemp() {
closetemp();
// 拉高
GPIO_BOP(GPIOC) = SEGMENT_C_PIN;
GPIO_BOP(GPIOB) = SEGMENT_D_PIN;
// 拉低 DIG4
GPIO_BC(GPIOC) = DIGIT_4_PIN;
}
// 关闭温度图标函数
void closetemp() {
closeAllSegments();
// 拉高 DIG4
GPIO_BOP(GPIOC) = DIGIT_4_PIN;
}
// 轮询显示函数
//第一个参数显示数字 第二个参数显示电量0 红色 /1 绿色 /2 黄色 第三个参数 1 打开蓝牙 第四个参数 1 打开温度
void ShowNum(uint8_t data, uint8_t power, uint8_t of1, uint8_t of2) {
static int displayStep = 0;
// 消隐时间
const TickType_t blankTime = pdMS_TO_TICKS(1);
switch (displayStep) {
case 0:
if(data <= 30){
// 消隐1ms
closeAllSegments();
vTaskDelay(blankTime);
// 显示十位
setDigit(DIGIT_2_PIN, data / 10);
vTaskDelay(pdMS_TO_TICKS(2));
// 消隐
closeAllSegments();
vTaskDelay(blankTime);
// 显示个位
setDigit(DIGIT_3_PIN, data % 10);
vTaskDelay(pdMS_TO_TICKS(2)); //延时停留2ms
}
else{ //如果关掉了这里空走延时 保证五个段总的显示时间在10ms(人眼观看不出刷新)
vTaskDelay(pdMS_TO_TICKS(2));
vTaskDelay(pdMS_TO_TICKS(2));
}
break;
case 1:
// 消隐
closeAllSegments();
vTaskDelay(blankTime);
showpercentage(power);
vTaskDelay(pdMS_TO_TICKS(2));
break;
case 2:
if (of1 == 1) {
// 消隐
closeAllSegments();
vTaskDelay(blankTime);
showblue();
vTaskDelay(pdMS_TO_TICKS(2));
}else{
vTaskDelay(pdMS_TO_TICKS(2));
}
break;
case 3:
if (of2 == 1) {
// 消隐
closeAllSegments();
vTaskDelay(blankTime);
showtemp();
vTaskDelay(pdMS_TO_TICKS(2));
}else{ //如果关掉了这里空走延时 保证五个段总的显示时间在10ms(人眼观看不出刷新)
vTaskDelay(pdMS_TO_TICKS(2));
}
break;
default:
displayStep = 0;
break;
}
// 消隐
closeAllSegments();
vTaskDelay(blankTime);
displayStep = (displayStep + 1) % 4;
}
NumLED.h
#ifndef __NUMLED_H
#define __NUMLED_H
#include "gd32l23x.h"
void numled_init(void);
// 函数声明
void showpercentage(uint8_t lv);
void closepercentage(void);
void shownum(uint8_t dig,uint8_t n);
void showblue(void);
void closeblue(void);
void showtemp(void);
void closetemp(void);
void showclear();
void ShowNum(uint8_t data,uint8_t power,uint8_t of1,uint8_t of2);
//第一个参数显示数字 第二个参数显示电量0 红色 /1 绿色 /2 黄色 第三个参数 1 打开蓝牙 第四个参数 1 打开温度
#endif