0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【XR806開發(fā)板試用】移植st7789屏幕驅(qū)動

冬至子 ? 來源:李隆 ? 作者:李隆 ? 2023-10-16 11:01 ? 次閱讀

SDK下載和環(huán)境搭建

如果提示 Username for : 請輸入 全志在線開發(fā)者論壇 的用戶名和密碼。(注:需要全志在線開發(fā)者論壇LV2等級以上用戶才有權(quán)限拉取 SDK,隨便注冊個賬戶,灌灌水就到了)

由于 SDK 普遍較大,拉取可能需要一定的時間。

接下來安裝環(huán)境依賴(我用Buildroot的docker容器,都裝過了,就不需要再搞了)

sudo apt-get install build-essential subversion git libncurses5-dev zlib1g-dev gawk flex bison quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip lsof kconfig-frontends android-tools-mkbootimg python2 libpython3-dev gcc-multilib libc6:i386 libstdc++6:i386 lib32z1

然后配置工具鏈,直接下載gcc-arm-none-eabi-8-2019-q3-update-linux.tar.bz2 壓縮包并解壓縮到~/.bin目錄下,并修改gcc.mk文件

# ----------------------------------------------------------------------------
# cross compiler
# ----------------------------------------------------------------------------
CC_DIR := /home/vuser/.bin/gcc-arm-8.3/bin/
CC_PREFIX := ccache $(CC_DIR)/arm-none-eabi-

這樣就配置好了??戳艘幌聀roject/example目錄下,有個spi工程,適合拿來修改,就是它了。

移植st7789驅(qū)動

ST7789是一款高度集成的彩色TFT液晶顯示屏控制器芯片,通常用于驅(qū)動小到中等尺寸的液晶屏。例如淘寶上常見的1.4寸、1.47寸、1.69寸屏幕等等。
現(xiàn)在就開始吧,首先新建st7789.c和st7789.h文件。然后創(chuàng)建用于初始化st7789芯片的命令序列表。

static lcd_init_cmd_t st7789_init_cmds[] = {
    {0x01, {0}, 0x80, 120},
    /* Sleep Out */
    {0x11, {0}, 0x80, 120},
    /* Memory Data Access Control, MX=MV=1, MY=ML=MH=0, RGB=0 */
    {0x36, {0x00}, 1},
    /* Interface Pixel Format, 16bits/pixel for RGB/MCU interface */
    {0x3A, {0x05}, 1},
#if 0
      {0x30, {0x00,0x50,0x01,0x3F}, 4},
      {0x12, {0x00}, 0},
#endif
    /* Porch Setting */
    {0xB2, {0x0c, 0x0c, 0x00, 0x33, 0x33}, 5},
    /* Gate Control, Vgh=13.65V, Vgl=-10.43V */
    {0xB7, {0x35}, 1},
    /* VCOM Setting, VCOM=1.35V */
    {0xBB, {0x32}, 1},
    // /* LCM Control, XOR: BGR, MX, MH */
    // {0xC0, {0x2C}, 1},
    /* VDV and VRH Command Enable, enable=1 */
    {0xC2, {0x01, 0xFF}, 2},
    /* VRH Set, Vap=4.4+... */
    {0xC3, {0x15}, 1},
    /* VDV Set, VDV=0 */
    {0xC4, {0x20}, 1},
    /* Frame Rate Control, 60Hz, inversion=0 */
    {0xC6, {0x0F}, 1},
    /* Power Control 1, AVDD=6.8V, AVCL=-4.8V, VDDS=2.3V */
    {0xD0, {0xA4, 0xA1}, 1},
    /* Positive Voltage Gamma Control */
    {0xE0,
     {0xD0, 0x08, 0x0E, 0x09, 0x09, 0x05, 0x31, 0x33, 0x48, 0x17, 0x14, 0x15,
      0x31, 0x34},
     14},
    /* Negative Voltage Gamma Control */
    {0xE1,
     {0xD0, 0x08, 0x0E, 0x09, 0x09, 0x15, 0x31, 0x33, 0x48, 0x17, 0x14, 0x15,
      0x31, 0x34},
     14},
    /* Display On */
    {0x21, {0}, 0},
    {0x29, {0}, 0},
    {0, {0}, 0xff}};

