「STM32」の3種のMCUボードに全く同じスケッチ(接続に使用するPinも同じです)
・Arduino IDE 2.3.4
・8ビットパラレル接続のTFTLCDモジュール
・TFT_eSPI ライブラリの Example UTFT_Demo_480x320.ino
を動作させ、どのくらいの差が出るか比較してみました。ただし、次のようなToolsオプションを適用しました。
「with LTO」を付けたため赤字の警告メッセージが出ますが動作し、少し速くなってます。「Board」「Board part number」はもちろんそれぞれのボードに応じて変えてあります。その結果以下の通りです。
チップの刻印 | 動作周波数 | 1ループに要する時間 | |
---|---|---|---|
STM32F103C8T6 | 72MHz | 1415msecs | 72x1415=101,880 |
STM32F401CCU6 | 84MHz | 1112msecs | 84x1112=93,408 最速? |
STM32F411CEU6 | 100MHz | 984msecs | 100x984=98,400 |
ちなみに「F103C8T6」の「8」からフラッシュメモリサイズは「64KB」と思いきや、
Sketch uses 84036 bytes (64%) of program storage space. Maximum is 131072 bytes.
Global variables use 4732 bytes (23%) of dynamic memory, leaving 15748 bytes for local variables. Maximum is 20480 bytes.
となり「84KB」のスケッチを受け入れており、実サイズは「13107 bytes x 1024 = 128KB」のようです。
【参考】https://qiita.com/shuji4649/items/bb5a30f0cea2839f9439
(写真内の金色の部品、以前購入した「ST-LINK V2」の御蔭で、作業がはかどりありがたいです。)
TFTモジュールと各MCUボードの接続は全く同じで、次のようにしました。
TFT LCD ディスプレイ | 各MCUボードのGPIOピン |
---|---|
TFT_RST(LCD_RST) | PB3 |
TFT_CS | PB4 |
TFT_DC | PB5 |
TFT_WR | PB6 |
TFT_RD | PB7 |
TFT_D0 | PA0 |
TFT_D1 | PA1 |
TFT_D2 | PA2 |
TFT_D3 | PA3 |
TFT_D4 | PA4 |
TFT_D5 | PA5 |
TFT_D6 | PA6 |
TFT_D7 | PA7 |
5V | 5V |
GND | GND |
「User_Setup.h]とスケッチ本体の「UTFT_Demo_480x320.ino」を示します。
#define USER_SETUP_INFO "User_Setup"
#define STM32
#define STM_PORTA_DATA_BUS
//#define STM_PORTB_DATA_BUS
// Tell the library to use parallel mode (otherwise SPI is assumed)
#define TFT_PARALLEL_8_BIT
#define ILI9488_DRIVER // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)
#define TFT_CNTRL_PORT GPIOB
#define TFT_DATA_PORT GPIOA
#define TFT_DATA_SHIFT 0 // take the lower bits/pins 0..7
// The ESP32 and TFT the pins used for testing are:
#define TFT_RST PB3//PB0 // Reset pin, toggles on startup
#define TFT_CS PB4//PB1 // Chip select control pin (library pulls permanently low
#define TFT_DC PB5//PB3 // Data Command control pin - must use a pin in the range 0-31
#define TFT_WR PB6//PB4 // Write strobe control pin - must use a pin in the range 0-31
#define TFT_RD PB7//PB5 // Read strobe control pin
#define TFT_D0 PA0 // Must use pins in the range 0-31 for the data bus
#define TFT_D1 PA1 // so a single register write sets/clears all bits.
#define TFT_D2 PA2 // Pins can be randomly assigned, this does not affect
#define TFT_D3 PA3 // TFT screen update performance.
#define TFT_D4 PA4
#define TFT_D5 PA5
#define TFT_D6 PA6
#define TFT_D7 PA7
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
// ##################################################################################
//
// Section 4. Other options
//
// ##################################################################################
// For the STM32 processor define the SPI port channel used (default 1 if undefined)
//#define TFT_SPI_PORT 2 // Set to 1 for SPI port 1, or 2 for SPI port 2
// Define the SPI clock frequency, this affects the graphics rendering speed. Too
// fast and the TFT driver will not keep up and display corruption appears.
// With an ILI9341 display 40MHz works OK, 80MHz sometimes fails
// With a ST7735 display more than 27MHz may not work (spurious pixels and lines)
// With an ILI9163 display 27 MHz works OK.
// #define SPI_FREQUENCY 1000000
// #define SPI_FREQUENCY 5000000
// #define SPI_FREQUENCY 10000000
// #define SPI_FREQUENCY 20000000
//#define SPI_FREQUENCY 27000000
// #define SPI_FREQUENCY 40000000
#define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY 80000000
// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000
/*
Example animated analogue meters using a TFT LCD screen
Originanally written for a 320 x 240 display, so only occupies half
of a 480 x 320 display.
Needs Font 2 (also Font 4 if using large centered scale label)
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
*/
// Attention to 5V !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 128kb board.BluePill or BlackPill
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
#include "User_Setup.h" // User_Setup_Select.h からドライバー設定を外しておく
#define WAIT 0 // Delay between tests, set to 0 to demo speed, 2000 to see what it does!
#define WAITs 0 // Delay between tests, set to 0 to demo speed, 2000 to see what it does!
#define CENTRE 240
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define TFT_GREY 0x7BEF
uint32_t runTime = 0;
void setup()
{
randomSeed(analogRead(0));
Serial.begin(115200);
Serial.println("* TFT_eSPI Test*");
// Setup the LCD
tft.init();
tft.setRotation(1);
}
void loop()
{
int buf[478];
int x, x2;
int y, y2;
int r;
runTime = millis();
// Clear the screen and draw the frame
tft.fillScreen(TFT_BLACK);
tft.fillRect(0, 0, 480, 13, TFT_RED);
tft.fillRect(0, 305, 480, 320, TFT_GREY);
tft.setTextColor(TFT_BLACK,TFT_RED);
tft.drawCentreString("* TFT_eSPI *", CENTRE, 3, 1);
tft.setTextColor(TFT_YELLOW,TFT_GREY);
tft.drawCentreString("Adapted by Bodmer", CENTRE, 309,1);
tft.drawRect(0, 14, 479, 305-14, TFT_BLUE);
delay(WAIT);
// Draw crosshairs
tft.drawLine(239, 15, 239, 304, TFT_BLUE);
tft.drawLine(1, 159, 478, 159, TFT_BLUE);
for (int i=9; i<470; i+=10){
tft.drawLine(i, 157, i, 161, TFT_BLUE);
delay(WAITs);
}
for (int i=19; i<220; i+=10){
tft.drawLine(237, i, 241, i, TFT_BLUE);
delay(WAITs);
}
// Draw sin-, cos- and tan-lines
tft.setTextColor(TFT_CYAN);
tft.drawString("Sin", 5, 15,2);
for (int i=1; i<478; i++){
tft.drawPixel(i,159+(sin(((i*1.13)*3.14)/180)*95),TFT_CYAN);
delay(WAITs);
}
tft.setTextColor(TFT_RED);
tft.drawString("Cos", 5, 30,2);
for (int i=1; i<478; i++){
tft.drawPixel(i,159+(cos(((i*1.13)*3.14)/180)*95),TFT_RED);
delay(WAITs);
}
tft.setTextColor(TFT_YELLOW);
tft.drawString("Tan", 5, 45,2);
for (int i=1; i<478; i++){
tft.drawPixel(i,159+(tan(((i*1.13)*3.14)/180)),TFT_YELLOW);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
tft.drawLine(239, 15, 239, 304,TFT_BLUE);
tft.drawLine(1, 159, 478, 159,TFT_BLUE);
// Draw a moving sinewave
int col = 0;
x=1;
for (int i=1; i<(477*15); i++) {
x++;
if (x==478) x=1;
if (i>478){
if ((x==239)||(buf[x-1]==159)) col = TFT_BLUE;
else tft.drawPixel(x,buf[x-1],TFT_BLACK);
}
y=159+(sin(((i*0.7)*3.14)/180)*(90-(i / 100)));
tft.drawPixel(x,y, TFT_BLUE);
buf[x-1]=y;
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled rectangles
for (int i=1; i<6; i++) {
switch (i){
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillRect(150+(i*20), 70+(i*20), 60, 60,col);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled, rounded rectangles
for (int i=1; i<6; i++) {
switch (i) {
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillRoundRect(270-(i*20), 70+(i*20), 60, 60, 3, col);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some filled circles
for (int i=1; i<6; i++) {
switch (i) {
case 1:
col = TFT_MAGENTA;
break;
case 2:
col = TFT_RED;
break;
case 3:
col = TFT_GREEN;
break;
case 4:
col = TFT_BLUE;
break;
case 5:
col = TFT_YELLOW;
break;
}
tft.fillCircle(180+(i*20),100+(i*20), 30,col);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some lines in a pattern
for (int i=15; i<304; i+=5) {
tft.drawLine(1, i, (i*1.6)-10, 303, TFT_RED);
delay(WAITs);
}
for (int i=304; i>15; i-=5) {
tft.drawLine(477, i, (i*1.6)-11, 15, TFT_RED);
delay(WAITs);
}
for (int i=304; i>15; i-=5) {
tft.drawLine(1, i, 491-(i*1.6), 15, TFT_CYAN);
delay(WAITs);
}
for (int i=15; i<304; i+=5) {
tft.drawLine(477, i, 490-(i*1.6), 303, TFT_CYAN);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random circles
for (int i=0; i<100; i++) {
x=32+random(416);
y=45+random(226);
r=random(30);
tft.drawCircle(x, y, r,random(0xFFFF));
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random rectangles
for (int i=0; i<100; i++) {
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
if (x2<x) r=x;x=x2;x2=r;
if (y2<y) r=y;y=y2;y2=r;
tft.drawRect(x, y, x2-x, y2-y,random(0xFFFF));
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
// Draw some random rounded rectangles
for (int i=0; i<100; i++) {
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
if (x2<x) r=x;x=x2;x2=r;
if (y2<y) r=y;y=y2;y2=r;
tft.drawRoundRect(x, y, x2-x, y2-y, 3,random(0xFFFF));
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
for (int i=0; i<100; i++) {
x=2+random(476);
y=16+random(289);
x2=2+random(476);
y2=16+random(289);
col=random(0xFFFF);
tft.drawLine(x, y, x2, y2,col);
delay(WAITs);
}
delay(WAIT);
tft.fillRect(1,15,478-1,304-15,TFT_BLACK);
for (int i=0; i<10000; i++) {
tft.drawPixel(2+random(476), 16+random(289),random(0xFFFF));
}
delay(WAIT);
tft.fillRect(0, 0, 480, 320, TFT_BLUE);
tft.fillRoundRect(160, 70, 319-160, 169-70, 3,TFT_RED);
tft.setTextColor(TFT_WHITE,TFT_RED);
tft.drawCentreString("That's it!", CENTRE, 93,2);
tft.drawCentreString("Restarting in a", CENTRE, 119, 2);
tft.drawCentreString("few seconds...", CENTRE, 132, 2);
tft.setTextColor(TFT_GREEN,TFT_BLUE);
tft.drawCentreString("Runtime: (msecs)", CENTRE, 280, 2);
tft.setTextDatum(TC_DATUM);
runTime = millis()-runTime;
tft.drawNumber(runTime, CENTRE, 300,2);
tft.setTextDatum(TL_DATUM);
delay (10000);
}
最後まで見ていただきありがとうございました。