mameng 发表于 2021-12-21 23:22

[复旦微FM33LG0系列开发板测评] 驱动RGB TFT显示屏

<p>&nbsp; &nbsp; &nbsp;今天冬至,看到朋友圈都在吃饺子。想写个祝福大家冬至的话题。手里有个中景园电子技术有限公司320RGB*480 dots matrix TFT LCD 模块,想用FM33LG0驱动一下:</p>

<p>&nbsp; &nbsp;</p>

<p>&nbsp; &nbsp;PIN定义:</p>

<p></p>

<p>逻辑时序图:</p>

<p>&nbsp; 普通口模拟:</p>

<pre>
<code>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, &amp;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, &amp;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);
}</code></pre>

<pre>
<code>
#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)        </code></pre>

<p>驱动代码:</p>

<pre>
<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, &amp;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, &amp;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&lt;8;i++)
        {                          
                LCD_SCLK_Clr();
                if(dat&amp;0x80)
                {
                   LCD_MOSI_Set();
                }
                else
                {
                   LCD_MOSI_Clr();
                }
                LCD_SCLK_Set();
                dat&lt;&lt;=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&gt;&gt;16);
        LCD_Writ_Bus(dat&gt;&gt;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&gt;&gt;8);
        LCD_WR_DATA8(x1);
        LCD_WR_DATA8(x2&gt;&gt;8);
        LCD_WR_DATA8(x2);
        LCD_WR_REG(0x2b);//行地址设置
        LCD_WR_DATA8(y1&gt;&gt;8);
        LCD_WR_DATA8(y1);
        LCD_WR_DATA8(y2&gt;&gt;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);
}







</code></pre>

<p>main<br />
&nbsp;</p>

<pre>
<code>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);</code></pre>

<p>效果如下:</p>

<p></p>

<p>测试视频:</p>

<p><iframe allowfullscreen="true" frameborder="0" height="350" src="//player.bilibili.com/player.html?bvid=1cM4y1w7s4&amp;page=1" style="background:#eee;margin-bottom:10px;" width="550"></iframe><br />
总结:库函数跟STM32命名和其他底层驱动略有不同,需要耐心细致。</p>

hjx12345 发表于 2024-7-19 15:29

<p>复旦微代理商</p>
页: [1]
查看完整版本: [复旦微FM33LG0系列开发板测评] 驱动RGB TFT显示屏