1451|5

441

帖子

3

TA的资源

纯净的硅(高级)

楼主
 

【RTT&英飞凌PSoC6评估板】rt-thread之LVGL测试 [复制链接]

这篇来测试下【RTT&英飞凌PSoC6评估板】的LVGL测试。

在上一篇https://bbs.eeworld.com.cn/thread-1247691-1-1.htmlLCD驱动测试的基础上,修改ili9341显示屏的驱动,添加LVGL组件。

 

一、添加LVGL组件

在rt-thread studio中增加LVGL组件

 

1.1、硬件选项中使能LVGL for LCD

1.2、软件包选项中,添加LVGL

添加完成后,会看到下面软件包

1.3、添加LCD驱动

在软件包中搜索9341显示驱动,添加提示无法添加到项目,后面手工添加驱动。

二、软件程序

LVGL源码添加到程序中,主要的就是LCD硬件驱动和LVGL之间的接口函数。

需要手工将ILI9341驱动程序添加到项目中,程序代码如下:

2.1、lcd_ili9341.c

#include "lcd_ili9341.h"

#define DBG_TAG "ili9341"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#ifdef PKG_USING_ILI9341

_lcd_dev lcddev;
static struct rt_spi_device *lcd_dev;

static void LCD_RESET(void)
{
    LCD_RES_CLR;
    DELAY(100);
    LCD_RES_SET;
    DELAY(100);
}

static void LCD_WR_REG(uint8_t reg)
{
    LCD_DC_CLR;
    rt_spi_send(lcd_dev, ®, 1);
    LCD_DC_SET;
}

static void LCD_WR_DATA(uint8_t data)
{
    LCD_DC_SET;
    rt_spi_send(lcd_dev, &data, 1);
}

static void LCD_ReadData(uint8_t *data, uint16_t length)
{
    LCD_DC_SET;
    rt_spi_transfer(lcd_dev, RT_NULL, &data, length);
}

static void LCD_WriteReg(uint8_t reg, uint16_t regdata)
{
    LCD_WR_REG(reg);
    LCD_WR_DATA(regdata);
}

static void LCD_WriteRAM_Prepare(void)
{
    LCD_WR_REG(lcddev.wramcmd);
}

static void LCD_WriteData_16Bit(uint16_t Data)
{
    uint8_t buf[2];
    LCD_DC_SET;
    buf[0] = Data >> 8;
    buf[1] = Data & 0xff;
    rt_spi_send(lcd_dev, buf, 2);
}

void LCD_direction(uint8_t direction)
{
    lcddev.setxcmd = 0x2A;
    lcddev.setycmd = 0x2B;
    lcddev.wramcmd = 0x2C;
    switch (direction)
    {
    case 0:
        lcddev.width = LCD_W;
        lcddev.height = LCD_H;
        LCD_WriteReg(0x36, (1 << 3) | (0 << 6) | (0 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
        break;
    case 1:
        lcddev.width = LCD_H;
        lcddev.height = LCD_W;
        LCD_WriteReg(0x36, (1 << 3) | (0 << 7) | (1 << 6) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
        break;
    case 2:
        lcddev.width = LCD_W;
        lcddev.height = LCD_H;
        LCD_WriteReg(0x36, (1 << 3) | (1 << 6) | (1 << 7)); /* BGR==1,MY==0,MX==0,MV==0 */
        break;
    case 3:
        lcddev.width = LCD_H;
        lcddev.height = LCD_W;
        LCD_WriteReg(0x36, (1 << 3) | (1 << 7) | (1 << 5)); /* BGR==1,MY==1,MX==0,MV==1 */
        break;
    default:
        break;
    }
}

void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
    LCD_WR_REG(lcddev.setxcmd);
    LCD_WR_DATA(xStar >> 8);
    LCD_WR_DATA(0x00FF & xStar);
    LCD_WR_DATA(xEnd >> 8);
    LCD_WR_DATA(0x00FF & xEnd);

    LCD_WR_REG(lcddev.setycmd);
    LCD_WR_DATA(yStar >> 8);
    LCD_WR_DATA(0x00FF & yStar);
    LCD_WR_DATA(yEnd >> 8);
    LCD_WR_DATA(0x00FF & yEnd);

    LCD_WriteRAM_Prepare();
}

void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
    LCD_SetWindows(Xpos, Ypos, Xpos, Ypos);
}

void LCD_Clear(uint16_t Color)
{
    unsigned int i, m;
    uint8_t buf[80];

    for (i = 0; i < 40; i++)
    {
        buf[2 * i] = Color >> 8;
        buf[2 * i + 1] = Color & 0xff;
    }

    LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);

    LCD_DC_SET;
    for (i = 0; i < lcddev.height; i++)
    {
        for (m = 0; m < lcddev.width;)
        {
            m += 40;
            rt_spi_send(lcd_dev, buf, 80);
        }
    }
}

void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color)
{
    uint16_t i, j;
    LCD_SetWindows(xsta, ysta, xend - 1, yend - 1);
    for (i = ysta; i < yend; i++)
    {
        for (j = xsta; j < xend; j++)
        {
            LCD_WriteData_16Bit(color);
        }
    }
}

