diff --git a/Display_cfg.h b/Display_cfg.h index a7e8023..4c9408c 100644 --- a/Display_cfg.h +++ b/Display_cfg.h @@ -20,21 +20,43 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#define DISPLAY_WIDTH 400 // Display width in pixel -#define DISPLAY_HEIGHT 240 // Display height in pixel +// #define DISPLAY_WIDTH 400 // Display width in pixel +// #define DISPLAY_HEIGHT 240 // Display height in pixel -#define USE_ESP32_DMA // 使用ESP32 DMA -#define DIFF_LINE_UPDATE // 差异行更新 +//#define USE_ESP32_DMA // 使用ESP32 DMA +//#define DIFF_LINE_UPDATE // 差异行更新 //================================================================= // Wiring details: https://github.com/Gbertaz/JDI_MIP_Display#wiring //================================================================= +// #define SPI_FREQUENCY 4000000 // SPI frequency in Hz +// #define SPI_CHANNEL spi0 // SPI channel number +// #define PIN_MISO D9 // SPI Data Signal pin +// #define PIN_MOSI D10 // SPI Data Signal pin +// #define PIN_SCK D8 // SPI Clock Signal pin +// #define PIN_SCS D7 // SPI Chip Select Signal pin +// #define PIN_DISP D0 // Display ON/OFF Switching Signal pin +// #define PIN_FRONTLIGHT -1 // Frontlight pin. Optional depending on the display model + +//================================================================= +// 适配老王JDI_Memory LCD屏幕,采用MEGA2560进行驱动 +// 分辨率为:144x72 +//================================================================= + +#define USE_144_72_LCD + +#define DISPLAY_WIDTH 144 // Display width in pixel +#define DISPLAY_HEIGHT 72 // Display height in pixel + +//控制引脚 +#define PIN_SCS A0 // SPI Chip Select Signal pin +#define PIN_DISP A1 // Display ON/OFF Switching Signal pin + +//SPI设置,不用关注 #define SPI_FREQUENCY 4000000 // SPI frequency in Hz #define SPI_CHANNEL spi0 // SPI channel number -#define PIN_MISO D9 // SPI Data Signal pin -#define PIN_MOSI D10 // SPI Data Signal pin -#define PIN_SCK D8 // SPI Clock Signal pin -#define PIN_SCS D7 // SPI Chip Select Signal pin -#define PIN_DISP D0 // Display ON/OFF Switching Signal pin +#define PIN_MISO 50 // SPI Data Signal pin +#define PIN_MOSI 51 // SPI Data Signal pin +#define PIN_SCK 52 // SPI Clock Signal pin #define PIN_FRONTLIGHT -1 // Frontlight pin. Optional depending on the display model \ No newline at end of file diff --git a/JDI_MIP_Display.cpp b/JDI_MIP_Display.cpp index 03854a1..dd1e362 100644 --- a/JDI_MIP_Display.cpp +++ b/JDI_MIP_Display.cpp @@ -28,7 +28,7 @@ spi_host_device_t spi_host = (spi_host_device_t)1; // 绘制一次然后冻结 #endif -JDI_MIP_Display::JDI_MIP_Display() : Adafruit_GFX(DISPLAY_WIDTH, DISPLAY_HEIGHT), _pSPIx(&SPI), _spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0) +JDI_MIP_Display::JDI_MIP_Display(uint16_t rot) : Adafruit_GFX(DISPLAY_WIDTH, DISPLAY_HEIGHT), _pSPIx(&SPI), _spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0) { _mosi = PIN_MOSI; _miso = PIN_MISO; @@ -37,6 +37,7 @@ JDI_MIP_Display::JDI_MIP_Display() : Adafruit_GFX(DISPLAY_WIDTH, DISPLAY_HEIGHT) _disp = PIN_DISP; _freq = SPI_FREQUENCY; _frontlight = PIN_FRONTLIGHT; + set_direction(rot); } void JDI_MIP_Display::selectSPI(SPIClass& spi, SPISettings spi_settings) @@ -45,6 +46,16 @@ void JDI_MIP_Display::selectSPI(SPIClass& spi, SPISettings spi_settings) _spi_settings = spi_settings; } + +void JDI_MIP_Display::set_direction(uint16_t rot){ + _rotation = rot; + if((rot == 0) || (rot == 180)){ + setRotation(1); //等效 setRotation(3); + }else{ + setRotation(0); //等效 setRotation(2); + } +} + void JDI_MIP_Display::begin() { _background = COLOR_BLACK; @@ -65,9 +76,117 @@ void JDI_MIP_Display::begin() #endif } +#ifdef USE_144_72_LCD +void JDI_MIP_Display::refresh() { + char buf = 0; + switch (_rotation) { + case 270: // 遍历所有行 + for (int i = 0; i < 144; i++) { + // 片选拉高,准备通信 + digitalWrite(_scs, HIGH); + _pSPIx->transfer(CMD_UPDATE); + _pSPIx->transfer(i + 1); + + // 处理行数据 + for (int a = 70; a >= 0; a -= 2) { + if (i % 2 == 0) { + // 偶数行:提取高 4 位并合并 + buf = ((_backBuffer[(a + 1) * 72 + i / 2] & 0xF0)) | + ((_backBuffer[(a + 0) * 72 + i / 2] & 0xF0) >> 4); + } else { + // 奇数行:提取低 4 位并合并 + buf = ((_backBuffer[(a + 1) * 72 + i / 2] & 0x0F) << 4) | + (_backBuffer[(a + 0) * 72 + i / 2] & 0x0F); + } + + // 通过 SPI 发送数据 + _pSPIx->transfer(buf); + } + // 结束数据传输,发送两个 0x00 字节 + _pSPIx->transfer(0x00); + _pSPIx->transfer(0x00); + + // 片选拉低,结束通信 + digitalWrite(_scs, LOW); + } + break; + case 90: + for (int i = 0; i < 144; i++) { + // 片选拉高,准备通信 + digitalWrite(_scs, HIGH); + _pSPIx->transfer(CMD_UPDATE); + _pSPIx->transfer(i + 1); + + // 处理行数据 + for (int a = 0; a < 72; a += 2) { + if ((143 - i) % 2 == 0) { + // 偶数行:提取高 4 位并合并 + buf = ((_backBuffer[(a + 0) * 72 + (143 - i) / 2] & 0xF0)) | + ((_backBuffer[(a + 1) * 72 + (143 - i) / 2] & 0xF0) >> + 4); + + } else { + // 奇数行:提取低 4 位并合并 + buf = ((_backBuffer[(a + 0) * 72 + (143 - i) / 2] & 0x0F) + << 4) | + (_backBuffer[(a + 1) * 72 + (143 - i) / 2] & 0x0F); + } + + // 通过 SPI 发送数据 + _pSPIx->transfer(buf); + } + // 结束数据传输,发送两个 0x00 字节 + _pSPIx->transfer(0x00); + _pSPIx->transfer(0x00); + + // 片选拉低,结束通信 + digitalWrite(_scs, LOW); + } + break; + case 180: + for (int i = 0; i < 144; i++) + { + int lineIdx = 36 * (143 - i); + char *line_cmd; + _pSPIx->beginTransaction(_spi_settings); + digitalWrite(_scs, HIGH); + _pSPIx->transfer(CMD_UPDATE); + _pSPIx->transfer(i + 1); + + for(int a = 0; a < 36; a++){ + + //交换高四位和低四位,因为反过来读的 + buf = _backBuffer[lineIdx + 35 - a]; + buf = ((buf & 0xF0) >> 4) | ((buf & 0x0F) << 4); + + _pSPIx->transfer(buf); + } + + _pSPIx->transfer(0x00); + _pSPIx->transfer(0x00); + digitalWrite(_scs, LOW); + _pSPIx->endTransaction(); + } + break; + case 0: + for (int i = 0; i < height(); i++) + { + int lineIdx = width()/2 * i; + char *line_cmd; + line_cmd = &_backBuffer[lineIdx]; + sendLineCommand(line_cmd, i); + } + break; + default: + break; + } +} + +#else + void JDI_MIP_Display::refresh() { - for (int i = 0; i < HEIGHT; i++) + for (int i = 0; i < height(); i++) { int lineIdx = HALF_WIDTH * i; char *line_cmd; @@ -81,7 +200,7 @@ void JDI_MIP_Display::refresh() sendLineCommand(line_cmd, i); } } - +#endif bool JDI_MIP_Display::compareBuffersLine(int lineIndex) { @@ -122,7 +241,7 @@ void JDI_MIP_Display::clearScreen() void JDI_MIP_Display::sendLineCommand(char *line_cmd, int line) { - if ((line < 0) || (line >= HEIGHT)) + if ((line < 0) || (line >= height())) { return; } @@ -149,7 +268,7 @@ void JDI_MIP_Display::sendLineCommand(char *line_cmd, int line) _pSPIx->transfer(CMD_UPDATE); _pSPIx->transfer(line + 1); - for(int i = 0; i < HALF_WIDTH; i++){ + for(int i = 0; i < width()/2; i++){ _pSPIx->transfer(line_cmd[i]); } diff --git a/JDI_MIP_Display.h b/JDI_MIP_Display.h index ef2c3f1..14a1f0c 100644 --- a/JDI_MIP_Display.h +++ b/JDI_MIP_Display.h @@ -51,7 +51,7 @@ class JDI_MIP_Display : public Adafruit_GFX { public: - JDI_MIP_Display(); + JDI_MIP_Display(uint16_t rot = 1); void begin(); void refresh(); void refresh2(); @@ -64,6 +64,7 @@ class JDI_MIP_Display : public Adafruit_GFX void setBackgroundColor(uint16_t color); void drawBufferedPixel(int16_t x, int16_t y, uint16_t color); void pushPixelsDMA(uint8_t *image, uint32_t len); + void set_direction(uint16_t n); private: uint8_t _sck; // 时钟信号 Clock signal uint8_t _miso; // 主输入从输出 Master input from output @@ -73,6 +74,7 @@ class JDI_MIP_Display : public Adafruit_GFX uint8_t _frontlight; // 前置灯 Front lights uint16_t _background; // 背景 background uint32_t _freq; // SPI频率 SPI frequency + uint16_t _rotation; // 屏幕旋转方向 0 90 180 270 SPIClass* _pSPIx; SPISettings _spi_settings; diff --git a/examples/FPS_and_Rotation_144x72/FPS_and_Rotation_144x72.ino b/examples/FPS_and_Rotation_144x72/FPS_and_Rotation_144x72.ino new file mode 100644 index 0000000..570cbdb --- /dev/null +++ b/examples/FPS_and_Rotation_144x72/FPS_and_Rotation_144x72.ino @@ -0,0 +1,157 @@ +//====================================================================== +//====================================================================== +// +// 这个例子基于FPS_test,增加了屏幕旋转测试,对144x72分辨率的屏幕显示做了优化 +// +// +// 接线: MEGA2560 +// PIN_SCS A0 +// PIN_DISP A1 +// PIN_MOSI 51 +// PIN_SCK 52 +// +// 使用前请注意: +// 1) 打开 Display_cfg.h 文件 +// 2) 使能 #define USE_144_72_LCD +// 3) 配置 PIN_DISP 和 PIN_SCS 引脚 +// +// License: +// +// MIT License +// +// Copyright(c) 2021 Giovanni Bertazzoni +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//====================================================================== +//====================================================================== + +#include + +#define NUMBER_COLORS 8 + +const uint16_t colors[NUMBER_COLORS] = {COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, + COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, + COLOR_YELLOW, COLOR_WHITE}; + +JDI_MIP_Display jdi_display(0); + +int rectHeight = jdi_display.height() / NUMBER_COLORS; +int rectWidth = jdi_display.width() / 2; +int startColor = 0; +int currentColor = 0; + +int fps = 0; +unsigned int frames = 0; +unsigned long startMillis = 0; +unsigned long test_rot_Millis = 0; +uint16_t rot_change_flag = 0; + +void setup() { + jdi_display.begin(); + delay(50); + jdi_display.displayOn(); + jdi_display.clearScreen(); // Clear the screen + jdi_display.refresh(); // Actually updates the display + startMillis = millis(); + test_rot_Millis = millis(); +} + +void loop() { + + //每过一秒使屏幕旋转一次 + if ((millis() - test_rot_Millis) > 1 * 1000) { + test_rot_Millis = millis(); + if (rot_change_flag==0) { + rot_change_flag = 1; + jdi_display.set_direction(0); + rectHeight = jdi_display.height() / NUMBER_COLORS; + rectWidth = jdi_display.width() / 2; + } else if (rot_change_flag==1){ + rot_change_flag = 2; + jdi_display.set_direction(90); + rectHeight = jdi_display.height() / NUMBER_COLORS; + rectWidth = jdi_display.width() / 2; + }else if (rot_change_flag==2){ + rot_change_flag = 3; + jdi_display.set_direction(180); + rectHeight = jdi_display.height() / NUMBER_COLORS; + rectWidth = jdi_display.width() / 2; + }else if (rot_change_flag==3){ + rot_change_flag = 0; + jdi_display.set_direction(270); + rectHeight = jdi_display.height() / NUMBER_COLORS; + rectWidth = jdi_display.width() / 2; + } + } + + scrollingColors(); + jdi_display.fillCircle(jdi_display.width() / 2, jdi_display.height() / 2, + 20, COLOR_BLUE); + + int xPos = (jdi_display.width() / 2) - 25; + int yPos = (jdi_display.height() / 2) - 45; + + jdi_display.setTextColor(COLOR_BLACK, COLOR_WHITE); + jdi_display.setTextSize(2); + jdi_display.setCursor(xPos, yPos + 10); + jdi_display.print("fps"); + + if (fps >= 10) + xPos -= 20; + jdi_display.setTextColor(COLOR_WHITE); + jdi_display.setTextSize(2); + jdi_display.setCursor(xPos + 20, yPos + 35); + jdi_display.print(fps); + jdi_display.refresh(); // Actually updates the display + + fps = frames / ((millis() - startMillis) / 1000); + frames++; +} + +void scrollingColors() { + + int y = 0; + + currentColor = startColor; + + for (int i = 0; i < NUMBER_COLORS; i++) { + jdi_display.fillRect(0, y, rectWidth, rectHeight, colors[currentColor]); + y += rectHeight; + currentColor++; + if (currentColor > NUMBER_COLORS - 1) + currentColor %= NUMBER_COLORS; + } + + currentColor = startColor; + y = jdi_display.height() - rectHeight; + for (int i = 0; i < NUMBER_COLORS; i++) { + jdi_display.fillRect(rectWidth, y, rectWidth, rectHeight, + colors[currentColor]); + y -= rectHeight; + currentColor++; + if (currentColor > NUMBER_COLORS - 1) + currentColor %= NUMBER_COLORS; + } + + if (startColor < NUMBER_COLORS - 1) + startColor++; + else + startColor = 0; +}