電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 46|回復(fù): 0
收起左側(cè)

基于STM32 HAL庫硬件SPI的ST7789驅(qū)動(TFT-LCD 240*320)

[復(fù)制鏈接]

193

主題

193

帖子

1532

積分

三級會員

Rank: 3Rank: 3

積分
1532
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2021-4-4 12:36:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
點(diǎn)擊上方「嵌入式實(shí)驗(yàn)基地」,選擇「置頂公眾號」第一時間查看嵌入式筆記!

??在日常開發(fā)項(xiàng)目中,顯示屏是經(jīng)常使用的一個部件,顯示屏的種類也是多種多樣,但對于開發(fā)者來說,主要關(guān)心的是顯示屏所用到的驅(qū)動芯片,本次給小伙伴們帶來的是 STM32 下的 HAL 庫硬件 SPI 驅(qū)動 320*240 分辨率的 TFT-LCD,LCD 顯示屏驅(qū)動芯片為 ST7789,一步步實(shí)現(xiàn)如何驅(qū)動此類驅(qū)動芯片的 LCD 屏幕,話不多說,上干貨!
  • 完成目標(biāo)1、cubemx配置硬件SPI
    2、驅(qū)動240*320分辨率LCD顯示屏(驅(qū)動芯片為ST7789)
  • 硬件環(huán)境1、STM32F103C8T6(自設(shè)計(jì))
    2、ST7789驅(qū)動LCD顯示屏
  • 軟件環(huán)境1、cubemx
    2、keil5
    一、cubemx配置硬件SPI及LCD相關(guān)引腳1.1 時鐘配置
    ??第一步仍然是時鐘配置,由于板子上設(shè)計(jì)沒有預(yù)留外部晶振,我使用的是內(nèi)部RC振蕩器,內(nèi)部RC振蕩器只能配置到64MHZ,如下,如果你使用的是外部晶振,最大到72MHZ

    1.2 LCD與STM32硬件連接關(guān)系
    LCDMCULCD-RSTPB1LCD-CSPB0LCD-DCPA4LCD-MOSIPA7LCD-CLKPA5LCD-LDE+VCC-3.3(可接IO控制)LCD-LDE-GNDLCD-VCCVCC-3.3VLCD-GNDGND1.3 LCD相關(guān)引腳配置
    ??本次使用的是SPI1,對SPI1的引腳及參數(shù)進(jìn)行配置,相關(guān)IO初始化狀態(tài)可以根據(jù)需要進(jìn)行配置u,比如CS引腳,拉低有效,初始化我們可以配置為高,根據(jù)自己需要進(jìn)行配置即可




    ??小伙伴們有沒有遇到過配置完發(fā)現(xiàn)不能仿真,這里需要設(shè)置一下,根據(jù)自己的仿真器接口進(jìn)行配置,是SWD模式還是JTAG模式

    生成工程配置,配置完之后,直接點(diǎn)擊生成即可,注意工程路徑不要有中文,記得以前可以有,不知道什么時候有的臭毛病...只能按照做了


    二、代碼編寫??先定義LCD相關(guān)引腳,CS、RST、DC
    #define LCD_REST_LOW()   HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
    #define LCD_REST_HIGH()  HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
    #define LCD_DC_LOW()     HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);
    #define LCD_DC_HIGH()    HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
    #define LCD_CS_LOW()     HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
    #define LCD_CS_HIGH()    HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
    #define LCD_WR_RS(n) (n?HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET):HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET))
    ??定義用到的幾個基本函數(shù)
    /**
    * @brief  寫16位的數(shù)據(jù)(兩個字節(jié))到LCD
    * @param   dat —— 需要發(fā)送的16bit數(shù)據(jù)
    * @return  none
    */
    void LCD_Write_2Bytes(const uint16_t dat)
    {
        uint8_t data[2] = {0};
        data[0] = dat >> 8;
        LCD_data_write(data[0]);
        data[1] = dat;
        LCD_data_write(data[1]);
        // LCD_SPI_Send(data, 2);
    }
    void LCD_command_write(uint8_t command)
    { // 寫命令
        LCD_DC_LOW();
        LCD_CS_LOW();
        lcd_SendBytes(command);
        LCD_CS_HIGH();
    }
    void LCD_data_write(uint8_t data)
    { //寫數(shù)據(jù)
        LCD_DC_HIGH();
        LCD_CS_LOW();
        lcd_SendBytes(data);
        LCD_CS_HIGH();
    }
    void delay_lcd(unsigned int time)
    {
        while (time)
        {
            time--;
            time--;
            time--;
            time--;
        }
    }
    void LCD_Reset(void)
    {
        LCD_REST_HIGH();
        delay_lcd(1000);
        LCD_REST_LOW();
        delay_lcd(10000);
        LCD_REST_HIGH();
        delay_lcd(10000);
        LCD_CS_HIGH();
    }
    LCD行列設(shè)置
    //========================================================
    //CASET (2Ah): Column Address Set
    //RASET (2Bh): Row Address Set
    //x1,y1:起始地址,x2,y2:終點(diǎn)地址
    //========================================================
    void lcd_set_address(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
    {
        LCD_command_write(0x2a);
        LCD_data_write(x1 >> 8);
        LCD_data_write(x1);
        LCD_data_write(x2 >> 8);
        LCD_data_write(x2);
        LCD_command_write(0x2b);
        LCD_data_write(y1 >> 8);
        LCD_data_write(y1);
        LCD_data_write(y2 >> 8);
        LCD_data_write(y2);
        LCD_command_write(0x2C); // write_ram
    }
    LCD初始化代碼,這部分主要是參考網(wǎng)上已經(jīng)完成的,相關(guān)配置可以在手冊具體查看
    void lcd_init(void)
    {
        LCD_CS_HIGH();
        LCD_Reset();
        /************* display Setting *************/
        LCD_command_write(0x01);
        delay_lcd(10000);
        LCD_command_write(LCD_CMD_SLPOUT);
        delay_lcd(10000);

      //修改此處,可以改變屏幕的顯示方向,橫屏,豎屏等
        LCD_command_write(LCD_CMD_MADCTL); // 0x36  ///
        LCD_data_write(0x00);              //50//40//C0
        LCD_command_write(LCD_CMD_COLMOD); //  0x3A     ///
        LCD_data_write(0x05);              /// 16bit/pixel
        /*********** Frame Rate Setting ***********/
        LCD_command_write(LCD_CMD_PORCTRL); //0xB2     ///
        LCD_data_write(0x0c);               ///
        LCD_data_write(0x0c);               ///
        LCD_data_write(0x00);               ///
        LCD_data_write(0x33);               ///
        LCD_data_write(0x33);               ///
        LCD_command_write(LCD_CMD_GCTRL); //  0xB7     ///
        LCD_data_write(0x72);             ///
        LCD_command_write(LCD_CMD_VCOMS); // 0xBB     ///
        LCD_data_write(0x3d);             ///
        LCD_command_write(LCD_CMD_LCMCTRL); ///0xC0     ///
        LCD_data_write(0x2c);
        LCD_command_write(LCD_CMD_VDVVRHEN); //0xC2     ///
        LCD_data_write(0x01);
        LCD_data_write(0xFF);
        /* VRH Set */
        LCD_command_write(LCD_CMD_VRHS); //0xC3
        LCD_data_write(0x19);
        /* VDV Set */
        LCD_command_write(LCD_CMD_VDVS); //0xC4
        LCD_data_write(0x20);
        LCD_command_write(LCD_CMD_FRCTRL2); //  0xC6     ///
        LCD_data_write(0x0f);               ///
        LCD_command_write(LCD_CMD_PWCTRL1); // 0xD0     ///
        LCD_data_write(0xa4);
        LCD_data_write(0xa1); ///
        /* Positive Voltage Gamma Control */
        LCD_command_write(0xE0);
        LCD_data_write(0xD0);
        LCD_data_write(0x04);
        LCD_data_write(0x0D);
        LCD_data_write(0x11);
        LCD_data_write(0x13);
        LCD_data_write(0x2B);
        LCD_data_write(0x3F);
        LCD_data_write(0x54);
        LCD_data_write(0x4C);
        LCD_data_write(0x18);
        LCD_data_write(0x0D);
        LCD_data_write(0x0B);
        LCD_data_write(0x1F);
        LCD_data_write(0x23);
        /* Negative Voltage Gamma Control */
        LCD_command_write(0xE1);
        LCD_data_write(0xD0);
        LCD_data_write(0x04);
        LCD_data_write(0x0C);
        LCD_data_write(0x11);
        LCD_data_write(0x13);
        LCD_data_write(0x2C);
        LCD_data_write(0x3F);
        LCD_data_write(0x44);
        LCD_data_write(0x51);
        LCD_data_write(0x2F);
        LCD_data_write(0x1F);
        LCD_data_write(0x1F);
        LCD_data_write(0x20);
        LCD_data_write(0x23);
        // LCD_command_write( 0x21);     ///
        //LCD_command_write( 0x13);
        //LCD_InitSequence();
        //Display_logo();
        // lcd_clear(LCD_DISP_RED);
      lcd_clear(LCD_DISP_WRITE);
        LCD_command_write(LCD_CMD_DISPON); ///
    }
    常用顏色定義,為RGB565格式,其他顏色可以自己改變配比
    /************** 顏色(RGB 5,6,5) **************/
    #define LCD_DISP_RED                    0xF800       //先高字節(jié),后低字節(jié)      
    #define LCD_DISP_GREEN                  0x07E0
    #define LCD_DISP_BLUE                   0x001F
    #define LCD_DISP_WRITE                  0xFFFF
    #define LCD_DISP_BLACK                  0x0000
    #define LCD_DISP_GRAY                   0xEF5D
    #define LCD_DISP_GRAY75                 0x39E7
    #define LCD_DISP_GRAY50                 0x7BEF
    #define LCD_DISP_GRAY25                 0xADB5
    LCD清屏,可以填充指定的顏色
    //========================================================
    //LCD清屏  color:要寫入的顏色
    //先關(guān)顯示,等所有的數(shù)據(jù)寫入到RAM后,再打開顯示
    //========================================================
    void lcd_clear(uint16_t color)
    {
        uint16_t i, j;
        LCD_command_write(0x2A);
        LCD_data_write(0);
        LCD_data_write(0);
        LCD_data_write(0);
        LCD_data_write(240);
        LCD_command_write(0X2B);
        LCD_data_write(0);
        LCD_data_write(0);
        LCD_data_write(0X01);
        LCD_data_write(0X40);
        LCD_command_write(0X2C);
        for (i = 0; i 240; i++)
        {
            for (j = 0; j 320; j++)
            {
                LCD_data_write(color >> 8);
                LCD_data_write(color);
            }
        }
        lcd_display_on(); /* 開LCD顯示 */
    }
    ??還有一些打點(diǎn)、劃線、畫圓等函數(shù),就不再一一介紹了,編寫測試代碼,刷屏,畫圓、畫矩形、顯示漢字,一氣呵成,直接來看演示視頻吧~

            后面會分享更多有意思的顯示小項(xiàng)目,包括界面等的設(shè)計(jì),敬請期待吧!
    本次的介紹就到這里啦,后面有更精彩的內(nèi)容,歡迎大家持續(xù)關(guān)注嵌入式實(shí)驗(yàn)基地!
    ??如果你覺得對自己有幫助的話,給個贊,點(diǎn)個關(guān)注,點(diǎn)個在看,感謝前進(jìn)的道路上有你的陪伴!

    推薦閱讀
    ?開源電路のSTM32最小系統(tǒng)設(shè)計(jì)
    ?一種你值得擁有的簡單易實(shí)現(xiàn)的開關(guān)電路
    ?無線通訊之紅外通訊?DIY一個離線語音控制器
    ?HAL庫us延時的3種實(shí)現(xiàn)方式?邏輯分析儀的簡單使用介紹(附帶iic,uart,spi數(shù)據(jù)波形分析)
    ?ART-PI重力感應(yīng)無線智能小車第一彈----ART-PI擴(kuò)展板設(shè)計(jì)?ART-PI重力感應(yīng)無線智能小車第二彈----Onenet+wifi+L298N電機(jī)驅(qū)動?ART-PI重力感應(yīng)無線智能小車第三彈----RT-Studio+MPU6050+MQTT發(fā)布訂閱?STM32 DAC音頻輸出
    ?pcb設(shè)計(jì)基礎(chǔ)?OLED+ESP8266網(wǎng)絡(luò)小時鐘
  • 發(fā)表回復(fù)

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表