O_嵌入式专题目录

本文基于Sipeed MaxiDockM1W开发板,SDK为堪智官方standalone,屏幕驱动改自官方kendryte_lcd-nt35310-standalone-driver。

主要涉及引脚

  • LCD_D0 - LCD_D7 默认接到K210的LCD8位并行接口,无需特殊配置。
  • LCD_WR - IO39 - CLK
  • LCD_DC - IO38 - DCX
  • LCD_RST - IO37 - RST
  • LCD_CS - IO36 - SS3
    // fpioa_set_function(37, FUNC_GPIOHS0 + RST_GPIONUM);  //HS3
    // fpioa_set_function(38, FUNC_GPIOHS0 + DCX_GPIONUM);  //HS2
    // fpioa_set_function(36, FUNC_SPI0_SS0 + LCD_SPI_SLAVE_SELECT);    //SS3
    // fpioa_set_function(39, FUNC_SPI0_SCLK);

device-manager.json

{
    "funcPinMap": {
        "UART1_RX": "H12",
        "UART1_TX": "G11",
        "GPIOHS2": "B2",
        "GPIOHS3": "A1",
        "SPI0_SCLK": "B1",
        "SPI0_SS3": "A2"
    },
    "selectedChip": "Kendryte K210"
}

fpioa-config.c

#include <fpioa.h>
#include "fpioa-config.h"

int ide_config_fpioa() {
int ret = 0;

ret += fpioa_set_function(5, FUNC_UART1_RX);
ret += fpioa_set_function(6, FUNC_UART1_TX);
ret += fpioa_set_function(38, FUNC_GPIOHS2);
ret += fpioa_set_function(37, FUNC_GPIOHS3);
ret += fpioa_set_function(39, FUNC_SPI0_SCLK);
ret += fpioa_set_function(36, FUNC_SPI0_SS3);

return ret;
}

main.c 配置代码

// 开启IO36-IO41的电源域
sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
// 开启SPI0的数据功能
sysctl_set_spi0_dvp_data(1);
// 初始化液晶屏
lcd_init();
// 屏幕填充为红色
lcd_clear(RED);

lcd.c

  • 这里主要是调颜色。

    #define LCD_SWAP_COLOR_BYTES 1
    
    #define SWAP_16(x) ((x >> 8 & 0xff) | (x << 8))
    #if LCD_SWAP_COLOR_BYTES
    static const uint16_t gray2rgb565[64] = {
      0x0000, 0x0020, 0x0841, 0x0861, 0x1082, 0x10a2, 0x18c3, 0x18e3,
      0x2104, 0x2124, 0x2945, 0x2965, 0x3186, 0x31a6, 0x39c7, 0x39e7,
      0x4208, 0x4228, 0x4a49, 0x4a69, 0x528a, 0x52aa, 0x5acb, 0x5aeb,
      0x630c, 0x632c, 0x6b4d, 0x6b6d, 0x738e, 0x73ae, 0x7bcf, 0x7bef,
      0x8410, 0x8430, 0x8c51, 0x8c71, 0x9492, 0x94b2, 0x9cd3, 0x9cf3,
      0xa514, 0xa534, 0xad55, 0xad75, 0xb596, 0xb5b6, 0xbdd7, 0xbdf7,
      0xc618, 0xc638, 0xce59, 0xce79, 0xd69a, 0xd6ba, 0xdedb, 0xdefb,
      0xe71c, 0xe73c, 0xef5d, 0xef7d, 0xf79e, 0xf7be, 0xffdf, 0xffff,
    };
    #else
    static const uint16_t gray2rgb565[64] = {
      0x0000, 0x2000, 0x4108, 0x6108, 0x8210, 0xa210, 0xc318, 0xe318,
      0x0421, 0x2421, 0x4529, 0x6529, 0x8631, 0xa631, 0xc739, 0xe739,
      0x0842, 0x2842, 0x494a, 0x694a, 0x8a52, 0xaa52, 0xcb5a, 0xeb5a,
      0x0c63, 0x2c63, 0x4d6b, 0x6d6b, 0x8e73, 0xae73, 0xcf7b, 0xef7b,
      0x1084, 0x3084, 0x518c, 0x718c, 0x9294, 0xb294, 0xd39c, 0xf39c,
      0x14a5, 0x34a5, 0x55ad, 0x75ad, 0x96b5, 0xb6b5, 0xd7bd, 0xf7bd,
      0x18c6, 0x38c6, 0x59ce, 0x79ce, 0x9ad6, 0xbad6, 0xdbde, 0xfbde,
      0x1ce7, 0x3ce7, 0x5def, 0x7def, 0x9ef7, 0xbef7, 0xdfff, 0xffff,
    };
    #endif
  • lcd_init
    (貌似不添加这两行也可以。)

      lcd_set_direction(DIR_YX_RLUD);
    
      tft_write_command(NORMAL_DISPALY_ON);
      usleep(100000);
    
      /*display on*/
      tft_write_command(DISPALY_ON);
      lcd_polling_enable();
  • lcd_draw_point

      lcd_set_area(x, y, x, y);
      // tft_write_half(&color, 1);
      tft_write_byte((uint8_t *)&color, 2);
  • lcd_draw_string / lcd_clear
    (函数开始处添加。)

    #if LCD_SWAP_COLOR_BYTES
      color = SWAP_16(color);
    #endif
  • lcd_fill_rectangle
    (函数开始处添加。)

      if ((x1 == x2) || (y1 == y2))
          return;
    #if LCD_SWAP_COLOR_BYTES
      color = SWAP_16(color);
    #endif
      uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
      // uint32_t data = color | (color << 16);
  • lcd_draw_rectangle
    (函数开始处添加。)

      // uint32_t data = color;
      uint32_t data;
    #if LCD_SWAP_COLOR_BYTES
      color = SWAP_16(color);
    #endif
    
      data = ((uint32_t)color << 16) | color;
      // data = (data << 16) | data;

st7789.h

  • 在本文件添加或在库内kendryte-package.json定义C、C++常量。
#define DCX_GPIONUM             (2)
#define RST_GPIONUM             (3)
#define SPI_CHANNEL             0
#define SPI_DMA_CH              DMAC_CHANNEL1
#define SPI_SLAVE_SELECT        3

st7789.c

  • 本文件内的所有 DMAC_CHANNEL0 替换为 SPI_DMA_CH ,即之前定义的 DMAC_CHANNEL1
  • 添加rst函数。

    static void init_rst(void)
    {
      gpiohs_set_drive_mode(RST_GPIONUM, GPIO_DM_OUTPUT);
      gpiohs_set_pin(RST_GPIONUM, GPIO_PV_HIGH);
    }
    
    static void set_rst(uint8_t val) { gpiohs_set_pin(RST_GPIONUM, val); }
  • tft_hard_init

      init_dcx();
      init_rst();
      set_rst(0);
      spi_init(SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_STANDARD, 8, 0);
      // spi_set_clk_rate(SPI_CHANNEL, 25000000);     //速率太高貌似有问题
      spi_set_clk_rate(SPI_CHANNEL, 15000000);
      msleep(50);
      set_rst(1);
      msleep(50);
    • SPI_FF_STANDARD 标准
    • SPI_FF_DUAL 双线
    • SPI_FF_QUAD 四线
    • SPI_FF_OCTAL 八线(SPI3不支持)

评论已关闭

Loading...
Fullscreen Image