一、基础理论
ESP32-S2具有43个GPIO,理论上可以支持835=280段,但实际上,受限于刷新率和保持时间的限制,按刷新时间20ms,保持时间1ms计算,大概能支持的上限为820=160段。
ESP32-S2 IO拉电流可以达到40mA,但是灌电流只有28mA,所以对于常见的共阴段码显示屏,如果亮度不够,需要加共阴极 二极管驱动。本DEMO仅供演示,IO口直接驱动。
软件架构上,先创建一个定时器任务,设置为20mS刷一次屏,按每条阴极线保持800us~1ms时间顺序刷新显示数据。
本文的目的是演示如何用ESP32-S2驱动段码屏,所写代码仅适合特定的显示屏,用户需要根据选用的段码屏,编写匹配的程序。
二、代码实现
1.框架
建components\display\src和components\display\include文件夹,将显示部分代码作为一个部件放在user_display.c和user_display.h,方便维护和扩展。
先看user_display.c的实现
2.IO配置和初始化部分
#include <stdio.h>
#include “freertos/FreeRTOS.h”
#include “freertos/task.h”
#include “freertos/queue.h”
#include “driver/timer.h”
#include “driver/gpio.h”
#include “user_display.h”/LED模块******************/
uint8_t display_temperature_88=0; //温度显示全局变量,00~99
uint8_t display_temperature_sw=ON; //温度显示开关uint8_t display_capacitance_88=0;//容量显示全局变量,00~99
uint8_t display_capacitance_sw=ON;//容量显示开关uint8_t display_time_88=60;//时间显示全局变量,00~99
uint8_t display_time_sw=ON;//时间显示开关uint8_t line8_sw=ON;//阴极线8显示控制开关
uint8_t line9_sw=ON;//阴极线9显示控制开关
uint8_t line10_water_sw=ON;//阴极线10花洒显示控制开关
uint8_t decorate_sw=ON;//阴极线11、12装饰条显示控制开关
uint8_t lineH_sw=ON;//阳极线H显示控制开关
uint8_t line13_sw=ON;//阴极线13显示控制开关uint8_t line10_cap=1;//阴极线10容量选择,0=不显示,1=8L,2=10L,3=12L
static uint8_t display_fan_num=0;//风扇状态动态计数器
static uint8_t display_fire_num=0;//火焰指示动态计数器
static uint8_t display_water_num=0;//花洒动态计数器#define user_delay_time_us 800 //LED保持时间
/阳极IO/
#define positive_A 33
#define positive_B 34
#define positive_C 35
#define positive_D 36
#define positive_E 37
#define positive_F 38
#define positive_G 39
#define positive_H 40/阴极IO/
#define negative_1 1
#define negative_2 2
#define negative_3 3
#define negative_4 4
#define negative_5 5
#define negative_6 6
#define negative_7 7
#define negative_8 8
#define negative_9 9
#define negative_10 10
#define negative_11 11
#define negative_12 12
#define negative_13 13
#define negative_14 14
#define negative_15 15
#define negative_16 16/IO配置函数*********/
void user_led_init(void)
{
/设置阳极为上拉输出***/
gpio_pad_select_gpio(positive_A);
gpio_set_direction(positive_A, GPIO_MODE_OUTPUT);gpio_pad_select_gpio(positive_B);
gpio_set_direction(positive_B, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_C);
gpio_set_direction(positive_C, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_D);
gpio_set_direction(positive_D, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_E);
gpio_set_direction(positive_E, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_F);
gpio_set_direction(positive_F, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_G);
gpio_set_direction(positive_G, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(positive_H);
gpio_set_direction(positive_H, GPIO_MODE_OUTPUT);
/***********设置阴极为开漏输出**************/
gpio_pad_select_gpio(negative_1);
gpio_set_direction(negative_1, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_2);
gpio_set_direction(negative_2, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_3);
gpio_set_direction(negative_3, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_4);
gpio_set_direction(negative_4, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_5);
gpio_set_direction(negative_5, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_6);
gpio_set_direction(negative_6, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_7);
gpio_set_direction(negative_7, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_8);
gpio_set_direction(negative_8, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_9);
gpio_set_direction(negative_9, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_10);
gpio_set_direction(negative_10, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_11);
gpio_set_direction(negative_11, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_12);
gpio_set_direction(negative_12, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_13);
gpio_set_direction(negative_13, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_14);
gpio_set_direction(negative_14, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_15);
gpio_set_direction(negative_15, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
gpio_pad_select_gpio(negative_16);
gpio_set_direction(negative_16, ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)));
/**********IO初始化***********/
gpio_set_level(positive_A, 0);
gpio_set_level(positive_B, 0);
gpio_set_level(positive_C, 0);
gpio_set_level(positive_D, 0);
gpio_set_level(positive_E, 0);
gpio_set_level(positive_F, 0);
gpio_set_level(positive_G, 0);
gpio_set_level(positive_H, 0);
gpio_set_level(negative_1, 1);
gpio_set_level(negative_2, 1);
gpio_set_level(negative_3, 1);
gpio_set_level(negative_4, 1);
gpio_set_level(negative_5, 1);
gpio_set_level(negative_6, 1);
gpio_set_level(negative_7, 1);
gpio_set_level(negative_8, 1);
gpio_set_level(negative_9, 1);
gpio_set_level(negative_10, 1);
gpio_set_level(negative_11, 1);
gpio_set_level(negative_12, 1);
gpio_set_level(negative_13, 1);
gpio_set_level(negative_14, 1);
gpio_set_level(negative_15, 1);
gpio_set_level(negative_16, 1);}
void user_led_on(uint8_t positive_io)
{
gpio_set_level(positive_io, 1);
}void user_led_off(uint8_t positive_io)
{
gpio_set_level(positive_io, 0);
}void user_led_all_off(void)
{
gpio_set_level(positive_A, 0);
gpio_set_level(positive_B, 0);
gpio_set_level(positive_C, 0);
gpio_set_level(positive_D, 0);
gpio_set_level(positive_E, 0);
gpio_set_level(positive_F, 0);
gpio_set_level(positive_G, 0);
gpio_set_level(positive_H, 0);gpio_set_level(negative_1, 1);
gpio_set_level(negative_2, 1);
gpio_set_level(negative_3, 1);
gpio_set_level(negative_4, 1);
gpio_set_level(negative_5, 1);
gpio_set_level(negative_6, 1);
gpio_set_level(negative_7, 1);
gpio_set_level(negative_8, 1);
gpio_set_level(negative_9, 1);
gpio_set_level(negative_10, 1);
gpio_set_level(negative_11, 1);
gpio_set_level(negative_12, 1);
gpio_set_level(negative_13, 1);
gpio_set_level(negative_14, 1);
gpio_set_level(negative_15, 1);
gpio_set_level(negative_16, 1);}
3.8字段码驱动,完成数字0~9的显示
/8字段码驱动****/
void display_driver_0() //驱动层,显示数字0
{
user_led_on(positive_A);
user_led_on(positive_B);
user_led_on(positive_C);
user_led_on(positive_D);
user_led_on(positive_E);
user_led_on(positive_F);
}void display_driver_1() //驱动层,显示数字1
{
user_led_on(positive_B);
user_led_on(positive_C);
}void display_driver_2() //驱动层,显示数字2
{
user_led_on(positive_A);
user_led_on(positive_B);
user_led_on(positive_G);
user_led_on(positive_E);
user_led_on(positive_D);
}void display_driver_3() //驱动层,显示数字3
{
user_led_on(positive_A);
user_led_on(positive_B);
user_led_on(positive_G);
user_led_on(positive_C);
user_led_on(positive_D);
}void display_driver_4() //驱动层,显示数字4
{
user_led_on(positive_F);
user_led_on(positive_G);
user_led_on(positive_B);
user_led_on(positive_C);
}void display_driver_5() //驱动层,显示数字5
{
user_led_on(positive_A);
user_led_on(positive_F);
user_led_on(positive_G);
user_led_on(positive_C);
user_led_on(positive_D);
}void display_driver_6() //驱动层,显示数字6
{
user_led_on(positive_A);
user_led_on(positive_F);
user_led_on(positive_G);
user_led_on(positive_C);
user_led_on(positive_D);
user_led_on(positive_E);
}void display_driver_7() //驱动层,显示数字7
{
user_led_on(positive_A);
user_led_on(positive_B);
user_led_on(positive_C);
}void display_driver_8() //驱动层,显示数字8
{
user_led_on(positive_A);
user_led_on(positive_B);
user_led_on(positive_C);
user_led_on(positive_D);
user_led_on(positive_E);
user_led_on(positive_F);
user_led_on(positive_G);
}void display_driver_9() //驱动层,显示数字9
{
user_led_on(positive_A);
user_led_on(positive_F);
user_led_on(positive_G);
user_led_on(positive_B);
user_led_on(positive_C);
}void display_mid_num(uint8_t display_number) //中间层,显示数字,display_number:要显示的数字,个位数0~9
{
switch(display_number)
{
case 0:
display_driver_0();
break;
case 1:
display_driver_1();
break;
case 2:
display_driver_2();
break;
case 3:
display_driver_3();
break;
case 4:
display_driver_4();
break;
case 5:
display_driver_5();
break;
case 6:
display_driver_6();
break;
case 7:
display_driver_7();
break;
case 8:
display_driver_8();
break;
case 9:
display_driver_9();
break;
}ets_delay_us(user_delay_time_us); //保持时间,可以用其它时间合适任务来替代
user_led_all_off(); //关,准备显示下一位}
4.按每根阴极线为一个单元,动态刷新数据
/段码显示APP****/
void user_display_temperature(void) //显示温度,全局变量display_temperature_88传递温度值
{
uint8_t temp_High;//温度高位数
uint8_t temp_Low;//温度低位数if(display_temperature_sw)
{
if(display_temperature_88>=10&&display_temperature_88<=99)
{
temp_High=display_temperature_88/10;
temp_Low=display_temperature_88%10;
}
else
{
temp_High=0;
temp_Low=display_temperature_88;
}
gpio_set_level(negative_1, 0); //开高位显示,line1
display_mid_num(temp_High);
gpio_set_level(negative_2, 0); //开低位显示,line2
display_mid_num(temp_Low);
}}
void user_display_capacitance(void) //显示容量,全局变量display_capacitance_88传递容量值
{
uint8_t Cap_High;//温度高位数
uint8_t Cap_Low;//温度低位数if(display_capacitance_sw)
{
if(display_capacitance_88>=10&&display_capacitance_88<=99)
{
Cap_High=display_capacitance_88/10;
Cap_Low=display_capacitance_88%10;
}
else
{
Cap_High=0;
Cap_Low=display_capacitance_88;
}
gpio_set_level(negative_4, 0); //开高位显示,line4
display_mid_num(Cap_High);
gpio_set_level(negative_5, 0); //开低位显示,line5
display_mid_num(Cap_Low);
}}
void user_display_time(void) //显示时间,全局变量display_time_88传递时间值
{
uint8_t time_High;//温度高位数
uint8_t time_Low;//温度低位数if(display_time_sw)
{
if(display_time_88>=10&&display_time_88<=99)
{
time_High=display_time_88/10;
time_Low=display_time_88%10;
}
else
{
time_High=0;
time_Low=display_time_88;
}
gpio_set_level(negative_6, 0); //开高位显示,line6
display_mid_num(time_High);
gpio_set_level(negative_7, 0); //开低位显示,line7
display_mid_num(time_Low);
}}
void user_display_line8(void) //阴极8线显示,变量line8_sw控制火焰图标的显示,0=不显示,1=显示
{if(line8_sw)
{
display_fire_num++;
switch(display_fire_num)
{
case 4:
gpio_set_level(positive_H, 1);
break;
case 8:
gpio_set_level(positive_F, 1);
gpio_set_level(positive_G, 1);
break;
}
if(display_fire_num>=12) //计数循环
{
display_fire_num=0;
}
}
gpio_set_level(positive_A, 1);
gpio_set_level(positive_B, 1);
gpio_set_level(positive_C, 1);
gpio_set_level(positive_D, 1);
gpio_set_level(positive_E, 1); //开LOGO
gpio_set_level(negative_8, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();}
void user_display_line9(void) //阴极9线显示,变量line9_sw控制风扇图标的显示,0=不显示,1=显示
{if(line9_sw)
{
display_fan_num++;
switch(display_fan_num)
{
case 1:
gpio_set_level(positive_A, 1);
break;
case 2:
gpio_set_level(positive_B, 1);
break;
case 3:
gpio_set_level(positive_C, 1);
break;
case 4:
gpio_set_level(positive_D, 1);
break;
case 5:
gpio_set_level(positive_E, 1);
break;
case 6:
gpio_set_level(positive_F, 1);
break;
}
if(display_fan_num>=6) //计数循环
{
display_fan_num=0;
}
}
gpio_set_level(positive_G, 1); //开"'C"
gpio_set_level(positive_H, 1); //"变升"
gpio_set_level(negative_9, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();}
void user_display_line10(void) //阴极10线显示,变量line10_water花洒图标,0=不显示,1=显示,变量line10_cap控制容量的,0=不显示,1=8L,2=10L,3=12L
{if(line10_water_sw)
{
gpio_set_level(positive_A, 1); //开"花洒"
display_water_num++;
switch(display_water_num)
{
case 3:
gpio_set_level(positive_B, 1);
break;
case 6:
gpio_set_level(positive_C, 1);
break;
case 9:
gpio_set_level(positive_D, 1);
break;
}
if(display_water_num>=9) //计数循环
{
display_water_num=0;
}
}
if(line10_cap)
{
switch(line10_cap)
{
case 1:
gpio_set_level(positive_G, 1);
break;
case 2:
gpio_set_level(positive_F, 1);
break;
case 3:
gpio_set_level(positive_E, 1);
break;
}
}
gpio_set_level(positive_H, 1); //"L"
gpio_set_level(negative_10, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();}
void user_display_decorate(void) //阴极11、12线显示,变量decorate_sw控制装饰条,0=不显示,1=显示
{if(decorate_sw)
{
gpio_set_level(positive_A, 1);
gpio_set_level(positive_B, 1);
gpio_set_level(positive_C, 1);
gpio_set_level(positive_D, 1);
gpio_set_level(positive_E, 1);
gpio_set_level(positive_F, 1);
gpio_set_level(positive_G, 1);
gpio_set_level(positive_H, 1);
gpio_set_level(negative_11, 0);
gpio_set_level(negative_12, 0);
gpio_set_level(negative_13, 0);
gpio_set_level(negative_14, 0);
gpio_set_level(negative_15, 0);
gpio_set_level(negative_16, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();
}}
void user_display_lineH(void) //阳极H线显示,变量lineH_sw控制装饰条,0=不显示,1=显示
{if(lineH_sw)
{
gpio_set_level(positive_H, 1);
gpio_set_level(negative_1, 0);
gpio_set_level(negative_2, 0);
gpio_set_level(negative_3, 0);
gpio_set_level(negative_4, 0);
gpio_set_level(negative_5, 0);
gpio_set_level(negative_6, 0);
gpio_set_level(negative_7, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();
}}
void user_display_line13() //阴极13线显示,变量line13_sw控制显示时间还是故障代码,0=关闭,1=时间,2=故障代码
{if(line13_sw)
{
switch(line13_sw)
{
case 1:
gpio_set_level(positive_G, 1); //"M"
gpio_set_level(positive_C, 1);
gpio_set_level(positive_D, 1); //"时 间"
break;
case 2:
gpio_set_level(positive_E, 1);
gpio_set_level(positive_F, 1); //"故障代码"
break;
}
}
gpio_set_level(positive_A, 1);
gpio_set_level(positive_B, 1); //"浴缸注水"
gpio_set_level(negative_13, 0);
ets_delay_us(user_delay_time_us);
user_led_all_off();}
5.至此,屏的驱动编写完成,接下来是建立一个定时器任务,这个代码直接用官方例程即可。
/定时器模块***************/
#define TIMER_DIVIDER 16 // Hardware timer clock divider
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
#define TIMER_INTERVAL0_SEC (3.4179) // sample test interval for the first timer
#define TEST_WITHOUT_RELOAD 0 // testing will be done without auto reload
#define TEST_WITH_RELOAD 1 // testing will be done with auto reload/*
• A sample structure to pass events
• from the timer interrupt handler to the main program.
*/
typedef struct {
int type; // the type of timer’s event
int timer_group;
int timer_idx;
uint64_t timer_counter_value;
} timer_event_t;xQueueHandle timer_queue;
/*• Timer group0 ISR handler
•
*/
void IRAM_ATTR timer_group0_isr(void *para)
{
timer_spinlock_take(TIMER_GROUP_0);
int timer_idx = (int) para;/* Retrieve the interrupt status and the counter value
from the timer that reported the interrupt */
uint32_t timer_intr = timer_group_get_intr_status_in_isr(TIMER_GROUP_0);
uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(TIMER_GROUP_0, timer_idx);
/* Prepare basic event data
that will be then sent back to the main program task */
timer_event_t evt;
evt.timer_group = 0;
evt.timer_idx = timer_idx;
evt.timer_counter_value = timer_counter_value;
/* Clear the interrupt
and update the alarm time for the timer with without reload */
if (timer_intr & TIMER_INTR_T0) {
evt.type = TEST_WITHOUT_RELOAD;
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE);
timer_group_set_alarm_value_in_isr(TIMER_GROUP_0, timer_idx, timer_counter_value);
} else if (timer_intr & TIMER_INTR_T1) {
evt.type = TEST_WITH_RELOAD;
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_1);
} else {
evt.type = -1; // not supported even type
}
/* After the alarm has been triggered
we need enable it again, so it is triggered the next time */
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx);
/* Now just send the event data back to the main program task */
xQueueSendFromISR(timer_queue, &evt, NULL);
timer_spinlock_give(TIMER_GROUP_0);}
/*
• Initialize selected timer of the timer group 0
/
void user_tg0_timer_init(int timer_idx,bool auto_reload, double timer_interval_sec)
{
/ Select and initialize basic parameters of the timer */
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.counter_en = TIMER_PAUSE,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = auto_reload,
}; // default clock source is APB
timer_init(TIMER_GROUP_0, timer_idx, &config);
/* Timer’s counter will initially start from value below.
Also, if auto_reload is set, this value will be automatically reload on alarm */
timer_set_counter_value(TIMER_GROUP_0, timer_idx, 0x00000000ULL);
/* Configure the alarm value and the interrupt on alarm. */
timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE);
timer_enable_intr(TIMER_GROUP_0, timer_idx);
timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
(void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
timer_start(TIMER_GROUP_0, timer_idx);
}/*
• 定时刷屏
*/
void user_timer_evt_task(void *arg)
{
while (1)
{
timer_event_t evt;
xQueueReceive(timer_queue, &evt, portMAX_DELAY);// printf("-------- TASK TIME --------\n");
/刷数码管*/
user_display_temperature();
user_display_capacitance();
user_display_time();
/按阴极线刷图标*/
user_display_line8();
user_display_line9();
user_display_line10();
user_display_lineH();
user_display_line13();
user_display_decorate();
}
}/*
• 定时器刷屏函数,
• 功能:配置定时器,开定时器任务,刷屏
• 参数:timer_sec,定时器任务运行间隔时间
*/
void user_display_app(double timer_ms)
{
user_led_init(); //配置GPIO
/配置和启用定时器任务*/
timer_queue = xQueueCreate(10, sizeof(timer_event_t));
user_tg0_timer_init(TIMER_1, TEST_WITH_RELOAD, timer_ms/1000);
xTaskCreate(user_timer_evt_task, “user_timer_evt_task”, 2048, NULL, 5, NULL);
}
- 6.user_display.C的内容编写完毕,user_display.h比较简单,主要是声明全局变量和外部函数。
• #ifndef __time_H
#define __time_H#define OFF 0
#define ON 1extern uint8_t display_temperature_88;
extern uint8_t display_capacitance_88;
extern uint8_t display_time_88;
extern uint8_t display_temperature_sw;
extern uint8_t display_capacitance_sw;
extern uint8_t display_time_sw;
extern uint8_t line8_sw;
extern uint8_t line9_sw;
extern uint8_t line10_water_sw;
extern uint8_t decorate_sw;
extern uint8_t lineH_sw;
extern uint8_t line13_sw;
extern uint8_t line10_cap;void user_display_app(double timer_sec);
#endif
7.在main.C里面,运行一次user_display_app()即可启动刷屏,用户应用程序user_app()给全局变量赋值可控制显示内容,用户不需要深入了解显示屏的运行,专心做用户逻辑。
#include <stdio.h>
#include “freertos/FreeRTOS.h”
#include “freertos/task.h”
#include “freertos/queue.h”
#include “driver/timer.h”
#include “driver/gpio.h”
#include “user_display.h”#define TIMER_INTERVAL1_ms 20 // 刷屏时间,ms
static uint8_t display_time_num=0;//显示计数器
void user_app() //demo,每隔2秒温度+1,容量+1,时间+1,用户可在此函数里通过对显示全局变量进行赋值来控制显示内容
{
/显示buff
display_temperature_sw=ON; //温度显示开关
display_capacitance_sw=ON;//容量显示开关
display_time_sw=ON;//时间显示开关
line8_sw=ON;//阴极线8显示控制开关
line9_sw=ON;//阴极线9显示控制开关
line10_water_sw=ON;//阴极线10花洒显示控制开关
decorate_sw=ON;//阴极线11、12装饰条显示控制开关
lineH_sw=ON;//阳极线H显示控制开关
line13_sw=ON;//阴极线13显示控制开关,0=关闭,1=时间,2=故障代码display_temperature_88=0; //温度数字
display_capacitance_88=0; //容量数字
display_time_88=0; //时间数字**********************************/
display_time_num++;
if(display_time_num>=101)
{
display_time_num=0;
}
if(display_time_num/100)
{
display_temperature_88++; //温度+1
if(display_temperature_88>99)
{
display_temperature_88=0;
}
display_capacitance_88++; //容量+1
if(display_capacitance_88>12)
{
display_capacitance_88=0;
}
display_time_88++; //时间+1
if(display_time_88>60)
{
display_time_88=0;
}
}
vTaskDelay(20 / portTICK_PERIOD_MS); //每隔20ms刷新一次显示数据,所以,应用不能刷得太快}
void app_main(void)
{
user_display_app(TIMER_INTERVAL1_ms); //刷屏函数,至少运行一次即可while(1)
{
user_app(); //用户应用函数
}}
三、程序优化
显示函数里LED点亮需要保持一定时间,大致在600us~1ms,DEMO是直接采用延迟函数来保持。用户可以在延迟函数里插入一些应用,例如ADC采样,按键扫描,数据发送等等。
调试时,可以修改以下2个时间,获得最佳的显示效果
#define user_delay_time_us 800 //LED保持时间
#define TIMER_INTERVAL1_ms 20 // 刷屏时间,ms