void lcd_fill_array_spi(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, void *Image)
{
    rt_uint32_t size = 0;

    size = (Xend - Xstart + 1) * (Yend - Ystart + 1) * 2;/*16bit*/
    LCD_SetWindows(Xstart, Ystart, Xend, Yend);
    LCD_DC_SET;

    rt_spi_send(lcd_dev, Image, size);
}

static void _ili9341_init(void)
{
    LCD_WR_REG(0xCF);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0X83);
    LCD_WR_DATA(0X30);

    LCD_WR_REG(0xED);
    LCD_WR_DATA(0x64);
    LCD_WR_DATA(0x03);
    LCD_WR_DATA(0X12);
    LCD_WR_DATA(0X81);

    LCD_WR_REG(0xE8);
    LCD_WR_DATA(0x85);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x79);

    LCD_WR_REG(0xCB);
    LCD_WR_DATA(0x39);
    LCD_WR_DATA(0x2C);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x34);
    LCD_WR_DATA(0x02);

    LCD_WR_REG(0xF7);
    LCD_WR_DATA(0x20);

    LCD_WR_REG(0xEA);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x00);

    LCD_WR_REG(0xC0);   /* Power control */
    LCD_WR_DATA(0x26);  /* VRH[5:0] */

    LCD_WR_REG(0xC1);   /* Power control */
    LCD_WR_DATA(0x11);  /* SAP[2:0];BT[3:0] */

    LCD_WR_REG(0xC5);   /* VCM control */
    LCD_WR_DATA(0x35);
    LCD_WR_DATA(0x3E);

    LCD_WR_REG(0xC7);   /* VCM control2 */
    LCD_WR_DATA(0XBE);

    LCD_WR_REG(0x36);   /* Memory Access Control */
    LCD_WR_DATA(0x28);

    LCD_WR_REG(0x3A);
    LCD_WR_DATA(0x55);

    LCD_WR_REG(0xB1);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x1B);

    LCD_WR_REG(0xB6);   /* Display Function Control */
    LCD_WR_DATA(0x0A);
    LCD_WR_DATA(0xA2);

    LCD_WR_REG(0xF2);   /* 3Gamma Function Disable */
    LCD_WR_DATA(0x08);

    LCD_WR_REG(0x26);   /* Gamma curve selected */
    LCD_WR_DATA(0x01);

    LCD_WR_REG(0xE0);   /* set Gamma */
    LCD_WR_DATA(0X1F);
    LCD_WR_DATA(0X1A);
    LCD_WR_DATA(0X18);
    LCD_WR_DATA(0X0A);
    LCD_WR_DATA(0X0F);
    LCD_WR_DATA(0X06);
    LCD_WR_DATA(0X45);
    LCD_WR_DATA(0X87);
    LCD_WR_DATA(0X32);
    LCD_WR_DATA(0X0A);
    LCD_WR_DATA(0X07);
    LCD_WR_DATA(0X02);
    LCD_WR_DATA(0X07);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X00);

    LCD_WR_REG(0xE1);   /* set Gamma */
    LCD_WR_DATA(0X00);
    LCD_WR_DATA(0X25);
    LCD_WR_DATA(0X27);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X10);
    LCD_WR_DATA(0X09);
    LCD_WR_DATA(0X3A);
    LCD_WR_DATA(0X78);
    LCD_WR_DATA(0X4D);
    LCD_WR_DATA(0X05);
    LCD_WR_DATA(0X18);
    LCD_WR_DATA(0X0D);
    LCD_WR_DATA(0X38);
    LCD_WR_DATA(0X3A);
    LCD_WR_DATA(0X2F);

    LCD_WR_REG(0x29);
}

