目标:在屏幕上显示一个数字,并用定时器动态修改其显示值,效果如下图(为了操作步骤尽可能简单,导致效果有点丑)
操作步骤:
- 开启定时器
- Legato字体管理
- 在屏幕上显示hello world
- 添加代码实现数字时钟
使用板子为官方IGAT开发板,以下都是使用例程quickstart,在其工程内进行修改
开启定时器
- 在harmony编辑界面左下角框内找到TC1,将其拖入中间的主界面内
2. 设置其为1000ms,勾选中断
3. 点击左上角生成代码,harmony启用定时器还是蛮简单的
在harmony的菜单栏点击 Tools -> legato Graphics Composer 进入legato界面
Legato字体管理
点击legato界面左上角 asset -> Fonts 进入字体管理器
1. 添加新字体
字体管理器左上角,那个绿色加号即是添加新字体,点击右边的preview即可预览字体样式。
除了自带的字体文件,也可以添加自己的字体文件。你所添加的每一个字体,都会被转化为数组的形式,生成到工程的代码文件中,并占用你的内存
2. 选择带上指定字符
点击右边的ranges按钮,显示以下界面
Start index32,End index126。含义是将从编号32(空格)到编号126(~)的95个字符(ascii中的所有可显示字符)的取模数据都强制保存到代码中,即使其在legato内没有被用到。当然,你也可以修改这个范围以更好的节省内存。
默认情况下,只有被用到的字符的取模数据才会被编译进程序中。毕竟一个字体包括65535个字符,这么多数据肯定不能全装进单片机里。
我们本节的程序,初始时在屏幕上只显示个hello world,系统会认为我们只用到了helowrd这个字符,为了节省内存就只将这7个字符的取模数据存进代码中,而没有123456789的取模数据,后续我们要在代码中显示数字时就会出错。
3. 字体其他设置
Size:是设置本字体的大小(取模时的大小)。在画布上放置文本时,如果觉得字太小,就得回到这个字体管理器内修改。如果你需要显示多种大小的文本,就要注册多个字体。
Antialiased:抗锯齿,勾选上之后会大幅增加占用的内存,需要在美观与内存占用之间取舍
屏幕上显示个hello world
这是在屏幕上显示文本的通用步骤
1. 进入字符串管理界面
点击菜单栏 asset -> strings
所有要显示的文本,都需要先在字符串管理器内定义。
2. 定义一个字符串hello world
3. 在画布内添加label部件
这里只是将字符串与label绑定到一起,如果在字符串管理器内修改文本的值,画布内也会同步变成新的值,如果觉得文本显示的尺寸不合适,就得去字体管理器内修改字体大小。(如果要显示多种不同大小的文本,就要去字体管理器内注册多个字体)
到这,我们已经完成了legato显示文本所需要的所有设置,点击legato界面内的生成代码按钮,再点击harmony界面内的生成代码按钮。等待harmony生成新代码,并将这份代码烧录进开发板,显示如下。开机即会显示预先设置好的界面。
添加代码实现数字时钟
以下代码都是修改存放在main.c文件内,这里只是在偷懒,实际项目中肯定要针对每个功能都创建一个.c文件。
1. 添加一些头文件
#include <stdio.h>
#include "gfx/legato/generated/le_gen_init.h"
2. 定义一些全局变量
static struct{
unsigned int s;
unsigned int min;
unsigned int hour;
}time={0,0,0}; //用来保存时间
static char display[20]; //定义数组,用来存放我们要显示的字符串
static leFixedString ClockString; //定义一个legato字符串结构体,
static leChar legatoBuffer[20] = {0}; //定义一个legato字符数组,作为上面结构体的存储空间
3. 在main函数内放置初始化函数
leFixedString_Constructor(&ClockString, legatoBuffer, 16);
这一句的功能是为ClockString指定一个存放字符串的空间,基地址是legatoBuffer,占用16字节(legato一个字符占用2字节)
leFixedString结构体的原型里,存储数据的部分是个指针,需要手动为其指定存储字符串所用的内存区域
ClockString.fn->setFont(&ClockString, leStringTable_GetStringFont(leGetState()->stringTable,stringID_clock_string , 0));
以上代码里套了几个函数,功能是为ClockString结构体设置字体,采用我们之前在legato界面中定义的字符串helloworld的字体(该字符串的名字是clock_string)。
后面函数参数中的stringID_clock_string ,定义的位置位于:
source file/config/xxx_igat/gfx/legato/generated/le_gen_assets.h
不想翻过去找的话,就根据规律直接stringID_加上在字符串管理器定义字符串时的name参数。
TC1_TimerCallbackRegister(tc_callback, (uintptr_t)NULL);
TC1_TimerStart();
以上代码是为tc1指定回调函数,并启动tc1
4. 定义tc1回调函数,内容是改变屏幕显示的数字
注意,这里为了图方便,将更改屏幕内容的函数写在了定时器回调函数中。实际项目中禁止这样做,因为如果在legato设置了多个界面,在切换到界面2时,如果定时器内执行了修改界面1部件的代码,会导致出错,屏幕会失控。
void tc_callback( TC_TIMER_STATUS status, uintptr_t context )
{
if( ++time.s >=60 )
{
time.s = 0;
if( ++time.min >=60 )
{
time.min = 0;
if( ++time.hour >=24 )
time.hour = 0;
}
}
sprintf(display, "%u:%u:%u", time.hour, time.min, time.s);
ClockString.fn->setFromCStr(&ClockString, display);
Screen0_Labnum->fn->setString(Screen0_Labnum, (leString*)&ClockString);
}
最后3行代码的解析:
sprintf(display, "%u:%u:%u", time.hour, time.min, time.s);
使用sprintf函数生成我们需要显示的文本,存储到自定义的display数组
ClockString.fn->setFromCStr(&ClockString, display);
将上一步生成的字符串,设置进ClockString字符串结构体
Screen0_Labnum->fn->setString(Screen0_Labnum, (leString*)&ClockString);
将ClockString的传送给之前定义的label标签,即可在屏幕上显示了
这个代码还有很多改进空间,这里只是为了尽可能简单。
放置一段时间后的效果如下:
点击进入下一篇: legato学习3 —— 按键切换界面