這個序列表使用的是這樣的數(shù)據(jù)結(jié)構(gòu)

/*The LCD needs a bunch of command/argument values to be initialized. They are
 * stored in this struct. */
typedef struct {
  # 指令
  uint8_t cmd;
  # 數(shù)據(jù)
  uint8_t data[16];
  # 數(shù)據(jù)長度和類型,一般初始化數(shù)據(jù)不會很長,使用部分做其他用。
  # 例如 0x80代表需要延時,延時時間由delaytime指定,0xFF代表結(jié)束
  uint8_t databytes; // No of data in data; bit 7 = delay after set; 0xFF =
                     // end of cmds.
  uint8_t delaytime; // delaytime
} lcd_init_cmd_t;

然后編寫初始化函數(shù),這里把gpio和spi的初始化都放在里面了。

printf("ST7789 initialization.n");

  int ret = dirver_spi_init();
  if (ret != 0) {
    printf("SPI dev init fail!n");
  }

  gpio_init(disp_pin_dc);
  gpio_init(disp_pin_rst);
  gpio_init(disp_pin_bckl);

  HAL_SPI_CS(DEMO_SPI_PORT, 1);
  // Reset the displayc
  gpio_set_level(disp_pin_rst, 1);
  OS_MSleep(1);
  gpio_set_level(disp_pin_rst, 0);
  OS_MSleep(100);
  gpio_set_level(disp_pin_rst, 1);
  OS_MSleep(100);

  st7789_enable_backlight(true);
  OS_MSleep(100);

  // Send all the commands
  uint16_t cmd = 0;
  while (st7789_init_cmds[cmd].databytes != 0xff) {
    printf("Send command 0x%02xn", st7789_init_cmds[cmd].cmd);
    st7789_send_cmd(st7789_init_cmds[cmd].cmd);
    if ((st7789_init_cmds[cmd].databytes & 0x1F) != 0) {
      st7789_send_data(st7789_init_cmds[cmd].data,
                       st7789_init_cmds[cmd].databytes & 0x1F);
    }
    if (st7789_init_cmds[cmd].databytes & 0x80) {
      OS_MSleep(st7789_init_cmds[cmd].delaytime);
    }
    cmd++;
  }
  printf("init finish.n");
  st7789_set_orientation(DISPLAY_ORIENTATION);

硬件連接如圖所示

image.png

1.jpg

為什么RES引腳直接接的VCC,因為不知道是這個芯片的問題還是什么問題。RES引腳接到推挽輸出的IO引腳后,屏幕也能點亮,但是亮度莫名其妙很低。手上幾個屏都測試了一下,都這樣。

然后就是編寫一下寫命令和寫數(shù)據(jù)的函數(shù),寫命令時需要設(shè)置一下DC引腳,然后寫完立即將DC引腳切換回高電平。

static void st7789_send_cmd(uint8_t cmd) {
  gpio_set_level(disp_pin_dc, 0);
  dirver_spi_send_data(&cmd, 1);
  gpio_set_level(disp_pin_dc, 1);
}
static void st7789_send_data(void *data, uint16_t length) {
  dirver_spi_send_data(data, length);
}

然后就是編寫屏幕翻轉(zhuǎn)配置函數(shù)

static void st7789_set_orientation(uint8_t orientation) {
  // ESP_ASSERT(orientation < 4);

  const char *orientation_str[] = {"PORTRAIT", "PORTRAIT_INVERTED", "LANDSCAPE",
                                   "LANDSCAPE_INVERTED"};

  printf("Display orientation: %sn", orientation_str[orientation]);

  uint8_t data[] = {0xC0, 0x00, 0x60, 0xA0};

  printf("0x36 command value: 0x%02Xn", data[orientation]);

  st7789_send_cmd(ST7789_MADCTL);
  st7789_send_data((void *)&data[orientation], 1);
}

