LCD(液晶ディスプレイ)の基本

ピクセル座標系

8ビットカラーモデル

ビット 7 6 5 4 3 2 1 0
データ

16ビットカラーモデル

ビット 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
データ

事前定義された色の例(16ビット)


#define TFT_BLACK       0x0000      /*   0,   0,   0 */
#define TFT_NAVY        0x000F      /*   0,   0, 128 */
#define TFT_DARKGREEN   0x03E0      /*   0, 128,   0 */
#define TFT_DARKCYAN    0x03EF      /*   0, 128, 128 */
#define TFT_MAROON      0x7800      /* 128,   0,   0 */
#define TFT_PURPLE      0x780F      /* 128,   0, 128 */
#define TFT_OLIVE       0x7BE0      /* 128, 128,   0 */
#define TFT_LIGHTGREY   0xC618      /* 192, 192, 192 */
#define TFT_DARKGREY    0x7BEF      /* 128, 128, 128 */
#define TFT_BLUE        0x001F      /*   0,   0, 255 */
#define TFT_GREEN       0x07E0      /*   0, 255,   0 */
#define TFT_CYAN        0x07FF      /*   0, 255, 255 */
#define TFT_RED         0xF800      /* 255,   0,   0 */
#define TFT_MAGENTA     0xF81F      /* 255,   0, 255 */
#define TFT_YELLOW      0xFFE0      /* 255, 255,   0 */
#define TFT_WHITE       0xFFFF      /* 255, 255, 255 */
#define TFT_ORANGE      0xFDA0      /* 255, 180,   0 */
#define TFT_GREENYELLOW 0xB7E0      /* 180, 255,   0 */

TFT LCDスクリーンの初期化

※はTFT LCDスクリーンの開始するコーナーを意味します。(0から3)

#include"TFT_eSPI.h"
TFT_eSPI tft;
 
void setup() {
  ...
    tft.begin();
    tft.setRotation(※);
    digitalWrite(LCD_BACKLIGHT, HIGH); // turn on the backlight
  ...
}

コード例

Wio TerminalのTFT LCD画面を初期化し、画面を赤で塗りつぶします。

#include"TFT_eSPI.h"
TFT_eSPI tft;
 
void setup() {
    tft.begin();
    tft.setRotation(3);
 
    tft.fillScreen(TFT_RED); // fills entire the screen with color red
}
 
void loop() {
 
}

LCDバックライトの制御

オフにするには、LCDバックライト制御ピン72UlをLOWにする。
オンにするには、LCDバックライト制御ピン72UlをHIGHにする。

#include"TFT_eSPI.h"
TFT_eSPI tft;
#define LCD_BACKLIGHT (72Ul) // Control Pin of LCD
 
void setup() {
  // put your setup code here, to run once:
 
    tft.begin();
    tft.setRotation(3);
    tft.fillScreen(TFT_RED);
 
    delay(2000);
    // Turning off the LCD backlight
    digitalWrite(LCD_BACKLIGHT, LOW);
    delay(2000);
    // Turning on the LCD backlight
    digitalWrite(LCD_BACKLIGHT, HIGH);
}
 
void loop() {
  // put your main code here, to run repeatedly:
 
}

LCDバックライトの明るさの制御

https://github.com/Seeed-Studio/Seeed_Arduino_Sketchbook/tree/master/examples/WioTerminal_BackLight
This example is written by Kenta IDA and all credits goes to Kenta IDA.
  1. Download the repo here.
    Under examples/WioTerminal_BackLight location.
  2. Upload the code.
    Upload the lcd_backlight_control.ino to Wio Terminal and you will see brightness change on the LCD.
WioTerminal_BackLight.ino
#include <TFT_eSPI.h>
#include "lcd_backlight.hpp"
#include <cstdint>

TFT_eSPI tft;
static LCDBackLight backLight;
void setup() {
    Serial.begin(115200);
    while(!Serial);

    tft.begin();
    tft.setRotation(3);

    tft.fillScreen(tft.color565(255, 0, 0));

    Serial.println("initializing backlight...");
    backLight.initialize();
}

static std::uint8_t brightness = 0;
void loop() {
    std::uint8_t maxBrightness = backLight.getMaxBrightness();
    brightness += 1;
    if( brightness > maxBrightness ) {
        brightness = 0;
    }
    backLight.setBrightness(brightness);
    delay(50);
}
lcd_backlight.hpp
// Copyright 2020 Kenta IDA
// LICENSE: Boost Software License
/**
 * @file lcd_backlight.hpp
*/

#ifndef LCD_BACKLIGHT_HPP__
#define LCD_BACKLIGHT_HPP__

//#include <samd51p19a.h>
#include <cstdint>

/**
 * @brief Controls Wio Terminal LCD back light brightness
 */
