wangpeng 发表于 2022-1-5 16:24:21

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

[复旦微FM33LG0系列开发板测评] 驱动SPI TFT显示
原帖地址:[复旦微FM33LG0系列开发板测评] 驱动SPI TFT显示 - 国产芯片交流 - 电子工程世界-论坛 (eeworld.com.cn)

看到淘宝有个9.9元的LCD SPI屏,拍下。买来发现是ST7735芯片控制的,一般淘宝里卖的比较多的基本是12864或者是由ILI93XX驱动的,用ST7735的比较少,所以我想写一篇关于ST7735的博文。在驱动屏幕之前我们需要看看它的产品手册。st7735有两种驱动方式,其中一种SPI通讯,另外一个是总线驱动。由于我买的液晶屏是SPI通讯的,所以我只讨论spi驱动。手册上有两个SPI通讯的时序图,分别是SPI三线和SPI四线。其实本质都是一样,只是三线SPI比四线SPI少了一个数据命令切换的控制。

http://bbs.eeworld.com.cn/data/attachment/forum/202112/01/195300af2zm99p1u6gufgu.jpg.thumb.jpg
http://bbs.eeworld.com.cn/data/attachment/forum/202112/01/195300ruqd83688338tjtl.jpg.thumb.jpgSPI7735SPI三线时序图
http://bbs.eeworld.com.cn/data/attachment/forum/202112/01/195900vgb6gln6616glcg7.jpg.thumb.jpgST7735SPI四线时序图:
http://bbs.eeworld.com.cn/data/attachment/forum/202112/01/195901doz773od4ob9idvm.jpg.thumb.jpg

   做驱动程序。移植一下午。搞定。

驱动函数:
#include "lcd_init.h"
//#include "delay.h"

void LCD_GPIO_Init(void)
{
//      GPIO_InitTypeDefGPIO_InitStructure;
//         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);         //使能A端口时钟
//      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;         
//         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
//      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
//         GPIO_Init(GPIOA, &GPIO_InitStructure);          //初始化GPIOA
//         GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5);
      
      
      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);
   
    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_5;
    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);
}