最后再寫一下寫屏函數(shù)即可,這里為了快速刷屏,設(shè)置了比較大的緩存區(qū)。目前還不會使用XR806的DMA,學(xué)會了可以減少緩存RAM的大小。

/* The ST7789 display controller can drive 320*240 displays, when using a
 * 240*240 display there's a gap of 80px, we need to edit the coordinates to
 * take into account that gap, this is not necessary in all orientations. */
void st7789_flush(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2,
                  uint16_t color) {
  uint8_t data[4] = {0};

  uint16_t offsetx1 = x1;
  uint16_t offsetx2 = x2;
  uint16_t offsety1 = y1;
  uint16_t offsety2 = y2;

#if (TFT_DISPLAY_OFFSETS)
  offsetx1 += TFT_DISPLAY_X_OFFSET;
  offsetx2 += TFT_DISPLAY_X_OFFSET;
  offsety1 += TFT_DISPLAY_Y_OFFSET;
  offsety2 += TFT_DISPLAY_Y_OFFSET;

#elif (LV_HOR_RES_MAX == 320) && (LV_VER_RES_MAX == 320)
#if (DISPLAY_ORIENTATION_PORTRAIT)
  offsetx1 += 80;
  offsetx2 += 80;
#elif (DISPLAY_ORIENTATION_LANDSCAPE_INVERTED)
  offsety1 += 80;
  offsety2 += 80;
#endif
#endif

  /*Column addresses*/
  st7789_send_cmd(ST7789_CASET);
  data[0] = (offsetx1 > > 8) & 0xFF;
  data[1] = offsetx1 & 0xFF;
  data[2] = (offsetx2 > > 8) & 0xFF;
  data[3] = offsetx2 & 0xFF;
  st7789_send_data(data, 4);

  /*Page addresses*/
  st7789_send_cmd(ST7789_RASET);
  data[0] = (offsety1 > > 8) & 0xFF;
  data[1] = offsety1 & 0xFF;
  data[2] = (offsety2 > > 8) & 0xFF;
  data[3] = offsety2 & 0xFF;
  st7789_send_data(data, 4);

  /*Display On*/
  st7789_send_cmd(ST7789_DISPON);
  /*Memory write*/
  st7789_send_cmd(ST7789_RAMWR);

  uint32_t size = (y2 - y1) * (x2 - x1);

  uint32_t buffsize = (x2 - x1) * 80;
  unsigned char *burst_buffer = (unsigned char *)malloc(buffsize * 2);

  for (uint32_t i = 0; i < size + buffsize; i += buffsize) {
    for (uint32_t j = 0; j < buffsize; j++) {
      burst_buffer[2 * j] = color > > 8;
      burst_buffer[2 * j + 1] = color;
    }
    st7789_send_data(burst_buffer, buffsize * 2);
  }

  free(burst_buffer);
}

還需要添加一個刷屏函數(shù)作為測試,現(xiàn)在補一下。
由于1.69寸屏幕不需要設(shè)置屏幕窗口偏移量,就直接按滿屏來刷了。

void lcd_clear(uint16_t color) { st7789_flush(0, 240, 0, 320, color); }

然后在main.c里調(diào)用屏幕初始化和刷屏函數(shù)就可以啦。

#include "common/framework/platform_init.h"
#include "kernel/os/os.h"
#include < stdio.h >

extern void st7789_init();
extern void st7789_flush(uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2,
                         uint16_t color);
extern void lcd_clear(uint16_t color);

