ST7789驱动

1. 信号线设置

以正点原子的潘多拉IOT开发板为例,主要有有6条线:

  • RESET:复位
  • CS:片选
  • DCX:数据/命令选择(正点原子的开发板将之标注为WR信号)
  • SCK:SPI时钟线
  • SDA:数据线
  • PWR:LED背光
    这种配置下,MCU只向ST7789写数据而不读取数据。

2. SPI配置要求

  • 主模式,仅发送,8bit模式
  • 时钟极性为高,第二个边沿(上升沿)latch
  • 是种周期不要低于16ns

3. 关键函数介绍

3.1 需要根据硬件平台进行设置的函数

void st7789_cfg_pwr_set(void);
void st7789_cfg_pwr_reset(void);
void st7789_cfg_rst_set(void);
void st7789_cfg_delay_ms(uint32_t ms);
void st7789_cfg_rst_reset(void);
void st7789_cfg_cs_set(void);
void st7789_cfg_cs_reset(void);
void st7789_cfg_dcx_set(void);
void st7789_cfg_dcx_reset(void);
void st7789_cfg_spi_write(uint8_t *pbuf, uint16_t size);

3.2 与硬件平台无关的函数(仅与上述函数相关)

void st7789_on(void);
void st7789_off(void);
void st7789_init(void);
void st7789_set_address(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void st7789_fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void st7789_draw_pixel(uint16_t x, uint16_t y, uint16_t color);

后四个函数示例如下:

/**
 * @brief   Initialize the LCD.
 * @param   None.
 * @retval  None.
 */
void st7789_init(void)
{
    /* Display off */
    st7789_cfg_pwr_reset();

    /* Reset */
    st7789_cfg_rst_reset();
    st7789_cfg_delay_ms(200);
    st7789_cfg_rst_set();
    /* Sleep Out */
    st7789_write_cmd(0x11);
    /* Wait for power stability */
    st7789_cfg_delay_ms(200);

    /* Memory Data Access Control */
    st7789_write_cmd(0x36);
    st7789_write_data(0x00);
    /* RGB 5-6-5-bit  */
    st7789_write_cmd(0x3A);
    st7789_write_data(0x65);
    /* Porch Setting */
    st7789_write_cmd(0xB2);
    st7789_write_data(0x0C);
    st7789_write_data(0x0C);
    st7789_write_data(0x00);
    st7789_write_data(0x33);
    st7789_write_data(0x33);
    /* Gate Control */
    st7789_write_cmd(0xB7);
    st7789_write_data(0x35);
    /* VCOM Setting */
    st7789_write_cmd(0xBB);
    st7789_write_data(0x19);
    /* LCM Control */
    st7789_write_cmd(0xC0);
    st7789_write_data(0x2C);
    /* VDV and VRH Command Enable */
    st7789_write_cmd(0xC2);
    st7789_write_data(0x01);
    /* VRH Set */
    st7789_write_cmd(0xC3);
    st7789_write_data(0x12);
    /* VDV Set */
    st7789_write_cmd(0xC4);
    st7789_write_data(0x20);
    /* Frame Rate Control in Normal Mode */
    st7789_write_cmd(0xC6);
    st7789_write_data(0x0F);
    /* Power Control 1 */
    st7789_write_cmd(0xD0);
    st7789_write_data(0xA4);
    st7789_write_data(0xA1);
    /* Positive Voltage Gamma Control */
    st7789_write_cmd(0xE0);
    st7789_write_data(0xD0);
    st7789_write_data(0x04);
    st7789_write_data(0x0D);
    st7789_write_data(0x11);
    st7789_write_data(0x13);
    st7789_write_data(0x2B);
    st7789_write_data(0x3F);
    st7789_write_data(0x54);
    st7789_write_data(0x4C);
    st7789_write_data(0x18);
    st7789_write_data(0x0D);
    st7789_write_data(0x0B);
    st7789_write_data(0x1F);
    st7789_write_data(0x23);
    /* Negative Voltage Gamma Control */
    st7789_write_cmd(0xE1);
    st7789_write_data(0xD0);
    st7789_write_data(0x04);
    st7789_write_data(0x0C);
    st7789_write_data(0x11);
    st7789_write_data(0x13);
    st7789_write_data(0x2C);
    st7789_write_data(0x3F);
    st7789_write_data(0x44);
    st7789_write_data(0x51);
    st7789_write_data(0x2F);
    st7789_write_data(0x1F);
    st7789_write_data(0x1F);
    st7789_write_data(0x20);
    st7789_write_data(0x23);
    /* Display Inversion On */
    st7789_write_cmd(0x21);

    /* Display on */
    st7789_on();
    st7789_fill(0, 0, _ST7789_WIDTH - 1, _ST7789_HEIGHT - 1, 0xFFFF);
    st7789_write_cmd(0x29);
}

/**
 * @brief   Set address to be edited.
 * @param   x1 [In]: start x.
 * @param   y1 [In]: start y.
 * @param   x2 [In]: end x.
 * @param   y2 [In]: end y.
 * @retval  None.
 */
void st7789_set_address(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
    st7789_write_cmd(0x2a);
    st7789_write_data(x1 >> 8);
    st7789_write_data(x1);
    st7789_write_data(x2 >> 8);
    st7789_write_data(x2);
    st7789_write_cmd(0x2b);
    st7789_write_data(y1 >> 8);
    st7789_write_data(y1);
    st7789_write_data(y2 >> 8);
    st7789_write_data(y2);
    st7789_write_cmd(0x2C);
}

/**
 * @brief   Fill specified area with specified color.
 * @param   x1 [In]: start x.
 * @param   y1 [In]: start y.
 * @param   x2 [In]: end x.
 * @param   y2 [In]: end y.
 * @param   color [In]: color to be filled.
 * @retval  None.
 */
void st7789_fill(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
    uint16_t size, r, i;

    size = (x2 - x1 + 1) * (y2 - y1 + 1);
    if (size > _ST7789_BUFFER_SIZE)
    {
        for (i = 0; i < _ST7789_BUFFER_SIZE; i++)
        {
            st7789_buffer[2 * i] = color >> 8;
            st7789_buffer[2 * i + 1] = color;
        }
    }
    else
    {
        for (i = 0; i < size; i++)
        {
            st7789_buffer[2 * i] = color >> 8;
            st7789_buffer[2 * i + 1] = color;
        }
    }
    
    r = size;
    st7789_set_address(x1, y1, x2, y2);
    st7789_cfg_dcx_set();
    while (1)
    {
        if (r > _ST7789_BUFFER_SIZE)
        {
            st7789_cfg_spi_write(st7789_buffer, _ST7789_BUFFER_SIZE * 2);
            r = r - _ST7789_BUFFER_SIZE;
        }
        else
        {
            st7789_cfg_spi_write(st7789_buffer, r * 2);
            break;
        }
    }
}

/**
 * @brief   Draw specified pixel with specified color.
 * @param   x [In]: x of specified pixel.
 * @param   y [In]: y of specified pixel.
 * @param   color [In]: color to be filled.
 * @retval  None.
 */
void st7789_draw_pixel(uint16_t x, uint16_t y, uint16_t color)
{
    uint8_t data[2];
    data[0] = color >> 8;
    data[1] = color;
    st7789_set_address(x, y, x, y);
    st7789_cfg_dcx_set();
    st7789_cfg_spi_write(data, 2);
}
posted @ 2021-11-09 22:25  xixizhk  阅读(1610)  评论(0编辑  收藏  举报