Funpack4-3 - 基于LVGL的双通道ADC数值显示
该项目使用了MAX32655 FTHR与LVGL,实现了基于LVGL的双通道ADC数值显示的设计,它的主要功能为:双通道ADC连续测量,相关结果动态展示在TFT屏幕上。相关的屏幕显示使用LVGL。
标签
Funpack活动
ADC
lvgl
MAX32655
Funpack S4 #3
littlestudent
更新2026-01-29
19

项目背景:

本次参加Funpack活动选择的是任务1:使用MAX32655FTHR板卡搭配任意彩色LCD屏幕,移植LVGL,设计一个显示两个ADC通道数值的app。

主要任务分解:

  • TFT屏幕的驱动。屏幕是ili9341 320*240,可以直接采用MAX32655的SPI接口进行驱动

image.png

  • LVGL的移植,有很多的参考资料。重点是\lvgl\porting里面的.c文件需要适配当前的TFT屏幕。

image.png

  • ADC的驱动,这部分可以参考官方提供的demo。

image.png

考虑到杜邦线链接不稳定,重用了之前给MAX78000设计的扩展板。这两个板子的布局完全一致,只需要更改相关引脚即可。

image.png

主控板卡介绍:

MAX32655FTHR 是一款快速开发平台,可帮助工程师使用MAX32655 Arm© Cortex®-M4F和Bluetooth® 5.2低功耗(LE)快速实施超低功耗无线解决方案。该电路板还包括MAX20303 PMIC以实现电池和电源管理。0.9 x 2.6英寸小尺寸双排接头与Adafruit Feather Wing外设扩展板兼容。该电路板包括各种外设,如数字麦克风、低功耗立体声音频编解码器、128MB QSPI闪存、micro SD卡连接器、RGB指示器LED和按钮。

特性:

  • 超低功耗无线微控制器
    • 内置100MHz振荡器
    • 具有7.3728MHz系统时钟选项的灵活低功耗模式
    • 512KB闪存和128KB SRAM
      • 一个32KB SRAM存储区上提供可选ECC
    • 16KB指令缓存
  • 蓝牙5.2 LE无线电
    • 专用的超低功耗32位RISC-V协处理器,可减轻时序关键型蓝牙处理负荷
    • 提供完全开源的蓝牙5.2协议栈
    • 支持医疗身体区域网络(MBAN)和Mesh
    • 高吞吐量(2Mbps)模式
    • 远程(125kbps和500kbps)模式
    • Rx灵敏度:-97dBm;Tx功率:+5.5dBm
    • 单端天线连接(50Ω)
  • 提供电源管理充分延长电池寿命
    • 电源电压范围:2.0V至3.6V
    • 集成SIMO功率调节器
    • 3.0V时的有源电流为12.9μA/MHz
    • 对于32KB,3.0V时的保持电流为1.53μA
    • 低功耗模式下可选择SRAM数据保留功能+RTC
  • 多个外设,用于实施系统控制
    • 多达两个高速SPI控制器/目标
    • 多达三个I2C控制器/目标
    • 多达四个UART
    • 一个I2S控制器/目标
    • 多达8路输入、10位Σ-Δ ADC 7.8ksps
    • 多达四个微功耗比较器
    • 定时器:四个32位、两个低功耗、一个看门狗、一个低功耗看门狗
    • 1-Wire®控制器
    • 多达四个脉冲序列(PWM)引擎
    • 带唤醒定时器的RTC
    • 多达52个GPIO
  • 安全性和完整性
    • 可选安全引导
    • TRNG Seed发生器
    • AES 128/192/256硬件加速引擎

系统框图:

用到的硬件模块:ADC与SPI。

image.png

系统实物图:


软件流程图:

image.png

项目重点:

一、ADC参考电压问题:

ADC的内部参考电压是1.22V,参考:https://www.analog.com/media/en/technical-documentation/data-sheets/max32655.pdf

image.png


二、系统上电后需要进行延迟:

MXC_Delay(200000);

/* Enable cache */

MXC_ICC_Enable(MXC_ICC0);


三、TFT屏幕需要单独处理RESET, BACKLIGHT:

mxc_gpio_cfg_t tft_reset_pin = { MXC_GPIO1, MXC_GPIO_PIN_8,
MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH };

mxc_gpio_cfg_t tft_blen_pin = { MXC_GPIO0, MXC_GPIO_PIN_25,
MXC_GPIO_FUNC_OUT, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH };

