1. 信号线设置
主要有有6条线:
- RESET:复位
- CS:片选
- DCX:数据/命令选择
- SCK:SPI时钟线
- SDA:数据线
- PWR:LED背光
这种配置下,MCU只向ST7789写数据而不读取数据。
2. SPI配置要求
- 主模式,仅发送,8bit模式
- 时钟极性为高,第二个边沿(上升沿)latch
- 时钟周期不要低于16ns
3. 关键函数介绍
- 需要根据硬件平台进行设置的函数,对应文件st7789_cfg.c/h;
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);
- 与硬件平台无关的函数(仅与上述函数相关),对应文件st7789.c/h;
void st7789_on(void);
void st7789_off(void);
void st7789_init(void);
void st7789_set_direction(uint8_t dir);
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);
void st7789_flush
(
uint16_t x1,
uint16_t y1,
uint16_t x2,
uint16_t y2,
uint16_t *color
);
4. 代码文件
- st7789_cfg.h
/**
*******************************************************************************
* @file st7789_cfg.h
* @author xixizhk
*******************************************************************************
* @version V20211108 \n
* Initial version.
*******************************************************************************
*/
/* Define to prevent recursive inclusion **************************************/
#ifndef _ST7789_CFG_H
#define _ST7789_CFG_H
#ifdef __cplusplus
extern "C" {
#endif
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "stm32g4xx_hal.h"
#include "main.h"
#include "spi.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
#define _ST7789_WIDTH 240
#define _ST7789_HEIGHT 240
#define _ST7789_BUFFER_SIZE 1024 /* 16-bit, less than 32768, even only */
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
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);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* _ST7789_CFG_H */
/**************************** ALL RIGHTS RESERVED *****************************/
- st7789_cfg.c
/**
*******************************************************************************
* @file st7789_cfg.c
* @author xixizhk
*******************************************************************************
* @version V20211108 \n
* Configure the low level interface for st7789.
*******************************************************************************
*/
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "st7789_cfg.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
/**
* @brief Set the PWR pin (back LED).
* @param None.
* @retval None.
*/
void st7789_cfg_pwr_set(void)
{
HAL_GPIO_WritePin(LCD_PWR_GPIO_Port, LCD_PWR_Pin, GPIO_PIN_SET);
}
/**
* @brief Reset the PWR pin (back LED).
* @param None.
* @retval None.
*/
void st7789_cfg_pwr_reset(void)
{
HAL_GPIO_WritePin(LCD_PWR_GPIO_Port, LCD_PWR_Pin, GPIO_PIN_RESET);
}
/**
* @brief Set the RESET pin.
* @param None.
* @retval None.
*/
void st7789_cfg_rst_set(void)
{
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
}
/**
* @brief Reset the RESET pin.
* @param None.
* @retval None.
*/
void st7789_cfg_rst_reset(void)
{
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
}
/**
* @brief Delay in ms.
* @param _ms [In]: number of microsecond.
* @retval None.
*/
void st7789_cfg_delay_ms(uint32_t _ms)
{
/* Functions based on interrupt such as HAL_Delay() not recommended,
* because it may result in blocking. Here, approximate delay is employed.
*/
uint32_t i, j;
for (i = 0; i < _ms; i++)
{
for (j = 0; j < 17000; j++)
{
;
}
}
}
/**
* @brief Set the CS pin.
* @param None.
* @retval None.
*/
void st7789_cfg_cs_set(void)
{
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
}
/**
* @brief Reset the CS pin.
* @param None.
* @retval None.
*/
void st7789_cfg_cs_reset(void)
{
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
}
/**
* @brief Set the DCX pin.
* @param None.
* @retval None.
*/
void st7789_cfg_dcx_set(void)
{
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_SET);
}
/**
* @brief Reset the DCX pin.
* @param None.
* @retval None.
*/
void st7789_cfg_dcx_reset(void)
{
HAL_GPIO_WritePin(LCD_DCX_GPIO_Port, LCD_DCX_Pin, GPIO_PIN_RESET);
}
/**
* @brief SPI write buffer.
* @param pbuf [In]: pointer to the buffer to be written.
* @param size [In]: size of the buffer to be written.
* @retval None.
*/
void st7789_cfg_spi_write(uint8_t *pbuf, uint16_t size)
{
HAL_SPI_Transmit(&hspi1, pbuf, size, 1000);
}
/**
* @}
*/
/**************************** ALL RIGHTS RESERVED *****************************/
- st7789.h
/**
*******************************************************************************
* @file st7789.h
* @author xixizhk
*******************************************************************************
* @version V20211108 \n
* Initial version.
* @version V20220406 \n
* Direction setting function added, Read function added for snapshot required
* by some GUI libraries (only 1-bit color supported, not verified).
*******************************************************************************
*/
/* Define to prevent recursive inclusion **************************************/
#ifndef _ST7789_H
#define _ST7789_H
#ifdef __cplusplus
extern "C" {
#endif
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "st7789_cfg.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
/**
* @brief Display direction
*/
#define _ST7789_DIRECTION_NORMAL 0U
#define _ST7789_DIRECTION_XMIRROR_YMIRROR 1U
#define _ST7789_DIRECTION_XYEXCHANGE_YMIRROR 2U
#define _ST7789_DIRECTION_XYEXCHANGE_XMIRROR 3U
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
void st7789_on(void);
void st7789_off(void);
void st7789_init(void);
void st7789_set_direction(uint8_t dir);
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);
void st7789_flush
(
uint16_t x1,
uint16_t y1,
uint16_t x2,
uint16_t y2,
uint16_t *color
);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* _ST7789_H */
/**************************** ALL RIGHTS RESERVED *****************************/
- st7789.c
/**
*******************************************************************************
* @file st7789.c
* @author xixizhk
*******************************************************************************
* @version V20211108 \n
* Driver for st7789 (st7789v2), initial version.
* @version V20220406 \n
* Direction setting function added, Read function added for snapshot required
* by some GUI libraries (only 1-bit color supported, not verified).
*******************************************************************************
*/
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "st7789.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
static uint8_t st7789_display_mode;
static uint8_t st7789_buffer[_ST7789_BUFFER_SIZE * 2];
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
static void st7789_set_window
(
uint16_t x1,
uint16_t y1,
uint16_t x2,
uint16_t y2
);
/**
* @brief Write a command to st7789.
* @param cmd [In]: command to be sent.
* @retval None.
*/
static void st7789_write_cmd(uint8_t cmd)
{
st7789_cfg_dcx_reset();
st7789_cfg_spi_write(&cmd, 1);
}
/**
* @brief Write a data to st7789.
* @param data [In]: data to be sent.
* @retval None.
*/
static void st7789_write_data(uint8_t data)
{
st7789_cfg_dcx_set();
st7789_cfg_spi_write(&data, 1);
}
/**
* @brief Turn on LCD.
* @param None.
* @retval None.
*/
void st7789_on(void)
{
st7789_cfg_pwr_set();
}
/**
* @brief Turn off LCD.
* @param None.
* @retval None.
*/
void st7789_off(void)
{
st7789_cfg_pwr_reset();
}
/**
* @brief Initialize the LCD.
* @param None.
* @retval None.
*/
void st7789_init(void)
{
/* Chip selection. */
st7789_cfg_cs_reset();
/* Reset. */
st7789_cfg_rst_reset();
st7789_cfg_delay_ms(200);
st7789_cfg_rst_set();
st7789_cfg_delay_ms(200);
/* Sleep Out */
st7789_write_cmd(0x11);
/* Wait for power stability */
st7789_cfg_delay_ms(200);
/* 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 mode setting. */
st7789_set_direction(_ST7789_DIRECTION_NORMAL);
/* Display on */
st7789_on();
st7789_fill(0, 0, _ST7789_WIDTH - 1, _ST7789_HEIGHT - 1, 0x001F);
st7789_write_cmd(0x29);
}
/**
* @brief Set display direction.
* @param dir [In]: Display direction, see _ST7789_DIRECTION_*.
* @retval None.
*/
void st7789_set_direction(uint8_t dir)
{
switch (dir)
{
case _ST7789_DIRECTION_NORMAL:
st7789_write_cmd(0x36);
st7789_write_data(0x00);
st7789_display_mode = _ST7789_DIRECTION_NORMAL;
break;
case _ST7789_DIRECTION_XMIRROR_YMIRROR:
st7789_write_cmd(0x36);
st7789_write_data(0xC0);
st7789_display_mode = _ST7789_DIRECTION_XMIRROR_YMIRROR;
break;
case _ST7789_DIRECTION_XYEXCHANGE_YMIRROR:
st7789_write_cmd(0x36);
st7789_write_data(0xA0);
st7789_display_mode = _ST7789_DIRECTION_XYEXCHANGE_YMIRROR;
break;
case _ST7789_DIRECTION_XYEXCHANGE_XMIRROR:
st7789_write_cmd(0x36);
st7789_write_data(0x60);
st7789_display_mode = _ST7789_DIRECTION_XYEXCHANGE_XMIRROR;
break;
default:
st7789_write_cmd(0x36);
st7789_write_data(0x00);
st7789_display_mode = _ST7789_DIRECTION_NORMAL;
break;
}
}
/**
* @brief Fill specified area with specified color (x1 <= x2, y1 <= y2).
* @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_window(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_window(x, y, x, y);
st7789_cfg_dcx_set();
st7789_cfg_spi_write(data, 2);
}
/**
* @brief Flush color to specified area (x1 <= x2, y1 <= y2), for some GUI.
* @param x1 [In]: start x.
* @param y1 [In]: start y.
* @param x2 [In]: end x.
* @param y2 [In]: end y.
* @param color [In]: pointer to the color buffer to be flushed.
* @retval None.
*/
void st7789_flush
(
uint16_t x1,
uint16_t y1,
uint16_t x2,
uint16_t y2,
uint16_t *color
)
{
uint16_t size = (x2 - x1 + 1) * (y2 - y1 + 1);
st7789_set_window(x1, y1, x2, y2);
st7789_cfg_dcx_set();
st7789_cfg_spi_write((uint8_t *)color, size * 2);
}
/**
* @brief Set window to be edited.
* y ^
* |
* | x
* ------------------>
* |
* |
* @param x1 [In]: start x.
* @param y1 [In]: start y.
* @param x2 [In]: end x.
* @param y2 [In]: end y.
* @retval None.
*/
static void st7789_set_window
(
uint16_t x1,
uint16_t y1,
uint16_t x2,
uint16_t y2
)
{
switch (st7789_display_mode)
{
case _ST7789_DIRECTION_NORMAL:
case _ST7789_DIRECTION_XYEXCHANGE_XMIRROR:
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);
break;
case _ST7789_DIRECTION_XYEXCHANGE_YMIRROR:
st7789_write_cmd(0x2A);
st7789_write_data((x1 + 80) >> 8);
st7789_write_data(x1 + 80);
st7789_write_data((x2 + 80) >> 8);
st7789_write_data(x2 + 80);
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);
break;
case _ST7789_DIRECTION_XMIRROR_YMIRROR:
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 + 80) >> 8);
st7789_write_data(y1 + 80);
st7789_write_data((y2 + 80) >> 8);
st7789_write_data(y2 + 80);
st7789_write_cmd(0x2C);
break;
default:
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);
break;
}
}
/**
* @}
*/
/**************************** ALL RIGHTS RESERVED *****************************/
Provided by 昨夜三更雨, see https://www.cnblogs.com/zysgy/p/15531272.html