int main(void) {

  platform_init();

  printf("gpio demo started.n");

  st7789_init();
  printf("flush color.n");
  // st7789_flush(0, 240, 0, 280, 0xFFFF);

  while (1) {
    lcd_clear(0x0000);
    OS_MSleep(1000);
    lcd_clear(0xFFFF);
    OS_MSleep(1000);
    lcd_clear(0xEF5D);
    OS_MSleep(1000);
    lcd_clear(0xF800);
    OS_MSleep(1000);
    lcd_clear(0x07E0);
    OS_MSleep(1000);
    lcd_clear(0x001F);
    OS_MSleep(1000);
  }

  printf("never run here.n");
  return 0;
}

# 清除錯誤用
void main_cmd_exec(char *cmd) {}

刷屏效果如圖

d236f6399ed47461c18a48c1245f0e0.jpg

經(jīng)過測試,手上的1.47寸屏幕和1.69寸st7789屏幕都可以正常驅(qū)動。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 驅(qū)動器
    +關(guān)注

    關(guān)注

    52

    文章

    8057

    瀏覽量

    145623
  • 控制器
    +關(guān)注

    關(guān)注

    112

    文章

    16033

    瀏覽量

    176655
  • RAM
    RAM
    +關(guān)注

    關(guān)注

    8

    文章

    1351

    瀏覽量

    114371
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1182

    瀏覽量

    51738
  • TFT屏
    +關(guān)注

    關(guān)注

    0

    文章

    17

    瀏覽量

    5723
