[Fudan Micro FM33LG0 Series Development Board Review] Driving RGB TFT Display
[Copy link]
Today is the winter solstice, and I saw that everyone in my circle of friends is eating dumplings. I want to write a topic to wish everyone a happy winter solstice. I have a 320RGB*480 dots matrix TFT LCD module from Zhongjingyuan Electronic Technology Co., Ltd., and I want to use FM33LG0 to drive it:
PIN definition:
Logic timing diagram:
Ordinary port simulation:
void LCD_GPIO_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOA, FL_GPIO_PIN_0|FL_GPIO_PIN_1|FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_5|FL_GPIO_PIN_6|FL_GPIO_PIN_7);
GPIO_InitStruct.pin = FL_GPIO_PIN_0|FL_GPIO_PIN_1|FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_6|FL_GPIO_PIN_7;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOA, &GPIO_InitStruct);
FL_GPIO_ResetOutputPin(GPIOB, FL_GPIO_PIN_5);
GPIO_InitStruct.pin = FL_GPIO_PIN_5;
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT ;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_7);
}
#define LCD_SCLK_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_0)//SCL=SCLK
#define LCD_SCLK_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_0)
#define LCD_MOSI_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_1)//SDA=MOSI
#define LCD_MOSI_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_1)
#define LCD_RES_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_2)//RES
#define LCD_RES_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_2)
#define LCD_DC_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_3)//DC
#define LCD_DC_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_3)
#define LCD_BLK_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_4)//BLK
#define LCD_BLK_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_4)
#define ZK_MISO FL_GPIO_ReadInputPort(GPIOB)//MISO 读取字库数据引脚
// GPIO_ReadInputDataBit
//GPIO_ResetBits
#define LCD_CS_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_6)//CS
#define LCD_CS_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_6)
#define ZK_CS_Clr() FL_GPIO_ResetOutputPin(GPIOA,FL_GPIO_PIN_7)
#define ZK_CS_Set() FL_GPIO_SetOutputPin(GPIOA,FL_GPIO_PIN_7)
Driver code:
#include "lcd_init.h"
void LCD_GPIO_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
FL_GPIO_ResetOutputPin(GPIOA, FL_GPIO_PIN_0|FL_GPIO_PIN_1|FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_5|FL_GPIO_PIN_6|FL_GPIO_PIN_7);
GPIO_InitStruct.pin = FL_GPIO_PIN_0|FL_GPIO_PIN_1|FL_GPIO_PIN_2|FL_GPIO_PIN_3|FL_GPIO_PIN_4|FL_GPIO_PIN_6|FL_GPIO_PIN_7;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOA, &GPIO_InitStruct);
FL_GPIO_ResetOutputPin(GPIOB, FL_GPIO_PIN_5);
GPIO_InitStruct.pin = FL_GPIO_PIN_5;
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT ;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
FL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6|GPIO_Pin_7);
}
/******************************************************************************
函数说明:LCD串行数据写入函数
入口数据:dat 要写入的串行数据
返回值: 无
******************************************************************************/
void LCD_Writ_Bus(u8 dat)
{
u8 i;
LCD_CS_Clr();
for(i=0;i<8;i++)
{
LCD_SCLK_Clr();
if(dat&0x80)
{
LCD_MOSI_Set();
}
else
{
LCD_MOSI_Clr();
}
LCD_SCLK_Set();
dat<<=1;
}
LCD_CS_Set();
}
/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA8(u8 dat)
{
LCD_Writ_Bus(dat);
}
/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA(u32 dat)
{
LCD_Writ_Bus(dat>>16);
LCD_Writ_Bus(dat>>8);
LCD_Writ_Bus(dat);
}
/******************************************************************************
函数说明:LCD写入命令
入口数据:dat 写入的命令
返回值: 无
******************************************************************************/
void LCD_WR_REG(u8 dat)
{
LCD_DC_Clr();//写命令
LCD_Writ_Bus(dat);
LCD_DC_Set();//写数据
}
/******************************************************************************
函数说明:设置起始和结束地址
入口数据:x1,x2 设置列的起始和结束地址
y1,y2 设置行的起始和结束地址
返回值: 无
******************************************************************************/
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
{
LCD_WR_REG(0x2a);//列地址设置
LCD_WR_DATA8(x1>>8);
LCD_WR_DATA8(x1);
LCD_WR_DATA8(x2>>8);
LCD_WR_DATA8(x2);
LCD_WR_REG(0x2b);//行地址设置
LCD_WR_DATA8(y1>>8);
LCD_WR_DATA8(y1);
LCD_WR_DATA8(y2>>8);
LCD_WR_DATA8(y2);
LCD_WR_REG(0x2c);//储存器写
}
void LCD_Init(void)
{
LCD_GPIO_Init();//初始化GPIO
LCD_RES_Clr();//复位
FL_DelayMs(100);
LCD_RES_Set();
FL_DelayMs(100);
LCD_BLK_Set();//打开背光
FL_DelayMs(100);
//************* Start Initial Sequence **********//
LCD_WR_REG(0x11); //Sleep out
FL_DelayMs(120); //Delay 120ms
//************* Start Initial Sequence **********//
LCD_WR_REG(0XF2);
LCD_WR_DATA8(0x18);
LCD_WR_DATA8(0xA3);
LCD_WR_DATA8(0x12);
LCD_WR_DATA8(0x02);
LCD_WR_DATA8(0XB2);
LCD_WR_DATA8(0x12);
LCD_WR_DATA8(0xFF);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0XF8);
LCD_WR_DATA8(0x21);
LCD_WR_DATA8(0x04);
LCD_WR_REG(0X13);
LCD_WR_REG(0x36); // Memory Access Control
if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x08);
else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC8);
else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x78);
else LCD_WR_DATA8(0xA8);
LCD_WR_REG(0xB4);
LCD_WR_DATA8(0x02);
LCD_WR_REG(0xB6);
LCD_WR_DATA8(0x02);
LCD_WR_DATA8(0x22);
LCD_WR_REG(0xC1);
LCD_WR_DATA8(0x41);
LCD_WR_REG(0xC5);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x18);
LCD_WR_REG(0x3a);
LCD_WR_DATA8(0x66);
FL_DelayMs(50);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x1F);
LCD_WR_DATA8(0x1C);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x98);
LCD_WR_DATA8(0x37);
LCD_WR_DATA8(0x0A);
LCD_WR_DATA8(0x13);
LCD_WR_DATA8(0x04);
LCD_WR_DATA8(0x11);
LCD_WR_DATA8(0x0D);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0xE1);
LCD_WR_DATA8(0x0F);
LCD_WR_DATA8(0x32);
LCD_WR_DATA8(0x2E);
LCD_WR_DATA8(0x0B);
LCD_WR_DATA8(0x0D);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x47);
LCD_WR_DATA8(0x75);
LCD_WR_DATA8(0x37);
LCD_WR_DATA8(0x06);
LCD_WR_DATA8(0x10);
LCD_WR_DATA8(0x03);
LCD_WR_DATA8(0x24);
LCD_WR_DATA8(0x20);
LCD_WR_DATA8(0x00);
LCD_WR_REG(0x11);
FL_DelayMs(120);
LCD_WR_REG(0x29);
LCD_WR_REG(0x2C);
}
main
Display_GB2312_String(10,50,32, "祝大家冬至吃水饺",WHITE,BLACK);
Display_GB2312_String(10,100,32, "祝大家冬至吃水饺",RED,BLACK);
Display_GB2312_String(10,150,32, "祝大家冬至吃水饺",BLUE,BLACK);
Display_GB2312_String(10,200,32, "祝大家冬至吃水饺",GREEN,BLACK);
The effect is as follows:
Test video:
Summary: The library function naming is slightly different from STM32 and other underlying drivers, which requires patience and meticulousness.
|