测试下使用开发板IO口方式驱动16位总线TFTLCD。
一、电路图
开发板上LCD接口部分电路图
转接板
硬件接口设计中间转接板,将开发板的接口定义转换成显示屏模块的接口。
二、代码
st7789.c
#include "board_init.h"
#include "hal_gpio.h"
#include "hal_rcc.h"
#include "st7789s.h"
#include "delay.h"
#include "font.h"
uint16_t POINT_COLOR=0x0000; //»±ÊÑÕÉ«
uint16_t BACK_COLOR=0xFFFF; //±³¾°É«
_lcd_dev lcddev;
static void ST7789_Reset(void)
{
LCD_SetRst();
delay_ms(1);
LCD_ClrRst();
delay_ms(10); // Delayms 10ms // This delay time is necessary
LCD_SetRst();
delay_ms(120); // Delayms 120 ms
}
void ST7789_Gpio_Writedat(uint16_t dat)
{
uint16_t temp_rpd, rpd;
uint16_t temp_rpe, rpe;
temp_rpd=GPIO_ReadOutData(GPIOD);
rpd=((dat>>5)&0x700) | ((dat<<14)&0xc000) | ((dat>>2)&0x03);
temp_rpd= (temp_rpd&(~0xc703))|rpd;
GPIO_WriteBits(GPIOD,temp_rpd);
//printf("rpd=%04x\r\n",rpd);
temp_rpe=temp_rpd=GPIO_ReadOutData(GPIOE);
rpe=(dat<<3)&0xff80; //1111 1111 1000 0000
temp_rpe=(temp_rpe&(~0xff80))|rpe;
GPIO_WriteBits(GPIOE,temp_rpe);
//printf("rpe=%04x\r\n",rpe);
/* temp_rpd=GPIO_ReadOutData(GPIOD)&0xc703;//1100 0111 0000 0011
printf("dat =%04x , ",dat);
printf("temp_rpd=%04x , ",temp_rpd);
temp_rpe=GPIO_ReadOutData(GPIOE)&0xff80; //1111 1111 1000 0000
printf("temp_rpe=%04x\r\n",temp_rpe);*/
}
void ST7789_WriteCommand(uint16_t cmd)
{
LCD_ClrCs(); //cs=0
LCD_ClrRs(); //rs=0
LCD_SetRd(); //rd=1
LCD_ClrWr(); //wr=0
//GPIO_Write(GPIOE, cmd);
ST7789_Gpio_Writedat(cmd);
LCD_SetWr(); //wr=1
LCD_SetCs(); //cs=1
LCD_SetRs(); //rs=1
}
void ST7789_WriteData(uint16_t dat)
{
LCD_SetRs(); //rs=1
LCD_ClrCs(); //cs=0
LCD_SetRd(); //rd=1
LCD_ClrWr(); //wr=0
ST7789_Gpio_Writedat(dat);
LCD_SetWr(); //wr=1
LCD_SetCs(); //cs=1
}
//ÉèÖÃLCDÏÔʾ·½Ïò
//dir:0,ÊúÆÁ£»1,ºáÆÁ
void LCD_Display_Dir(uint8_t dir)
{
if(dir==0) //ÊúÆÁ
{
lcddev.dir=0; //ÊúÆÁ
lcddev.width=240;
lcddev.height=320;
}else //ºáÆÁ
{
lcddev.dir=1; //ºáÆÁ
lcddev.width=320;
lcddev.height=240;
}
//LCD_Scan_Dir(DFT_SCAN_DIR); //ĬÈÏɨÃè·½Ïò
}
void init_st7789s(void)
{
GPIO_Init_Type gpio_init;
/* GPIOD. */
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOD, true);
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOD);
/* GPIOE. */
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOE, true);
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOE);
/* GPIOG. */
RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOG, true);
RCC_ResetAHB1Periphs(RCC_AHB1_PERIPH_GPIOG);
gpio_init.Pins = GPIO_PIN_15|GPIO_PIN_14|GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_1|GPIO_PIN_0;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpio_init);
gpio_init.Pins = GPIO_PIN_15|GPIO_PIN_14|GPIO_PIN_13|GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7|GPIO_PIN_3|GPIO_PIN_2;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &gpio_init);
gpio_init.Pins = GPIO_PIN_11|GPIO_PIN_12;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &gpio_init);
ST7789_Reset();
ST7789_WriteCommand(0x0011); //exit SLEEP mode
delay_ms(120);
ST7789_WriteCommand(0x0036);
ST7789_WriteData(0x0060); //MADCTL: memory data access control
ST7789_WriteCommand(0x003A);
ST7789_WriteData(0x0005); //COLMOD: Interface Pixel format *** I use 262K-colors in 18bit/pixel format when using 8-bit interface to allow 3-bytes per pixel
// ST7789_WriteCommand(0x003A);ST7789_WriteData(0x0055);//COLMOD: Interface Pixel format *** I use 65K-colors in 16bit/pixel (5-6-5) format when using 16-bit interface to allow 1-byte per pixel
ST7789_WriteCommand(0x00B2);
ST7789_WriteData(0x000C);
ST7789_WriteData(0x000C);
ST7789_WriteData(0x0000);
ST7789_WriteData(0x0033);
ST7789_WriteData(0x0033); //PORCTRK: Porch setting
ST7789_WriteCommand(0x00B7);
ST7789_WriteData(0x0035); //GCTRL: Gate Control
ST7789_WriteCommand(0x00BB);
ST7789_WriteData(0x001c); //VCOMS: VCOM setting
ST7789_WriteCommand(0x00C0);
ST7789_WriteData(0x002C); //LCMCTRL: LCM Control
ST7789_WriteCommand(0x00C2);
ST7789_WriteData(0x0001);
ST7789_WriteData(0x00FF); //VDVVRHEN: VDV and VRH Command Enable
ST7789_WriteCommand(0x00C3);
ST7789_WriteData(0x000B); //VRHS: VRH Set
ST7789_WriteCommand(0x00C4);
ST7789_WriteData(0x0020); //VDVS: VDV Set
ST7789_WriteCommand(0x00C6);
ST7789_WriteData(0x000F); //FRCTRL2: Frame Rate control in normal mode
ST7789_WriteCommand(0x00D0);
ST7789_WriteData(0x00A4);
ST7789_WriteData(0x00A1); //PWCTRL1: Power Control 1
ST7789_WriteCommand(0x00E0);
ST7789_WriteData(0x00D0);
ST7789_WriteData(0x0000);
ST7789_WriteData(0x0003);
ST7789_WriteData(0x0009);
ST7789_WriteData(0x0013);
ST7789_WriteData(0x001c);
ST7789_WriteData(0x003a);
ST7789_WriteData(0x0055);
ST7789_WriteData(0x0048);
ST7789_WriteData(0x0018);
ST7789_WriteData(0x0012);
ST7789_WriteData(0x000e);
ST7789_WriteData(0x0019);
ST7789_WriteData(0x001e); //PVGAMCTRL: Positive Voltage Gamma control
ST7789_WriteCommand(0x00E1);
ST7789_WriteData(0x00D0);
ST7789_WriteData(0x0000);
ST7789_WriteData(0x0003);
ST7789_WriteData(0x0009);
ST7789_WriteData(0x0005);
ST7789_WriteData(0x0025);
ST7789_WriteData(0x003a);
ST7789_WriteData(0x0055);
ST7789_WriteData(0x0050);
ST7789_WriteData(0x003d);
ST7789_WriteData(0x001c);
ST7789_WriteData(0x001d);
ST7789_WriteData(0x001d);
ST7789_WriteData(0x001e);
ST7789_WriteCommand(0x0029); //display ON
ST7789_WriteCommand(0x002c);
printf("\n\r st7789 init ok! \r ");
LCD_Display_Dir(1);
LCD_BLA_ON();
}
void Lcd_SetBox(uint16_t xStart, uint16_t yStart, uint16_t xlong, uint16_t ylong)
{
uint16_t xEnd=0, yEnd=0;
xEnd=xStart+xlong-1;
yEnd=yStart+ylong-1;
ST7789_WriteCommand(0x2a);
ST7789_WriteData(xStart>>8);
ST7789_WriteData(xStart);
ST7789_WriteData(xEnd>>8);
ST7789_WriteData(xEnd);
ST7789_WriteCommand(0x2b);
ST7789_WriteData(yStart>>8);
ST7789_WriteData(yStart);
ST7789_WriteData(yEnd>>8);
ST7789_WriteData(yEnd);
ST7789_WriteCommand(0x2c);
}
void Lcd_SetBox1(uint16_t xStart, uint16_t xEnd, uint16_t yStart, uint16_t yEnd)
{
ST7789_WriteCommand(0x2a);
ST7789_WriteData(xStart>>8);
ST7789_WriteData(xStart);
ST7789_WriteData(xEnd>>8);
ST7789_WriteData(xEnd);
ST7789_WriteCommand(0x2b);
ST7789_WriteData(yStart>>8);
ST7789_WriteData(yStart);
ST7789_WriteData(yEnd>>8);
ST7789_WriteData(yEnd);
ST7789_WriteCommand(0x2c);
}
void LCD_WriteOneDot(uint16_t color)
{
ST7789_WriteData(color);
}
void LCD_Clear(uint16_t Color)
{
uint32_t i;
Lcd_SetBox(0,0,320,240);
for(i=0;i<78900;i++){
LCD_WriteOneDot(Color);
}
}
void ST7789_SetPoint(uint16_t x, uint16_t y, uint16_t color)
{
Lcd_SetBox1(x,x+1,y,y+1);
LCD_WriteOneDot(color);
}
//ÔÚÖ¸¶¨Î»ÖÃÏÔʾһ¸ö×Ö·û
//x,y:Æðʼ×ø±ê
//num:ÒªÏÔʾµÄ×Ö·û:" "--->"~"
//size:×ÖÌå´óС 12/16/24
//mode:µþ¼Ó·½Ê½(1)»¹ÊǷǵþ¼Ó·½Ê½(0)
void LCD_ShowChar(uint16_t x, uint16_t y, uint8_t num, uint8_t size, uint8_t mode)
{
uint8_t temp,t1,t;
uint8_t y0=y;
uint8_t csize=(size/8+((size%8)?1:0))*(size/2); //µÃµ½×ÖÌåÒ»¸ö×Ö·û¶ÔÓ¦µãÕó¼¯ËùÕ¼µÄ×Ö½ÚÊý
num=num-' ';//µÃµ½Æ«ÒƺóµÄÖµ£¨ASCII×Ö¿âÊÇ´Ó¿Õ¸ñ¿ªÊ¼È¡Ä££¬ËùÒÔ-' '¾ÍÊǶÔÓ¦×Ö·ûµÄ×ֿ⣩
for(t=0;t<csize;t++)
{
if(size==12)temp=asc2_1206[num][t]; //µ÷ÓÃ1206×ÖÌå
else if(size==16)temp=asc2_1608[num][t]; //µ÷ÓÃ1608×ÖÌå
else if(size==24)temp=asc2_2412[num][t]; //µ÷ÓÃ2412×ÖÌå
else return; //ûÓеÄ×Ö¿â
for(t1=0;t1<8;t1++)
{
if(temp&0x80)ST7789_SetPoint(x,y,POINT_COLOR);
else if(mode==0)ST7789_SetPoint(x,y,BACK_COLOR);
temp<<=1;
y++;
if(y>=lcddev.height)return; //³¬ÇøÓòÁË
if((y-y0)==size)
{
y=y0;
x++;
if(x>=lcddev.width)return; //³¬ÇøÓòÁË
break;
}
}
}
}
//ÏÔʾ×Ö·û´®
//x,y:Æðµã×ø±ê
//width,height:ÇøÓò´óС
//size:×ÖÌå´óС
//*p:×Ö·û´®ÆðʼµØÖ·
void LCD_ShowString(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, uint8_t *p)
{
uint8_t x0=x;
width+=x;
height+=y;
while((*p<='~')&&(*p>=' '))//ÅжÏÊDz»ÊÇ·Ç·¨×Ö·û!
{
if(x>=width){x=x0;y+=size;}
if(y>=height)break;//Í˳ö
LCD_ShowChar(x,y,*p,size,0);
x+=size/2;
p++;
}
}
st7789.h
#ifndef __ST7789S_H__
#define __ST7789S_H__
#include "board_init.h"
typedef struct
{
uint16_t width;
uint16_t height;
uint16_t id;
uint8_t dir;
uint16_t wramcmd;
uint16_t setxcmd;
uint16_t setycmd;
}_lcd_dev;
extern _lcd_dev lcddev;
extern uint16_t POINT_COLOR;
extern uint16_t BACK_COLOR;
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define BACKCOLOR 0xFFFF
#define WORDCOLOR 0x0000
/* Ƭѡ */
#define LCD_SetCs() {GPIO_WriteBit(GPIOG, GPIO_PIN_12, 1u);}
#define LCD_ClrCs() {GPIO_WriteBit(GPIOG, GPIO_PIN_12, 0u);}
/* ¸´Î» */
#define LCD_SetRst() {GPIO_WriteBit(GPIOG, GPIO_PIN_11, 1);}
#define LCD_ClrRst() {GPIO_WriteBit(GPIOG, GPIO_PIN_11, 0);}
/* /RD */
#define LCD_SetRd() {GPIO_WriteBit(GPIOD, GPIO_PIN_4, 1);}
#define LCD_ClrRd() {GPIO_WriteBit(GPIOD, GPIO_PIN_4, 0);}
/* /WR */
#define LCD_SetWr() {GPIO_WriteBit(GPIOD, GPIO_PIN_5, 1);}
#define LCD_ClrWr() {GPIO_WriteBit(GPIOD, GPIO_PIN_5, 0);}
/* BLA */
#define LCD_BLA_ON() {GPIO_WriteBit(GPIOE, GPIO_PIN_3, 1);}
#define LCD_BLA_OFF() {GPIO_WriteBit(GPIOE, GPIO_PIN_3, 0);}
/* RS */
#define LCD_SetRs() {GPIO_WriteBit(GPIOE, GPIO_PIN_2, 1);}
#define LCD_ClrRs() {GPIO_WriteBit(GPIOE, GPIO_PIN_2, 0);}
void init_st7789s(void);
void LCD_Clear(uint16_t Color);
void LCD_ShowString(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, uint8_t *p);
#endif
main.c
/*
* Copyright 2021 MindMotion Microelectronics Co., Ltd.
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "board_init.h"
#include "hal_flexcan.h"
#include "hal_gpio.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "flexcan.h"
#include "st7789s.h"
int main(void)
{
BOARD_Init();
delay_init();
init_led();
//init_key();
//init_flexcan1();
init_st7789s();
POINT_COLOR=RED;
LCD_Clear(WHITE);
printf("\r\nmm32f5270 test.\r\n");
LCD_ShowString(30,40,210,24,24,"MM32F5270");
LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");
LCD_ShowString(30,90,200,16,16,"ST7789");
LCD_ShowString(30,110,200,16,16,"2022/09/01");
LCD_ShowString(30,150,210,24,24,"https://aijishu.com");
while(1)
{
GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 1u);
delay_ms(100);
GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 0u);
delay_ms(100);
}
}
三、程序运行
原作者:小会
更多回帖