收藏 人收藏

    評論

    相關(guān)推薦

    XR806開發(fā)板適用】基于多源信息融合的糧食霉變檢測系統(tǒng)設(shè)計

    XR806開發(fā)板具有強大的數(shù)據(jù)處理和傳輸能力,廣泛應(yīng)用于物聯(lián)網(wǎng)和嵌入式系統(tǒng)開發(fā)
    的頭像 發(fā)表于 10-27 17:06 ?846次閱讀
    【<b class='flag-5'>XR806</b><b class='flag-5'>開發(fā)板</b>適用】基于多源信息融合的糧食霉變檢測系統(tǒng)設(shè)計

    基于全志XR806開發(fā)板的家用環(huán)境監(jiān)測傳感器設(shè)計

    本文來自全志XR806開發(fā)板評測活動文章,作者使用XR806開發(fā)板制作一個簡單的家用環(huán)境監(jiān)測傳感器,可以獲取當前的溫度、濕度、氣壓、海拔這四個參數(shù),同時能夠通過外部的
    的頭像 發(fā)表于 12-03 10:20 ?599次閱讀
    基于全志<b class='flag-5'>XR806</b><b class='flag-5'>開發(fā)板</b>的家用環(huán)境監(jiān)測傳感器設(shè)計

    如何使用XR806開發(fā)板來設(shè)計一個糧食霉變檢測系統(tǒng)?

    XR806開發(fā)板具有強大的數(shù)據(jù)處理和傳輸能力,廣泛應(yīng)用于物聯(lián)網(wǎng)和嵌入式系統(tǒng)開發(fā),
    的頭像 發(fā)表于 01-05 17:30 ?740次閱讀
    如何使用<b class='flag-5'>XR806</b><b class='flag-5'>開發(fā)板</b>來設(shè)計一個糧食霉變檢測系統(tǒng)?

    OpenHarmony南向嵌入式:【XR806開發(fā)板指導(dǎo)文檔】

    XR806_OpenHarmony開發(fā)板是基于XR806芯片設(shè)計開發(fā)的參考評估,身集成了XR806
    的頭像 發(fā)表于 04-14 09:25 ?711次閱讀
    OpenHarmony南向嵌入式:【<b class='flag-5'>XR806</b><b class='flag-5'>開發(fā)板</b>指導(dǎo)文檔】

    XR806芯片、XR806開源鴻蒙開發(fā)板簡介

    ??蓮V泛滿足 智能家居、智慧樓宇、工業(yè)互聯(lián)、兒童玩具、電子競賽、極客DIY 等領(lǐng)域的無線連接需求。芯片框圖芯片參數(shù)XR806開源鴻蒙開發(fā)板介紹XR806開發(fā)板是基于
    發(fā)表于 11-15 17:08

    XR806芯片、XR806開源鴻蒙開發(fā)板簡介

    。可廣泛滿足 智能家居、智慧樓宇、工業(yè)互聯(lián)、兒童玩具、電子競賽、極客DIY 等領(lǐng)域的無線連接需求。芯片框圖芯片參數(shù)XR806開源鴻蒙開發(fā)板介紹XR806開發(fā)板是基于
    發(fā)表于 11-15 18:32

    請問大佬XR806鴻蒙開發(fā)板怎么樣?

    請問大佬XR806鴻蒙開發(fā)板怎么樣?
    發(fā)表于 12-29 07:06

    在全志XR806移植st7789屏幕驅(qū)動

    \"); st7789_set_orientation(DISPLAY_ORIENTATION); 硬件連接如圖所示 屏幕 開發(fā)板 BLK B14 CS B06 DC B03 RES VCC
    發(fā)表于 11-10 10:21

    全志XR806開發(fā)板適配ST7789LCD屏幕測試

    本次使用XR806實現(xiàn)ST7789屏幕驅(qū)動。 硬件連接 本文使用的LCD屏幕的原理圖如下,可以確定LCD
    發(fā)表于 12-13 14:03

    XR806開發(fā)板試用】留言功能開發(fā)

    XR806開源鴻蒙開發(fā)板是一款基于XR806芯片設(shè)計,高度集成WiFi/BLE/常用外設(shè),可供開發(fā)者進行方案評估、DIY或小規(guī)模產(chǎn)品研發(fā),可廣泛應(yīng)用于智能家居、智能樓宇、智能城市和工業(yè)
    的頭像 發(fā)表于 10-08 10:58 ?583次閱讀

    XR806開發(fā)板試用】FreeRTOS創(chuàng)建任務(wù)測試

    這篇來學(xué)習(xí)下,XR806開發(fā)板在FreeRTOS系統(tǒng)下創(chuàng)建兩個任務(wù)測試,由于沒有找到學(xué)習(xí)的文檔,試著參考例程來測試。
    的頭像 發(fā)表于 10-10 11:47 ?590次閱讀
    【<b class='flag-5'>XR806</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>試用</b>】FreeRTOS創(chuàng)建任務(wù)測試

    使用XR806芯片驅(qū)動一下DHT11溫濕度傳感器

    參與全志在線與極術(shù)社區(qū)聯(lián)合舉辦的開發(fā)板試用活動,收到寄來的全志XR806開發(fā)板,之前用過很多全志的SOC芯片,但是像這種無線芯片還是第一次用。這次打算使用
    發(fā)表于 10-13 17:28 ?518次閱讀
    使用<b class='flag-5'>XR806</b>芯片<b class='flag-5'>驅(qū)動</b>一下DHT11溫濕度傳感器

    移植st7789屏幕驅(qū)動教程

    ST7789是一款高度集成的彩色TFT液晶顯示屏控制器芯片,通常用于驅(qū)動小到中等尺寸的液晶屏。例如淘寶上常見的1.4寸、1.47寸、1.69寸屏幕等等。
    的頭像 發(fā)表于 10-21 16:35 ?7242次閱讀
    <b class='flag-5'>移植</b><b class='flag-5'>st7789</b><b class='flag-5'>屏幕</b><b class='flag-5'>驅(qū)動</b>教程

    XR806串口驅(qū)動CM32M對小廚寶的控制實驗

    非常感謝基于安謀科技STAR-MC1的全志XR806 Wi-Fi+BLE開源鴻蒙開發(fā)板試用活動,并獲得開發(fā)板試用。
    的頭像 發(fā)表于 10-23 11:39 ?509次閱讀
    <b class='flag-5'>XR806</b>串口<b class='flag-5'>驅(qū)動</b>CM32M對小廚寶的控制實驗

    全志XR806開發(fā)板原理圖

    全志XR806開發(fā)板原理圖
    發(fā)表于 10-19 15:11 ?11次下載