本日はヒラサカさんの56歳の生誕祭なので日本国民の祝日です.
さて本日も、STM32で4chオシロを作りましょう.
LCDを動かすのがわからんくてしばらく困っていたのですがやっと少し表示が出ました.
LCDはMSP3520という中華製品で、サイズは3.5inchだったかな.LCD driver ICはILI9488です.画素数は480x320.3bit/pixel modeで動かしていますから8colorsです.ILI9488にはSPIで接続しています.
今回はILI9488の制御について解説します.
【SPIの結線】
SCK,CS,MISO,MOSI、のお決まりの4本線はSPIの作法に則って配線すればOKです.
CSはLow Activeです.CSは常にLowでも問題なく動いてます.(レジスタ制御が一区切りする毎にCS=Highにするなどは不要ということです)
ところがこの他にもう1本の制御線があるんです.DT/REGとか呼びます.何の役割かというと、レジスタアクセスとGRAMアクセスを識別するためです.レジスタアクセスの時はLowにする、GRAMアクセスの時はHighにする.
なので、STM32のSPIをDMAで処理する時には少々めんどくさくなります.SPI-DMAを2度に分けなければならないからです.
GPIO操作でDT/REG=Low
↓
SPI-DMAでレジスタコマンドを送信
↓
GPIO操作でDT/REG=High
↓
SPI-DMAでGRAMデータを送信
SPI clockの最高周波数は、ILI9488の制約で20MHzまでです.
STM32F205の事情では、バス周波数が60MHzでそれをプリスケーラで4分周して15MHzでSPIを動かしますので20→15MHzに損しちゃってます.
CPOLとCPHAの設定にも注意してね.STM32F205の事情では、バス周波数が60MHzでそれをプリスケーラで4分周して15MHzでSPIを動かしますので20→15MHzに損しちゃってます.
【SPI以外の結線】
SPI以外の信号があります.
左側の5本はタッチパネル信号線なので無視します.
LEDは、backlightのON/OFFです.Highで点灯.
RESETは、hard resetです.Lowでreset.
制御softwareのハナシに移ります.
datasheetのレジスタを見ると、Power Saveやreset系レジスタで怪しいのはこんなにたくさんあります.これらの依存関係がよくわかりません.
Soft Reset、Sleep IN、Sleep OUT、Normal Display Mode ON、All Pixel OFF、All Pixel ON、Display OFF、Display ON、Idle Mode OFF、Idle Mode ON
GitHubのcodeをチラ見しても、いろいろやり過ぎていてよくわからん.
レジスタのデフォ値を不揮発メモリに記憶することもできるみたいよ.
わたしが買ったLCDにはどんなデフォ値がストアされているのかは不明です.
なので動かしてみるしかないです.
【ILI9488を動かすミニマム操作】
GRAM data formatは3bit pixelで、1byteに2pixelsが入ります.
なので、480x320の全面を埋め尽くすなら、480x320/2=76800bytes送信すればいいです.計算では40mSecぐらいかかる見込みです.ILI9488を初期設定して画面をblackにして、シアンとマゼンタの矩形を描きます.
void LCD_setup(void){
LCD_RESET(); hardware reset
HAL_Delay(200); 200mSec待ち
LCD_BACKLIGHT_ON(); hardware back light LED ON
LCD_CS(); hardware CS=Low
LCD_send_command(ILI9488_SLPOUT); Sleep Out (11H)
LCD_send_command(ILI9488_MADCTL); Memory Access Ctl. (36H)
LCD_send_byte(0xE0); 座標系設定
LCD_send_command(ILI9488_PIXFMT); Interface Pixel fmt. (3AH)
LCD_send_byte(0x01); 3bit/pixel mode
LCD_rectangle(0,0,479,319,0); 全画面ブラック
LCD_rectangle(0,0,239,159,6); シアンの矩形
LCD_rectangle(239,159,479,319,5); マゼンタの矩形
}
レジスタコマンド送信routine
void LCD_send_command( uint8_t x ){
LCD_CMD(); DT/REG=Low
HAL_SPI_Transmit(&hspi1, &x, 1, 1000);
}
データ送信routine
void LCD_send_byte(uint8_t x){
LCD_DATA(); DT/REG=High
HAL_SPI_Transmit(&hspi1, &x, 1, 1000);
}
矩形範囲を塗りつぶすroutine
void LCD_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t col){
uint8_t c;
c = col & 0x7;
LCD_send_command(ILI9488_DISPOFF); 一応画面OFF
LCD_send_command(ILI9488_CASET); 描画X座標範囲指定
LCD_send_byte( x1>>8 );
LCD_send_byte( x1 );
LCD_send_byte( x2>>8 );
LCD_send_byte( x2 );
LCD_send_command(ILI9488_PASET); 描画Y座標範囲指定
LCD_send_byte( y1>>8 );
LCD_send_byte( y1 );
LCD_send_byte( y2>>8 );
LCD_send_byte( y2 );
LCD_send_command(ILI9488_RAMWR); GRAM書き予告
for(int i=0;i<(x2-x1)*(y2-y1)/2;i++)
LCD_send_byte((c<<3) + c); GRAMデータ送信
LCD_send_command(ILI9488_DISPON); 画面ON
}
今後はいろんな描画routineをつくらなくちゃ.
かしこ
LCD_RESET()などは、どのドキュメントを参照しましたか?
返信削除記憶が薄れていますが、これとか使えそうな資料みたく思います.
削除https://www.hpinfotech.ro/ILI9488.pdf
ありがとうございます。ライブラリ自体は以下にございました。
返信削除http://www.lcdwiki.com/3.5inch_SPI_Module_ILI9488_SKU:MSP3520
忘れちまっててすいませんでしたー
削除がんばってくださーい