一、基础理论

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); //开高位显示,line1display_mid_num(temp_High);gpio_set_level(negative_2, 0); //开低位显示,line2display_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); //开高位显示,line4display_mid_num(Cap_High);gpio_set_level(negative_5, 0); //开低位显示,line5display_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); //开高位显示,line6display_mid_num(time_High);gpio_set_level(negative_7, 0); //开低位显示,line7display_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); //开LOGOgpio_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 valuefrom 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 datathat 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 interruptand 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 triggeredwe 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 1

extern 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++;  //温度+1if(display_temperature_88>99){display_temperature_88=0;}display_capacitance_88++;  //容量+1if(display_capacitance_88>12){display_capacitance_88=0;}display_time_88++;  //时间+1if(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

启明云端分享|干货来了,怎么用ESP32-S2驱动断码屏呢?更多干货欢迎关注启明云端CSDN技术社区!相关推荐

  1. 启明云端分享| 2.4寸磁编码旋钮屏

    提示:启明云端从2013年起就作为Espressif(乐鑫科技)大中华区合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程.同时也用心推出了基于乐鑫的相关应用方案!希望你 ...

  2. 启明云端分享| 2.4寸磁编码旋钮方案智能屏

    提示:启明云端是一家集物联网WIFI.蓝牙.智慧屏产品及解决方案提供商,公司为客户提供完善的ODM/OEM服务,方案已服务全球超过1000+企业,累积帮助客户完成100+以上带彩屏的智能产品的应用及落 ...

  3. 启明云端分享|ESP32摄像头应用方案常遇到的问题

    提示:启明云端从2013年起就作为Espressif(乐鑫科技)大中华区合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用心整理了乐鑫新产品.新 ...

  4. 启明云端分享| 家电应用 串口屏选型推荐

    提示:近日小明做了一份针对90后人群的家电选用调查问卷,90%的人都选择了价格不要太贵.功能要强大点.操控智能,颜值是首选.不可否认,90后群体逐步成为家电消费市场的有生力量,他们对家电的需求代表着年 ...

  5. 启明云端分享|盘点ESP8684开发板有哪些功能

    提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...

  6. 启明云端分享:高性价比ESP32-S3驱屏应用于洗衣机的方案

    洗衣机在现今生活中已经成了居家旅行必不可少的家用电器,在洗衣机市场的饱和情况下,各大商家开始在洗衣机的功能上寻找新的突破口. 而应用了乐鑫ESP32-S3芯片的新一代驱屏,刚好可以满足用户的体验与需求 ...

  7. 启明云端分享| ESP32-S3 + 480*480分辨率的2.1寸圆屏旋钮方案

    提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...

  8. 启明云端分享| 继ESP32-S3点屏480*480分辨率的2.1寸屏后,目前在8ms平台又发布了480*480分辨率的4寸屏、480*272分辨率的4.3寸屏、800*480分辨率的4.3寸屏SDK

    提示: 作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也 ...

  9. 启明云端分享| ESP32-S3点480*480分辨率的RGB 2.1寸旋钮屏刷新效果到底会怎么样呢

    提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考.同时也用 ...

最新文章

  1. 大开源时代,“仁慈的独裁者”管理模式还走得通吗?
  2. 厦大的计算机博士好考吗,2018双非学姐的厦大考博逆袭之路——本硕求学生涯历程...
  3. Intellij IDEA——创建MyBatis的Mapper.xml模板
  4. C++实现顺序查找(附完整源码)
  5. 基于Linux和MiniGUI的嵌入式系统软件开发指南(六)
  6. 浅谈ASP.NET客户端回调
  7. FileUtils常用方法 - commons-io常用工具类
  8. Linux关于qt缺少xcb问题解决办法
  9. 【demo记录】百度地图获取当前所在城市
  10. [刷题]2017百度之星资格赛 - 度度熊与邪恶大魔王
  11. 【HTML+CSS】页内侧边导航栏 页内导航
  12. Eclipse 安装 Jrebel插件
  13. 爬虫写得好,牢饭吃得早
  14. 关于参加大学生数学竞赛的一点感悟与体会
  15. Rocket MQ(四)Topic,Topic分片和Queue
  16. [算法导论] 最大差值、最小差值
  17. LG 2.2.1 P350安卓系统刷机,问题总结,希望对需要的朋友有助
  18. argparse参数详解--python
  19. SSDP协议编程 upnp设备查找方法
  20. 兔子试毒 #算法学习

热门文章

  1. 【JavaScript】前端开发框架三剑客—AngularJS VS. Backone.js VS.Ember.js
  2. 智能手机系统对进程生命周期的管理
  3. velocity 遍历map
  4. 前端月趋势榜:5 月最热门的 20 个前端开源项目 - 2105
  5. 【大二在读】说说我对“软件工程”的理解
  6. 新人问一般都用哪些 Linux 命令,我把这个扔了过去
  7. mybatis批量插入(insert)和批量更新(update)
  8. spring boot2.x整合redis
  9. reactjs组件实例的三大属性之props使用示例:在函数式组件中使用props
  10. Dockerfile常见指令优化