链接:https://pan.baidu.com/s/1hgyQqoDqDuETEHr_I80M8Q
提取码:e890
已移植好的stm32f407例程下载链接:
https://download.csdn.net/download/mygod2008ok/12315598
#define INCLUDE_xTaskGetCurrentTaskHandle 1
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
// 创建其它任务
vTaskDelete(NULL); //删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
int main(void)
{
xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )128, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )3, //任务优先级
(TaskHandle_t* )0); //任务句柄
vTaskStartScheduler();
/* Infinite loop */
for (;;)
{
}
}
#define FF_USE_MKFS 1
#define FF_USE_LABEL 1
#define FF_CODE_PAGE 437
#define FF_USE_LFN 2
#define FF_LFN_UNICODE 2
#define FF_STRF_ENCODE 3
#define FF_VOLUMES 1
#define FF_FS_REENTRANT 1
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t SemaphoreHandle_t
#include "semphr.h"
#include "queue.h"
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
FF_SYNC_t* sobj /* Pointer to return the created sync object */
)
{
/* Win32 */
// *sobj = CreateMutex(NULL, FALSE, NULL);
// return (int)(*sobj != INVALID_HANDLE_VALUE);
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
*sobj = xSemaphoreCreateMutex();
return (int)(*sobj != NULL);
/* CMSIS-RTOS */
// *sobj = osMutexCreate(&Mutex[vol]);
// return (int)(*sobj != NULL);
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
/* Win32 */
// return (int)CloseHandle(sobj);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
vSemaphoreDelete(sobj);
return 1;
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* Win32 */
// return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
// ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_MUTEXES 1
#include "w25qxx.h"
#include "ff.h"
#define EX_FLASH 0 //外部flash,卷标为1
#define FLASH_SECTOR_SIZE 512
//对于W25Q128
//前12M字节给fatfs用,12M字节后,用于存放字库,字库占用3.09M. 剩余部分,给客户自己用
uint16_t FLASH_SECTOR_COUNT=2048*12; //W25Q1218,前12M字节给FATFS占用
#define FLASH_BLOCK_SIZE 8 //每个BLOCK有8个扇区
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return 0;
}
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
uint8_t res=0;
switch(pdrv)
{
case EX_FLASH://外部flash
W25QXX_Init();
FLASH_SECTOR_COUNT=2048*12;//W25Q1218,前12M字节给FATFS占用
break;
default:
res=1;
}
if(res)return STA_NOINIT;
else return 0; //初始化成功
}
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
uint8_t res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case EX_FLASH://外部flash
for(;count>0;count--)
{
W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res==0x00)return RES_OK;
else return RES_ERROR;
}
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
LBA_t sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
uint8_t res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case EX_FLASH://外部flash
for(;count>0;count--)
{
W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv==EX_FLASH) //外部FLASH
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK; //同步操作
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE; //返回扇区大小,这里为512
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE; //返回块大小,这里为8,
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT; //返回扇区数量
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}else res=RES_ERROR;//其他的不支持
return res;
}
上面的扇区大小为512,这个是fatfs系统的扇区大小,块大小是8,两数相乘刚好是4096,对应flash的1个扇区大小
DWORD get_fattime (void)
{
return 0;
}
uint8_t res=f_mount(&fs,"0:",1); //挂载FLASH.
BYTE work[512];
if(res==0X0D)//FLASH磁盘,FAT文件系统错误,重新格式化FLASH
{
res=f_mkfs("0:",0,work,sizeof(work));//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇
if(res==0)
{
f_setlabel((const TCHAR *)"0:ALIENTEK"); //设置Flash磁盘的名字为:ALIENTEK
NRF_LOG_INFO("set disk name");
}else{NRF_LOG_INFO("format fail");} //格式化失败
}
/* Maximal horizontal and vertical resolution to support by the library.*/
#define LV_HOR_RES_MAX (480)
#define LV_VER_RES_MAX (320)
/* Color depth:
* - 1: 1 byte per pixel
* - 8: RGB233
* - 16: RGB565
* - 32: ARGB8888
*/
#define LV_COLOR_DEPTH 16
/* Swap the 2 bytes of RGB565 color.
* Useful if the display has a 8 bit interface (e.g. SPI)*/
#define LV_COLOR_16_SWAP 0
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
#define LV_ANTIALIAS 1
/*1: Enable the Animations */
#define LV_USE_ANIMATION 1
#define LV_USE_GPU 0
void lv_disp_drv_flush_simple_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
u16 height,width;
u16 i,j;
width=area->x2-area->x1+1; //得到填充的宽度
height=area->y2-area->y1+1; //高度
for(i=0;ix1,area->y1+i); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(j=0;jLCD_RAM=color_p->full;
color_p++;
}
}
lv_disp_flush_ready(disp_drv);
}
//读点函数实现
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
/*Save the state and save the pressed coordinate*/
data->state = tp_dev.sta & TP_PRES_DOWN ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
if(data->state == LV_INDEV_STATE_PR) //触摸屏被按下
{
NRF_LOG_DEBUG("x=%d,y=%d\n",tp_dev.x[0],tp_dev.y[0]);
if((tp_dev.x[0] < LV_HOR_RES_MAX) && (tp_dev.y[0]point.x = last_x;
data->point.y = last_y;
return false; /*Return `false` because we are not buffering and no more data to read*/
}
FATFS fs;
bool my_ready_cb(struct _lv_fs_drv_t * drv)
{
return disk_status(0)==0;
}
lv_fs_res_t my_open_cb(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode)
{
return f_open(file_p, path, mode);
}
lv_fs_res_t my_close_cb(struct _lv_fs_drv_t * drv, void * file_p)
{
return f_close(file_p);
}
lv_fs_res_t my_read_cb(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
return f_read(file_p,buf,btr,br);
}
lv_fs_res_t my_write_cb(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
{
return f_write(file_p,buf,btw,bw);
}
lv_fs_res_t my_seek_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos)
{
return f_lseek(file_p,pos);
}
lv_fs_res_t my_trunc_cb(struct _lv_fs_drv_t * drv, void * file_p)
{
return f_truncate(file_p);
}
lv_fs_res_t my_tell_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
return f_tell((FIL*)file_p);
}
lv_fs_res_t my_size_cb(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * size_p)
{
return f_size((FIL*)file_p);
}
lv_fs_res_t my_rename_cb(struct _lv_fs_drv_t * drv, const char * oldname, const char * newname)
{
return f_rename(oldname,newname);
}
lv_fs_res_t my_free_space_cb(struct _lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p)
{
lv_fs_res_t result;
uint32_t fre_clust = 0;
uint32_t fre_sect = 0;
uint32_t tot_sect = 0;
FATFS *fs1 = &fs;
result = f_getfree((const TCHAR*)&drv->letter,&fre_clust,&fs1);
if(result == 0)
{
tot_sect = (fs1->n_fatent-2)*fs1->csize; // total sector
fre_sect = fre_clust * fs1->csize;
#if FF_MAX_SS != 512
tot_sect*=fs1->ssize/512;
tot_sect*=fs1->ssize/512;
#endif
*total_p = tot_sect >> 1; // unit in kb
*free_p = fre_sect >> 1; // unit in kb
}
return result;
}
lv_fs_res_t my_dir_open_cb(struct _lv_fs_drv_t * drv, void * rddir_p, const char * path)
{
return f_opendir(rddir_p,path);
}
lv_fs_res_t my_dir_read_cb(struct _lv_fs_drv_t * drv, void * rddir_p, char * fn)
{
FILINFO info;
lv_fs_res_t result = f_readdir(rddir_p,&info);
return result;
}
lv_fs_res_t my_dir_close_cb(struct _lv_fs_drv_t * drv, void * rddir_p)
{
return f_closedir(rddir_p);
}
//閬嶅巻鏂囦欢
//path:璺緞
//杩斿洖鍊?鎵ц缁撴灉
uint8_t mf_scan_files(uint8_t * path,char *file_res,char *dir_res)
{
FRESULT res;
char *fn; /* This function is assuming non-Unicode cfg. */
DIR dir;
FILINFO fileinfo; //鏂囦欢淇℃伅
//#if FF_USE_LFN
// fileinfo.fsize = FF_MAX_LFN * 2 + 1;
// fileinfo.lfname = malloc(SRAMIN,fileinfo.lfsize);
//#endif
char *p = file_res;
res = f_opendir(&dir,(const TCHAR*)path); //鎵撳紑涓€涓洰褰?
if (res == FR_OK)
{
// NRF_LOG_DEBUG("\r\n");
while(1)
{
res = f_readdir(&dir, &fileinfo); //璇诲彇鐩綍涓嬬殑涓€涓枃浠?
if (res != FR_OK || fileinfo.fname[0] == 0) break; //閿欒浜?鍒版湯灏句簡,閫€鍑?
//if (fileinfo.fname[0] == '.') continue; //蹇界暐涓婄骇鐩綍
#if _USE_LFN
fn = *fileinfo.lfname ? fileinfo.lfname : fileinfo.fname;
#else
fn = fileinfo.fname;
#endif
/* It is a file. */
NRF_LOG_DEBUG("attr=%d,%s\r\n",fileinfo.fattrib,fileinfo.fname);//鎵撳嵃鏂囦欢鍚?
if(fileinfo.fattrib == AM_DIR)
{
while(*fn)
{
*dir_res++ = *fn++;
}
*dir_res++ = '\n';
}
while(*fn)
{
*p++ = *fn++;
}
*p++ = '\n';// NRF_LOG_DEBUG("%s/", path);//鎵撳嵃璺緞
}
}
// myfree(SRAMIN,fileinfo.lfname);
return res;
}
/**
* @brief ivgl相关初时化
*/
static void lvgl_config_init(void)
{
//--------------------------lvgl初时化--------------------------------------------------
lv_init();
// 显示缓冲初时化
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10]; /*Declare a buffer for 10 lines*/
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
//===================================================================================================
// 注册显示回调函数
lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.flush_cb = lv_disp_drv_flush_simple_cb; /*Set your driver function*/
disp_drv.buffer = &disp_buf; /*Assign the buffer to the display*/
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
//===============================================================================================
//触摸输入注册
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv); /*Descriptor of a input device driver*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
//------file system------------------------------
lv_fs_drv_t drv;
lv_fs_drv_init(&drv);
drv.letter = '0';
drv.file_size = sizeof(FIL);
drv.rddir_size = sizeof(DIR);
drv.ready_cb = my_ready_cb;
drv.open_cb = my_open_cb;
drv.close_cb = my_close_cb;
drv.read_cb = my_read_cb;
drv.write_cb = my_write_cb;
drv.seek_cb = my_seek_cb;
drv.tell_cb = my_tell_cb;
drv.trunc_cb = my_trunc_cb;
drv.size_cb = my_size_cb;
drv.rename_cb = my_rename_cb;
drv.dir_open_cb = my_dir_open_cb;
drv.dir_read_cb = my_dir_read_cb;
drv.dir_close_cb = my_dir_close_cb;
drv.free_space_cb = my_free_space_cb;
// drv.user_data = my_user_data;
lv_fs_drv_register(&drv);
}
int main(void)
{
RTT_INIT();
delay_init();
TFTLCD_Init(); //初始化LCD FSMC接口
tp_dev.init(); //触摸屏初始化
uint8_t res=f_mount(&fs,"0:",1); //挂载FLASH.
BYTE work[512];
if(res==0X0D)//FLASH磁盘,FAT文件系统错误,重新格式化FLASH
{
res=f_mkfs("0:",0,work,sizeof(work));//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇
if(res==0)
{
f_setlabel((const TCHAR *)"0:ALIENTEK"); //设置Flash磁盘的名字为:ALIENTEK
NRF_LOG_INFO("set disk name");
}else{NRF_LOG_INFO("format fail");} //格式化失败
}
res = f_open(&fil, "0:touch.txt", FA_OPEN_ALWAYS|FA_READ);
if (res==0)
{
memset(work,0x0,50);
uint32_t bw1;
res = f_read(&fil,work,1,&bw1);
if (work[0] != 'o')
{
LCD_Clear(WHITE); //清屏
TP_Adjust(); //屏幕校准
TP_Save_Adjdata();
Load_Drow_Dialog();
f_close(&fil);
res = f_open(&fil,"0:touch.txt", FA_CREATE_ALWAYS|FA_WRITE);
if(res==0)
{
work[0] = 'o';
work[1] = 0;
f_write(&fil,work,1,&bw1);
}
}
}
f_close(&fil);
Load_Drow_Dialog();
lvgl_config_init();
lv_log_register_print_cb(my_printf);
lvgl_demo();
// lv_test_theme_1(lv_theme_nemo_init(210, NULL));
xTaskCreate((TaskFunction_t )start_task, //任务函数
(const char* )"start_task", //任务名称
(uint16_t )128, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )3, //任务优先级
(TaskHandle_t* )0); //任务句柄
vTaskStartScheduler();
/* Infinite loop */
for (;;)
{
}
}
static lv_obj_t * mbox;
static void mbox_event_handler(lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_VALUE_CHANGED) {
NRF_LOG_DEBUG("Button: %s\n", lv_mbox_get_active_btn_text(obj));
lv_obj_del_async(lv_obj_get_parent(obj));
}
}
void event_handler(struct _lv_obj_t * obj, lv_event_t event)
{
if(event == LV_EVENT_PRESSED)
{
static const char* btns[] = { "OK","" };
lv_obj_t * back = lv_obj_create(lv_scr_act(),NULL);
lv_obj_set_size(back,LV_HOR_RES_MAX,LV_VER_RES_MAX);
static lv_style_t lab_style;
lv_style_copy(&lab_style,&lv_style_plain);
lab_style.body.main_color = LV_COLOR_WHITE;
lab_style.body.opa = LV_OPA_100;
lv_obj_set_style(back,&lab_style);
mbox = lv_mbox_create(back, NULL);
char file_str[64]={0};
char dir_str[64] = {0};
mf_scan_files((uint8_t*)"0:",file_str,dir_str);
NRF_LOG_INFO("file=%s dir=%s",file_str,dir_str);
strcat(file_str,dir_str);
lv_mbox_set_text(mbox, file_str);
lv_mbox_add_btns(mbox, btns);
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
static lv_style_t style_box;
lv_style_copy(&style_box,&lv_style_plain);
style_box.text.color = LV_COLOR_RED;
style_box.body.main_color = lv_color_hex3(0xf0f);
style_box.body.grad_color = lv_color_hex3(0xf0f);
lv_mbox_set_style(mbox,LV_MBOX_STYLE_BTN_PR,&style_box);
lv_obj_set_event_cb(mbox, mbox_event_handler);
}
}
void lvgl_demo(void)
{
////建立一按钮
lv_obj_t * label;
lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
lv_obj_set_event_cb(btn1, event_handler);//按钮按下回调函数,可以不用设置,可以多按钮同一个回调函数
lv_obj_set_size(btn1,80,30);
lv_obj_align(btn1, NULL, LV_ALIGN_IN_TOP_MID, 0, 40);
label = lv_label_create(btn1, NULL);
lv_label_set_text(label, "OK");
lv_obj_t *slider = lv_slider_create(lv_scr_act(),NULL);
lv_obj_set_size(slider,160,45);
lv_obj_align(slider,btn1,LV_ALIGN_OUT_BOTTOM_MID,0,10);
lv_slider_set_range(slider,0,100);
lv_slider_set_value(slider,60,LV_ANIM_ON);
/*Create a style for the line meter*/
static lv_style_t style_lmeter;
lv_style_copy(&style_lmeter, &lv_style_pretty_color);
style_lmeter.line.width = 3;
style_lmeter.line.color = LV_COLOR_RED;
style_lmeter.body.main_color = lv_color_hex(0x91bfed);
style_lmeter.body.grad_color = lv_color_hex(0x04386c);
style_lmeter.body.padding.left = 8;
/*Create a line meter*/
lv_obj_t* lmeter;
lmeter = lv_lmeter_create(lv_scr_act(), NULL);
lv_lmeter_set_range(lmeter, 0, 60);
lv_lmeter_set_value(lmeter, 10);
lv_lmeter_set_scale(lmeter, 360, 15);
lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN,&style_lmeter);
lv_obj_set_size(lmeter, 80, 80);
lv_obj_align(lmeter, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
lv_task_t* t = lv_task_create(line_meter_task, 200, LV_TASK_PRIO_MID, lmeter);
lv_task_ready(t);
LV_FONT_DECLARE(myFont)
lv_obj_t* label2 = lv_label_create(lv_scr_act(), NULL);
lv_label_set_long_mode(label2, LV_LABEL_LONG_SROLL_CIRC);
static lv_style_t red_style;
lv_style_copy(&red_style,&lv_style_plain);
red_style.text.color = LV_COLOR_RED;
red_style.text.font = &myFont;
lv_label_set_style(label2,LV_LABEL_STYLE_MAIN,&red_style);
lv_obj_set_size(label2, 178,50);
lv_label_set_text(label2,"闀块鐮存氮浼氭湁鏃剁洿鎸備簯甯嗘祹娌ф捣");
lv_obj_align(label2, lmeter, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
}