一、spi驱动屏幕,
我使用的屏幕为1.8寸spi屏幕 驱动芯片为st7735,因为我之前在stm32使用keil裸机驱动已经配置好了,我移植过来只需要将spi对应的接口替换掉即可。
使用spi,我用的spi为spi0,具体使用可以查看rtt的文档中心。贴上我的代码供大家使用。
void spi_init(void)
{
/////我的rt_hw_spi_device_attach函数修改过,不知道怎么改的可以看上面发的文章
rt_hw_spi_device_attach(SPI,SPI_DA,BSP_IO_PORT_02_PIN_05);//挂载到SPI设备上
/* 查找 spi 设备获取设备句柄 */
spi_da = (struct rt_spi_device *)rt_device_find(SPI_DA);
if (spi_da == RT_NULL)
{
rt_kprintf("spi sample run failed! can't find %s device!\n", SPI);
}
else {
struct rt_spi_configuration spi_config;
spi_config.data_width = 8;
spi_config.max_hz = 25 * 1000 * 1000;
spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0| RT_SPI_MSB;
rt_spi_configure(spi_da, &spi_config);
}
}
void spi_send(uint8_t data)
{
uint8_t send_data[1];
send_data[0]=data;
rt_spi_transfer (spi_da, send_data, RT_NULL,1);
}
void spi_send_two(uint16_t data)
{
uint8_t send_data[2];
send_data[0]=data>>8;
send_data[1]=data;
rt_spi_transfer (spi_da, send_data, RT_NULL,2);
}
二、移植lvgl
(一)、添加lvgl软件包
首先打开rtthread setting,点击右侧的缩进,打开后,选择软件包,再将多媒体包第一个就为lvgl的软件包,作为测试可以添加demo,然后关闭rtthread setting保存,lvgl软件包就会添加进工程。软件包在packages文件夹下。
(二)适配瑞萨工程
因为本人移植lvgl使用在keil比较多,所以有些跟rtt的不太一样。
1、 首先需要创建几个源跟头文件,分别命名为lv_conf.h、 lv_port_disp.c
lv_port_disp.h、lv_demo_conf.h、lv_demo.c几个文件夹,我分别说一下他们的功能。
lv_conf.h: 是lvgl的配置文件,添加我们需要的控件的,一些宏的配置
lv_port_disp.c、lv_port_disp.h: 是lvgl的屏幕底层驱动。
lv_demo_conf.h: lvgl的demo 启动的宏
lv_demo.c : 编写lvgl的初始化,demo的初始化接口,任务启动等。
2、lv_conf.h、lv_demo_conf.h
在我们拉取的软件包里有一个lv_conf_template.h文件,其实我们在keil移植的时候都是使用这个文件,因为在写的话很麻烦,所以我将它的文件复制过来,头有if0,将其改为if1或者去掉。
在lvgl8.2的版本是将demo的启动宏放到lv_conf_template.h文件的,我们拉到最下面DEMO USAGE,将下面的一些宏剪切到lv_demo_conf.h文件下。
如果使用music的demo,rtt将这个demo单独拉出来了,如果添加的话需要将红对应的修改,其实不用在拉去的软件包中也有这个demo的存在。
lv_conf.h,将文件拷贝过来后,因为我们使用了系统,找到LV_TICK_CUSTOM宏将其设为1,使用rtt的时钟做心跳,不用自己在实现定时器。
#define LV_TICK_CUSTOM 1
#if LV_TICK_CUSTOM
#define LV_TICK_CUSTOM_INCLUDE <rtthread.h> /Header for the system time function/
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (rt_tick_get_millisecond())
3、lv_port_disp.c
lv_port_disp.h文件我们首先也可以在lvgl的软件包中找到,在packages\LVGL-v8.2.0\examples\porting这个路径下有lv_port_disp_template名字的两个文件,一样可以复制过来到对应的lv_port_disp.c lv_port_disp.h的文件中,然后修改
static void tft_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
int32_t x,y;
for(y = area->y1; y <= area->y2; y++) {
for(x = area->x1; x <= area->x2; x++) {
// 画点函数,例如常见的一些屏用的是16位颜色,把16位数据输出到屏幕即可
Gui_Draw_Point(x,y, color_p->full );
color_p++;
}
}
lv_disp_flush_ready(disp_drv);
}
void lv_port_disp_init(void)
{
void *draw_buf1 = RT_NULL;
draw_buf1 = (void )rt_malloc(160 * 50 * sizeof(lv_color_t));//缓冲区 缓冲区的大小可以不为整屏
rt_kprintf("LVGL: Use one buffers - buf1@%08x\n", draw_buf1);
/Initialize disp_buf
with the buffer(s)./
lv_disp_draw_buf_init(&disp_buf, draw_buf1, RT_NULL, 160 * 50);
lv_disp_drv_init(&disp_drv); /Basic initialization/
/Set the resolution of the display/
disp_drv.hor_res = 160;//屏幕的宽度
disp_drv.ver_res = 128;//屏幕的宽度
// disp_drv.full_refresh = 1;
/Set a display buffer/
disp_drv.draw_buf = &disp_buf;
/Write the internal buffer (draw_buf) to the display/
disp_drv.flush_cb = tft_flush;
/ Called after every refresh cycle to tell the rendering and flushing time + the number of flushed pixels */
//disp_drv.monitor_cb = lcd_perf_monitor;
/Finally register the driver/
lv_disp_drv_register(&disp_drv);
}
4、lv_demo.c,
是我们的工程启动文件,创建线程,在初始化时添加lv_init();,以及lv_port_disp_init();函数,然后在while(1)循环里添加lv_task_handler();函数。然后这样我们需要配置的文件就写完了,将头文件添加进工程,然后编译,使用即可。
当然其他的芯片也可以这么添加,需要改的是lv_port_disp的屏幕驱动,对应上就好了。
原作者: 嚜軒公告