/******************************************************************************
      函数说明:LCD串行数据写入函数
      入口数据:dat要写入的串行数据
      返回值:无
******************************************************************************/
void LCD_Writ_Bus(unsigned char dat)
{      
      unsigned char 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(unsigned char dat)
{
      LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:无
******************************************************************************/
void LCD_WR_DATA(unsigned short dat)
{
      LCD_Writ_Bus(dat>>8);
      LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:无
******************************************************************************/
void LCD_WR_REG(unsigned char dat)
{
      LCD_DC_Clr();//写命令
      LCD_Writ_Bus(dat);
      LCD_DC_Set();//写数据
}


/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:无
******************************************************************************/
void LCD_Address_Set(unsigned short x1,unsigned short y1,unsigned short x2,unsigned short y2)
{
      if(USE_HORIZONTAL==0)
      {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+2);
                LCD_WR_DATA(x2+2);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+1);
                LCD_WR_DATA(y2+1);
                LCD_WR_REG(0x2c);//储存器写
      }
      else if(USE_HORIZONTAL==1)
      {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+2);
                LCD_WR_DATA(x2+2);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+1);
                LCD_WR_DATA(y2+1);
                LCD_WR_REG(0x2c);//储存器写
      }
      else if(USE_HORIZONTAL==2)
      {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+1);
                LCD_WR_DATA(x2+1);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+2);
                LCD_WR_DATA(y2+2);
                LCD_WR_REG(0x2c);//储存器写
      }
      else
      {
                LCD_WR_REG(0x2a);//列地址设置
                LCD_WR_DATA(x1+1);
                LCD_WR_DATA(x2+1);
                LCD_WR_REG(0x2b);//行地址设置
                LCD_WR_DATA(y1+2);
                LCD_WR_DATA(y2+2);
                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
      //------------------------------------ST7735S Frame Rate-----------------------------------------//
      LCD_WR_REG(0xB1);
      LCD_WR_DATA8(0x05);
      LCD_WR_DATA8(0x3C);
      LCD_WR_DATA8(0x3C);
      LCD_WR_REG(0xB2);
      LCD_WR_DATA8(0x05);
      LCD_WR_DATA8(0x3C);
      LCD_WR_DATA8(0x3C);
      LCD_WR_REG(0xB3);
      LCD_WR_DATA8(0x05);
      LCD_WR_DATA8(0x3C);
      LCD_WR_DATA8(0x3C);
      LCD_WR_DATA8(0x05);
      LCD_WR_DATA8(0x3C);
      LCD_WR_DATA8(0x3C);
      //------------------------------------End ST7735S Frame Rate---------------------------------//
      LCD_WR_REG(0xB4); //Dot inversion
      LCD_WR_DATA8(0x03);
      //------------------------------------ST7735S Power Sequence---------------------------------//
      LCD_WR_REG(0xC0);
      LCD_WR_DATA8(0x28);
      LCD_WR_DATA8(0x08);
      LCD_WR_DATA8(0x04);
      LCD_WR_REG(0xC1);
      LCD_WR_DATA8(0XC0);
      LCD_WR_REG(0xC2);
      LCD_WR_DATA8(0x0D);
      LCD_WR_DATA8(0x00);
      LCD_WR_REG(0xC3);
      LCD_WR_DATA8(0x8D);
      LCD_WR_DATA8(0x2A);
      LCD_WR_REG(0xC4);
      LCD_WR_DATA8(0x8D);
      LCD_WR_DATA8(0xEE);
      //---------------------------------End ST7735S Power Sequence-------------------------------------//
      LCD_WR_REG(0xC5); //VCOM
      LCD_WR_DATA8(0x1A);
      LCD_WR_REG(0x36); //MX, MY, RGB mode
      if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
      else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
      else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
      else LCD_WR_DATA8(0xA0);
      //------------------------------------ST7735S Gamma Sequence---------------------------------//
      LCD_WR_REG(0xE0);
      LCD_WR_DATA8(0x04);
      LCD_WR_DATA8(0x22);
      LCD_WR_DATA8(0x07);
      LCD_WR_DATA8(0x0A);
      LCD_WR_DATA8(0x2E);
      LCD_WR_DATA8(0x30);
      LCD_WR_DATA8(0x25);
      LCD_WR_DATA8(0x2A);
      LCD_WR_DATA8(0x28);
      LCD_WR_DATA8(0x26);
      LCD_WR_DATA8(0x2E);
      LCD_WR_DATA8(0x3A);
      LCD_WR_DATA8(0x00);
      LCD_WR_DATA8(0x01);
      LCD_WR_DATA8(0x03);
      LCD_WR_DATA8(0x13);
      LCD_WR_REG(0xE1);
      LCD_WR_DATA8(0x04);
      LCD_WR_DATA8(0x16);
      LCD_WR_DATA8(0x06);
      LCD_WR_DATA8(0x0D);
      LCD_WR_DATA8(0x2D);
      LCD_WR_DATA8(0x26);
      LCD_WR_DATA8(0x23);
      LCD_WR_DATA8(0x27);
      LCD_WR_DATA8(0x27);
      LCD_WR_DATA8(0x25);
      LCD_WR_DATA8(0x2D);
      LCD_WR_DATA8(0x3B);
      LCD_WR_DATA8(0x00);
      LCD_WR_DATA8(0x01);
      LCD_WR_DATA8(0x04);
      LCD_WR_DATA8(0x13);
      //------------------------------------End ST7735S Gamma Sequence-----------------------------//
      LCD_WR_REG(0x3A); //65k mode
      LCD_WR_DATA8(0x05);
      LCD_WR_REG(0x29); //Display on
}


mian()://主函数#include "main.h"
#include "user_init.h"
#include "lcd_init.h"
#include "lcd.h"


int main(void)
{
    /* Reset of all peripherals, Initializes the Flash inte**ce and the Systick. */
    /* SHOULD BE KEPT!!! */
    MF_Clock_Init();

    /* Configure the system clock */
    /* SHOULD BE KEPT!!! */
    MF_SystemClock_Config();

    /* Initialize FL Driver Library */
    /* SHOULD BE KEPT!!! */
    FL_Init();

    /* Initialize all configured peripherals */
    /* SHOULD BE KEPT!!! */
    MF_Config_Init();

    UserInit();


                LCD_Init();//LCD初始化
                LCD_Fill(0,0,LCD_W,LCD_H,BLUE);
                FL_DelayMs(100);
                LCD_ShowString(18,30,"Fudan",WHITE,BLUE,32,0);
                LCD_ShowString(5,90,"FM33LG0",WHITE,BLUE,32,0);
                FL_DelayMs(10);
      while(1)
    {
      LED0_TOG();
//                        printf("祝福复旦微电子越办越好!\r\n");
      FL_DelayMs(1000);
    }
}
页: [1]
查看完整版本: [复旦微FM33LG0系列开发板测评] 驱动SPI TFT显示