class LCDBackLight
{
private:
    std::uint8_t currentBrightness = 100;
    std::uint8_t maxBrightness = 100;
public:
    /**
     * @brief Gets current brightness
     * @return current brightness.
     */
    std::uint8_t getBrightness() const { return this->currentBrightness; }
    /**
     * @brief Gets maximum brightness
     * @return maximum brightness.
     */
    std::uint8_t getMaxBrightness() const { return this->maxBrightness; }
    
    /**
     * @brief Sets brightness.
     * @param [in] brightness new value of brightness. If the brightness value exceeds maximum brightness, the value will be clipped.
     * 
     */
    void setBrightness(std::uint8_t brightness)
    {
        this->currentBrightness = brightness < this->maxBrightness ? brightness : this->maxBrightness;
        TC0->COUNT8.CC[0].reg = this->currentBrightness;
        while(TC0->COUNT8.SYNCBUSY.bit.CC0);
    }
    /**
     * @brief Sets maximum brightness.
     * @param [in] maxBrightness new value of maximum brightness. If the current brightness value exceeds maximum brightness, the current brightness will be clipped.
     * 
     */
    void setMaxBrightness(std::uint8_t maxBrightness)
    {
        this->maxBrightness = maxBrightness;
        if( this->currentBrightness > this->maxBrightness ) {
            this->currentBrightness = this->maxBrightness;
        }
        TC0->COUNT8.PER.reg = this->maxBrightness;
        while(TC0->COUNT8.SYNCBUSY.bit.PER);
        TC0->COUNT8.CC[0].reg = this->currentBrightness;
        while(TC0->COUNT8.SYNCBUSY.bit.CC0);
    }

    /**
     * @brief Initialize hardware/peripherals to control back light brightness.
     * @remark This function must be called before using other LCDBackLight class member functions.
     */
    void initialize()
    {
        /* Enable Peripheral Clocks */
        GCLK->PCHCTRL[9].reg = 0 | (1u<<6);         // TC0, TC1
        while(!GCLK->PCHCTRL[9].bit.CHEN);
        GCLK->PCHCTRL[11].reg = 0 | (1u<<6);    // EVSYS[0]
        while(!GCLK->PCHCTRL[11].bit.CHEN);
        GCLK->PCHCTRL[33].reg = 0 | (1u<<6);    // CCL
        while(!GCLK->PCHCTRL[33].bit.CHEN);
        /* Enable Peropheral APB Clocks */
        MCLK->APBAMASK.bit.TC0_ = 1;
        MCLK->APBBMASK.bit.EVSYS_ = 1;
        MCLK->APBCMASK.bit.CCL_ = 1;

        /* Configure PORT */
        PORT->Group[2].DIRSET.reg = (1<<5);
        PORT->Group[2].EVCTRL.reg = 0x85; // PC05, OUT
        /* Configure EVSYS */
        EVSYS->USER[1].reg = 0x01;  // Channel0 -> PORT_EV0
        EVSYS->Channel[0].CHANNEL.reg = 0x74 | (0x02<<8) | (0x00<<10);  // CCL_LUTOUT0, ASYNCHRONOUS, NO_EVT_OUTPUT
        /* Configure CCL */
        CCL->CTRL.reg = (1<<0); // SWRST
        CCL->SEQCTRL[0].reg = 0x0; // Disable SEQCTRL
        CCL->LUTCTRL[0].reg = (0xaau << 24) | (1u<<22) | (0x6<<8) | (1<<1); // TRUTH=0xaa, LUTEO, INSEL0=0x06(TC), ENABLE
        CCL->CTRL.reg = (1<<1); // ENABLE

        /* Configure TC0 */
        TC0->COUNT8.CTRLA.reg = (1u<<0);   // SWRST;
        while( TC0->COUNT8.SYNCBUSY.bit.SWRST );
        
        TC0->COUNT8.CTRLA.reg = (0x01 << 2) | (0x01 << 4) | (0x04 << 8);   // MODE=COUNT8, PRESCALER=DIV16, PRESCSYNC=PRESC
        TC0->COUNT8.WAVE.reg  = 0x02; // WAVEGEN=NPWM;
        TC0->COUNT8.CTRLBSET.reg = (1u<<1); // LUPD
        TC0->COUNT8.PER.reg = this->maxBrightness;
        TC0->COUNT8.CC[0].reg = this->currentBrightness;
        TC0->COUNT8.CC[1].reg = 0u;
        TC0->COUNT8.DBGCTRL.bit.DBGRUN = 1;
        TC0->COUNT8.INTFLAG.reg = 0x33;    // Clear all flags
        while( TC0->COUNT8.SYNCBUSY.reg );
        
        TC0->COUNT8.CTRLA.bit.ENABLE = 1;   // ENABLE
        while( TC0->COUNT8.SYNCBUSY.bit.ENABLE );
    }
};
#endif //LCD_BACKLIGHT_HPP__