RL78でのILI9341の使い方|初期化やコマンドとライブラリ化

当サイトにはアフィリエイト広告が表示されます。

※arduino や raspberry pi、esp32などは使ってません。
ルネサスのRL78と直接16bitのパラレル接続で動作させています(SPIではない)。
ライブラリ化しやすいようコードを分けています。

興味があるところを読む

ILI9341+グラフィックLCD

2016/10/29 参考HP データシート

グラフィックLCDを使うとなれば、LCDコントローラーの出番です。
LCDを直接操作するわけじゃなくて、コントローラICのILI9341(ILI9340でも動くと思う)のいじり方をご紹介しています。

・RL78と9341は16bitのパラレルで接続。
・リセットはハード的に発生してます。

ってことで、あちこちググり回って見付けたのが上記の参考HP。
とても分かりやすく、更にソースも載せてくれてるんで至って簡単に完成した。有り難うございます。

パラレル接続時の変更点

ところでどのサイトでもCPUと9341をSPIで接続してるけど、今回は16bitパラレル接続(P7/8)なので、IO部分だけを修正すれば動くはずと目星を付けて作ったのがこれ。
要するにSPIで出力してるのをポート出力に変更しただけ。

・IM0~3を0001にセットすることで16bitバスになる(9341マニュアルより抜粋)。
・またレジスタへのアクセスは8bit幅だけど、GRAMは16bit幅でアクセスすることが読み取れる。

CMDを書くときはDCX=L、DATAを書くときはDCX=Hにしておいて、WRXで↑エッジを出してやる。 
・GRAMに上位8bitゼロで書き込むと赤だけ表示されなかった(CPUボードは北斗電子製)。
・この後で16bitで書き込んだら赤も表示されたから上位8bitが赤だ。 
スポンサーリンク

コード

コードはライブラリー化し易いように分けてます。
コピーしてCS+に貼り付け、LcdMain()をコールすれば動作するはず。