MXC_TFT_Init(MXC_SPI1, 0, &tft_reset_pin, &tft_blen_pin);


四、LVGL相关:

4.1 LVGL小组件:

void LvglTest(void) {

lv_obj_t *label1 = lv_label_create(lv_scr_act());
lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_label_set_recolor(label1, true);
lv_label_set_text(label1, "#0000ff Funpack# MAX32655 LVGL #");
lv_obj_set_width(label1, 240);
lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);
lv_obj_align(label1, LV_ALIGN_TOP_MID, 0, 20);

//Bar in the middle
bar = lv_bar_create(lv_scr_act());
lv_obj_add_event_cb(bar, event_cb, LV_EVENT_DRAW_PART_END, NULL);
lv_obj_set_size(bar, 200, 20);
lv_bar_set_range(bar, 0, 1023);
lv_obj_center(bar);

// Bar1 in the bottom mid
static lv_style_t style_indic;
lv_style_init(&style_indic);
lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);
lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_RED));
lv_style_set_bg_grad_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_bg_grad_dir(&style_indic, LV_GRAD_DIR_VER);

bar1 = lv_bar_create(lv_scr_act());
lv_obj_add_style(bar1, &style_indic, LV_PART_INDICATOR);
lv_obj_add_event_cb(bar1, myBar_event_cb, LV_EVENT_DRAW_PART_END, NULL);
lv_obj_set_size(bar1, 200, 20);

//lv_obj_center(bar1);

lv_obj_align(bar1, LV_ALIGN_BOTTOM_MID, 0, -50);
lv_bar_set_range(bar1, 0, 1023);
lv_bar_set_value(bar1, 70, LV_ANIM_OFF);

//labels for the two bar:
lv_obj_t *label_bar = lv_label_create(lv_scr_act());
lv_label_set_text(label_bar, "CH0");
lv_obj_align_to(label_bar, bar, LV_ALIGN_OUT_LEFT_MID, -10, 0);

label_bar_phy = lv_label_create(lv_scr_act());
lv_label_set_text(label_bar_phy, "0 V");
lv_obj_align_to(label_bar_phy, bar, LV_ALIGN_OUT_RIGHT_MID, 5, 0);

lv_obj_t *label_bar1 = lv_label_create(lv_scr_act());
lv_label_set_text(label_bar1, "CH1");
lv_obj_align_to(label_bar1, bar1, LV_ALIGN_OUT_LEFT_MID, -10, 0);

label_bar1_phy = lv_label_create(lv_scr_act());
lv_label_set_text(label_bar1_phy, "0 V");
lv_obj_align_to(label_bar1_phy, bar1, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
lv_timer_create(add_data, 10, NULL);
}

4.2 LVGL的滴答处理:

void SysTick_Handler(void)

{

lv_tick_inc(1);

SysTicktempCnt++;

if(SysTicktempCnt%1000 == 0){

LED_Toggle(LED_RED);

}

}

4.3 lvgl动态更新数据的call back:

static void add_data(lv_timer_t * timer)
{
static float bar_phy, bar1_phy;
static char tepval[10];

LV_UNUSED(timer);
lv_bar_set_value(bar, adc_ch0_val, LV_ANIM_OFF);
lv_bar_set_value(bar1, adc_ch1_val, LV_ANIM_OFF);

bar_phy = adc_ch0_val*1.22/1023;
sprintf(tepval, "%4.3f V", bar_phy);
lv_label_set_text(label_bar_phy, tepval);

bar1_phy = adc_ch1_val*1.22/1023;
sprintf(tepval, "%4.3f V", bar1_phy);
lv_label_set_text(label_bar1_phy, tepval);
}


实物展示:

通道CH0电阻分压网络,通道CH1接VCC。通道CH0成功采集电压,与万用表测量非常接近。

image.png


通道CH0接地,通道CH1接电阻分压网络:

image.png


总结:

非常感谢硬禾学堂和得捷电子提供的funpack平台,学习到了MAX32655单片机如何硬件驱动TFT屏幕,如何使用LVGL。和一些简单的MAKEFILE知识。双通道ADC值动态展示在屏幕上,但是还存在一定的不足,比如刷新屏幕较慢。目前还在尝试如何用DMA来改善刷屏效果。

祝funpack活动越办越好!


附件下载
Example_FthrTft.zip
团队介绍
LITTLE STUDENT
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号