static void Lcd_pin_init(void)
{
    rt_pin_mode(PKG_ILI_9341_DC_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(PKG_ILI_9341_RES_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(PKG_ILI_9341_BLK_PIN, PIN_MODE_OUTPUT);
}

static void LCD_Init(void)
{
    Lcd_pin_init();

    LCD_RESET();        /* LCD Hardware Reset */
    LCD_WR_REG(0x11);   /* Sleep out */
    DELAY(120);         /* Delay 120ms */
    _ili9341_init();    /* IlI9341 init */
    LCD_BLK_CLR;        /* Open Backlight */

    LCD_direction(USE_DIRECTION);
}

rt_err_t spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
{
    RT_ASSERT(bus_name != RT_NULL);
    RT_ASSERT(device_name != RT_NULL);

    rt_err_t result = RT_EOK;
    struct rt_spi_device *spi_device;

    /* attach the device to spi bus*/
    spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
    RT_ASSERT(spi_device != RT_NULL);

    result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
    if (RT_EOK != result)
    {
        LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
    }
    else
    {
        LOG_I("%s attach to %s done", device_name, bus_name);
    }

    return result;
}

rt_err_t spi_lcd_init(uint32_t freq)
{
    rt_err_t res = RT_EOK;

    spi_device_attach(PKG_ILI_9341_SPI_BUS_NAME, PKG_ILI_9341_SPI_DEVICE_NAME, PKG_ILI_9341_CS_PIN);
    lcd_dev = (struct rt_spi_device *)rt_device_find(PKG_ILI_9341_SPI_DEVICE_NAME);
    if (lcd_dev != RT_NULL)
    {
        struct rt_spi_configuration spi_config;
        spi_config.data_width = 8;
        spi_config.max_hz = freq * 1000 * 1000;
        spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
        rt_spi_configure(lcd_dev, &spi_config);
    }
    else
    {
        res = -RT_ERROR;
    }

    LCD_Init();

    return res;
}

static uint16_t color_array[] =
{
    WHITE, BLACK, BLUE, BRED,
    GRED, GBLUE, RED, YELLOW
};

static int lcd_spi_test(void)
{
    uint8_t index = 0;
    for (index = 0; index < sizeof(color_array) / sizeof(color_array[0]); index++)
    {
        LCD_Clear(color_array[index]);
        LOG_I("lcd clear color: %#x", color_array[index]);
        DELAY(200);
    }

    return RT_EOK;
}
MSH_CMD_EXPORT(lcd_spi_test, lcd will fill color => you need init lcd first);
#endif

 

2.2、lcd_ili9341.h

#ifndef __LCD_ILI9341_H__
#define __LCD_ILI9341_H__

#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "drivers/spi.h"

#include "drv_gpio.h"

typedef struct
{
    uint16_t width;   /* LCD width */
    uint16_t height;  /* LCD high */
    uint32_t id;      /* LCD ID */
    uint8_t dir;      /* 0:Vertical | 1:Vertical */
    uint16_t wramcmd; /* gram cmd */
    uint16_t setxcmd; /* set x cmd */
    uint16_t setycmd; /* set y cmd */
} _lcd_dev;

/* LCD param */
extern _lcd_dev lcddev;

/* 0-0 angle|1-90 angle|2-180 angle|-270 angle */
#define USE_DIRECTION   0

/* lcd size */
#define LCD_W PKG_ILI_9341_WIDTH
#define LCD_H PKG_ILI_9341_HEIGHT

#define PKG_ILI_9341_DC_PIN         GET_PIN(11, 5)//47
#define PKG_ILI_9341_RES_PIN        GET_PIN(11, 4)//46
#define PKG_ILI_9341_CS_PIN         GET_PIN(0, 5)//5
#define PKG_ILI_9341_BLK_PIN        GET_PIN(9, 2)//-1

#define LCD_DC_CLR  rt_pin_write(PKG_ILI_9341_DC_PIN, PIN_LOW)
#define LCD_DC_SET  rt_pin_write(PKG_ILI_9341_DC_PIN, PIN_HIGH)
#define LCD_RES_CLR rt_pin_write(PKG_ILI_9341_RES_PIN, PIN_LOW)
#define LCD_RES_SET rt_pin_write(PKG_ILI_9341_RES_PIN, PIN_HIGH)
#define LCD_BLK_CLR rt_pin_write(PKG_ILI_9341_BLK_PIN, PIN_HIGH)
#define DELAY       rt_thread_mdelay

#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40
#define BRRED 0XFC07
#define GRAY 0X8430

void LCD_Clear(uint16_t Color);
void LCD_direction(uint8_t direction);
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);
void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd);
void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color);
void lcd_fill_array_spi(uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end, void *pcolor);

rt_err_t spi_lcd_init(uint32_t freq);

#ifdef __cplusplus
}
#endif
#endif

 

2.3、项目工程源码

psoc62-rt-thread-prj.rar (42.32 MB, 下载次数: 34)

 

三、程序运行

 

3.1、连接硬件

3.2、下载程序后,复位开发板,程序运行LVGL例程,运行视频如下:

2000

 

 

最新回复

刷新速度效果挺好的呀!  详情 回复 发表于 2023-7-3 08:45
点赞 关注

回复
举报

7205

帖子

2

TA的资源

版主

沙发
 

这个帧率不太高的样子,刷屏幕用的是Arm-Cortex-M4F核吗?

点评

spi 时钟频率25M,运行速度不是很快。  详情 回复 发表于 2023-6-27 11:05
 
 

回复

441

帖子

3

TA的资源

纯净的硅(高级)

板凳
 
wangerxian 发表于 2023-6-27 09:17 这个帧率不太高的样子,刷屏幕用的是Arm-Cortex-M4F核吗?

spi 时钟频率25M,运行速度不是很快。

点评

SPI频率再加快点估计会好一些。  详情 回复 发表于 2023-6-27 11:45
 
 
 

回复

7205

帖子

2

TA的资源

版主

4
 
TL-LED 发表于 2023-6-27 11:05 spi 时钟频率25M,运行速度不是很快。

SPI频率再加快点估计会好一些。

 
 
 

回复

7640

帖子

2

TA的资源

五彩晶圆(高级)

5
 

25M不算慢了吧。

 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

6998

帖子

11

TA的资源

版主

6
 
刷新速度效果挺好的呀!
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表