//
// lcd.c ILI9341+4DLCD-28QA 2016/10/15
//   http://imagewriteriij.blogspot.jp/2014/01/raspberry-pi-9-lcd-1.html
//   http://nopnop2002.webcrow.jp/TFT/ILI9340-1.html
//
#include "r_cg_macrodriver.h"
#include "iodefine.h"
#include "r_cg_userdefine.h"
// LCD Ports define
#define LCD_BKL     P3_bit.no1  // BackLight
#define LCD_CSX     P6_bit.no5  // CSX
#define LCD_DCX     P6_bit.no4  // DCX
#define LCD_WRX     P6_bit.no7  // WRX
#define LCD_RDX     P6_bit.no6  // RDX
// Prototype
static void lcd_test(uint16_t r, uint16_t g, uint16_t b);
static void clear(uint16_t r, uint16_t g, uint16_t b);
static void colorbar(void);
static void write_dc(uint8_t dc, uint8_t c);
static void write_dc_w(uint16_t w);
static void write_dc_w16(uint16_t w);
static void lcd_init(void);
static void addset(uint16_t x, uint16_t y);
static uint16_t rgb565_conv(uint16_t r, uint16_t g, uint16_t b);
//================================================================================================
// LCD main
//================================================================================================
void LcdMain(void)
{
/* 手動でリセットするなら・・・
 LCD_CSX = 0;   // CS=L(これは要らないかも)
 LCD_DCX = 1;   // D/C = H
 RESET = 0;     // Reset = L
 delay1ms(100); // delay 100ms
 RESET = 1;     // Reset = 1
 delay1ms(100); // delay 100ms
*/
    LCD_BKL = 1;    // バックライトON
    LCD_CSX = 0;    // CS=L
    lcd_init();

    lcd_test(0, 255, 255);
    lcd_test(255, 255, 0);
    lcd_test(255, 0, 255);

    LCD_CSX = 1;    // CS=H
    LCD_BKL = 0;    // バックライトOFF
}
// デバッグ用のLCD表示
void lcd_test(uint16_t r, uint16_t g, uint16_t b)
{
    clear(r, g, b);
    colorbar();
}
// lcd initial
static void lcd_init(void)
{
    LCD_WRX = 1;
    LCD_RDX = 1;
    delay1ms(25);
    write_dc(0,0xC0);       //Power control 
    write_dc(1,0x23);
    write_dc(0,0xC1);       //Power control 
    write_dc(1,0x10);
    write_dc(0,0xC5);       //VCM control 
    write_dc(1,0x3e);
    write_dc(1,0x28); 
    write_dc(0,0xC7);       //VCM control2 
    write_dc(1,0x86);
    write_dc(0,0x36);       // Memory Access Control 
    write_dc(1,0x48);
    write_dc(0,0x3A);       
    write_dc(1,0x55); 
    write_dc(0,0xB1);       
    write_dc(1,0x00);    
    write_dc(1,0x18); 
    write_dc(0,0xB6);       // Display Function Control 
    write_dc(1,0x08); 
    write_dc(1,0x82);
    write_dc(1,0x27);    
    write_dc(0,0xF2);       // 3Gamma Function Disable 
    write_dc(1,0x00); 
    write_dc(0,0x26);       //Gamma curve selected 
    write_dc(1,0x01); 
    write_dc(0,0xE0);       //Set Gamma 
    write_dc(1,0x0F); 
    write_dc(1,0x31); 
    write_dc(1,0x2B); 
    write_dc(1,0x0C); 
    write_dc(1,0x0E); 
    write_dc(1,0x08); 
    write_dc(1,0x4E); 
    write_dc(1,0xF1); 
    write_dc(1,0x37); 
    write_dc(1,0x07); 
    write_dc(1,0x10); 
    write_dc(1,0x03); 
    write_dc(1,0x0E); 
    write_dc(1,0x09); 
    write_dc(1,0x00); 
    write_dc(0,0XE1);       //Set Gamma 
    write_dc(1,0x00); 
    write_dc(1,0x0E); 
    write_dc(1,0x14); 
    write_dc(1,0x03); 
    write_dc(1,0x11); 
    write_dc(1,0x07); 
    write_dc(1,0x31); 
    write_dc(1,0xC1); 
    write_dc(1,0x48); 
    write_dc(1,0x08); 
    write_dc(1,0x0F); 
    write_dc(1,0x0C); 
    write_dc(1,0x31); 
    write_dc(1,0x36); 
    write_dc(1,0x0F); 
    write_dc(0,0x11);       //Exit Sleep 
    delay1ms(120); 
    write_dc(0,0x29);       //Display on 
    write_dc(0,0x2c);       //Memory Write
}
// clear
static void clear(uint16_t r, uint16_t g, uint16_t b)
{
    int i,j; 
    for (i=0;i<240;i++) {       // x = 0 to 239
        for(j=0;j<320;j++) {    // y = 0 to 319 
            addset(i,j);
            write_dc_w16(rgb565_conv(r, g, b));
        }
    }
}
// write color bar
static void colorbar(void)
{
    int i,j; 
    for(i=0;i<240;i++){         // x = 0 to 239
        for(j=0;j<320;j++){     // y = 0 to 319 
            if(j<106) {
                addset(i,j);
                write_dc_w16(rgb565_conv(255,0,0)); //red
            } else if(j<212) {
                addset(i,j);
                write_dc_w16(rgb565_conv(0,255,0)); //green
            } else { 
                addset(i,j);
                write_dc_w16(rgb565_conv(0,0,255)); //blue
            }
        }
    }
}
// set address
static void addset(uint16_t x, uint16_t y)
{
    write_dc(0,0x2A); // set column(x) address
    write_dc_w(x);
    write_dc_w(x);
    write_dc(0,0x2B); // set Page(y) address
    write_dc_w(y);
    write_dc_w(y);
    write_dc(0,0x2C); // Memory Write
}
// RGB565 conversion
// RGB565 is R(5)+G(6)+B(5)=16bit color format.
// Bit image "RRRRRGGGGGGBBBBB"
static uint16_t rgb565_conv(uint16_t r,uint16_t g,uint16_t b)
{
    uint16_t RR,GG,BB;
    RR = (r * 31 / 255) << 11;
    GG = (g * 63 / 255) << 5;
    BB = (b * 31 / 255);
    return(RR | GG | BB);
}
// Write data/command
static void write_dc(uint8_t dc, uint8_t c) 
{
    LCD_DCX = dc;   // 0=command, 1=data
    P7 = c;         // 下位8bitのみ(上位8bitはdont care)
    LCD_WRX = 0;    // WR out
    NOP();
    LCD_WRX = 1;    
}
// Write data word
static void write_dc_w(uint16_t w)
{
    uint8_t hi,lo;
    hi = (uint8_t)(w >> 8);
    lo = (uint8_t)(w & 0x00FF);
    write_dc(1,hi);
    write_dc(1,lo);
}
// Write data word by 16bit
static void write_dc_w16(uint16_t w)
{
    uint8_t hi,lo;
    hi = (uint8_t)(w >> 8);
    lo = (uint8_t)(w & 0x00FF);
    LCD_DCX = 1;    // 1=data
    P8 = hi;        // 上位8bit
    P7 = lo;        // 下位8bit
    LCD_WRX = 0;    // WR out
    NOP();
    LCD_WRX = 1;    
}
スポンサーリンク
スポンサーリンク
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


興味があるところを読む