代码从作者那拷贝过来的,只做了引脚定义的修改。
#define TFT_DC 27
#define TFT_RST 26
#define TFT_CS 5
#define TFT_MOSI 23
#define TFT_SCLK 18
屏幕是ST7789的SPI屏
/*
*@功能:ESP32读取SD卡图片显示在1.14IPS屏幕上
*@作者:刘泽文
*@时间:2020/3/27
*/
//引用相关库
#include <SD.h>
#include <FS.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <JPEGDecoder.h>
#define DEBUG
#ifdef DEBUG
#define DebugPrintln(message) Serial.println(message)
#else
#define DebugPrintln(message)
#endif
#ifdef DEBUG
#define DebugPrint(message) Serial.print(message)
#else
#define DebugPrint(message)
#endif
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
void drawSdJpeg(const char *filename, int xpos, int ypos);
void jpegRender(int xpos, int ypos);
void jpegInfo();
void showTime(uint32_t msTime);
void SD_read_Time(uint32_t msTime);
void setup()
{
Serial.begin(9600);
DebugPrintln();
tft.init();
SPIClass sdSPI(VSPI);
#define SD_MISO 13
#define SD_MOSI 12
#define SD_SCLK 17
#define SD_CS 14
tft.setRotation(2);
tft.fillScreen(TFT_WHITE);
tft.setTextSize(1);
tft.setTextColor(TFT_MAGENTA);
tft.setCursor(0, 0);
tft.setTextDatum(MC_DATUM);
tft.setTextSize(1);
tft.setSwapBytes(true);
delay(500);
//挂载文件系统
sdSPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
if (!SD.begin(SD_CS, sdSPI))
{
DebugPrintln("存储卡挂载失败");
return;
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE)
{
DebugPrintln("未连接存储卡");
return;
}
else if (cardType == CARD_MMC)
{
DebugPrintln("挂载了MMC卡");
}
else if (cardType == CARD_SD)
{
DebugPrintln("挂载了SDSC卡");
}
else if (cardType == CARD_SDHC)
{
DebugPrintln("挂载了SDHC卡");
}
else
{
DebugPrintln("挂载了未知存储卡");
}
//打印存储卡信息
Serial.printf("存储卡总大小是: %lluMB \n", SD.cardSize() / (1024 * 1024)); // "/ (1024 * 1024)"可以换成">> 20"
Serial.printf("文件系统总大小是: %lluB \n", SD.totalBytes());
Serial.printf("文件系统已用大小是: %lluB \n", SD.usedBytes());
//测试壁纸
for(int image_num = 1;image_num<=20;image_num++){
char FileName[15];
sprintf(FileName,"/gif/%d.jpg",image_num);
drawSdJpeg(FileName, 0, 0); // This draws a jpeg pulled off the SD Card
//delay(00);
}
}
void loop() {
}
void drawSdJpeg(const char *filename, int xpos, int ypos) {
uint32_t readTime = millis();
// Open the named file (the Jpeg decoder library will close it)
File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library
if ( !jpegFile ) {
DebugPrint("ERROR: File \"");
DebugPrint(filename);
DebugPrintln ("\" not found!");
return;
}
DebugPrintln("===========================");
DebugPrint("Drawing file: "); DebugPrintln(filename);
DebugPrintln("===========================");
// Use one of the following methods to initialise the decoder:
boolean decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder,
//boolean decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array)
SD_read_Time(millis() - readTime);
if (decoded) {
// print information about the image to the serial port
jpegInfo();
// render the image onto the screen at given coordinates
jpegRender(xpos, ypos);
}
else {
DebugPrintln("Jpeg file format not supported!");
}
}
//####################################################################################################
// Draw a JPEG on the TFT, images will be cropped on the right/bottom sides if they do not fit
//####################################################################################################
// This function assumes xpos,ypos is a valid screen coordinate. For convenience images that do not
// fit totally on the screen are cropped to the nearest MCU size and may leave right/bottom borders.
void jpegRender(int xpos, int ypos) {
// record the current time so we can measure how long it takes to draw an image
uint32_t drawTime = millis();
//jpegInfo(); // Print information from the JPEG file (could comment this line out)
uint16_t *pImg;
uint16_t mcu_w = JpegDec.MCUWidth;
uint16_t mcu_h = JpegDec.MCUHeight;
uint32_t max_x = JpegDec.width;
uint32_t max_y = JpegDec.height;
bool swapBytes = tft.getSwapBytes();
tft.setSwapBytes(true);
// Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
// Typically these MCUs are 16x16 pixel blocks
// Determine the width and height of the right and bottom edge image blocks
uint32_t min_w = (mcu_w<(max_x % mcu_w)?mcu_wmax_x % mcu_w));
uint32_t min_h = (mcu_h<(max_y % mcu_h)?mcu_hmax_y % mcu_h));
// save the current image block size
uint32_t win_w = mcu_w;
uint32_t win_h = mcu_h;
// save the coordinate of the right and bottom edges to assist image cropping
// to the screen size
max_x += xpos;
max_y += ypos;
// Fetch data from the file, decode and display
while (JpegDec.read()) { // While there is more data in the file
pImg = JpegDec.pImage ; // Decode a MCU (Minimum Coding Unit, typically a 8x8 or 16x16 pixel block)
// Calculate coordinates of top left corner of current MCU
int mcu_x = JpegDec.MCUx * mcu_w + xpos;
int mcu_y = JpegDec.MCUy * mcu_h + ypos;
// check if the image block size needs to be changed for the right edge
if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
else win_w = min_w;
// check if the image block size needs to be changed for the bottom edge
if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
else win_h = min_h;
// copy pixels into a contiguous block
if (win_w != mcu_w)
{
uint16_t *cImg;
int p = 0;
cImg = pImg + win_w;
for (int h = 1; h < win_h; h++)
{
p += mcu_w;
for (int w = 0; w < win_w; w++)
{
*cImg = *(pImg + w + p);
cImg++;
}
}
}
// calculate how many pixels must be drawn
uint32_t mcu_pixels = win_w * win_h;
// draw image MCU block only if it will fit on the screen
if (( mcu_x + win_w ) <= tft.width() && ( mcu_y + win_h ) <= tft.height())
tft.pushImage(mcu_x, mcu_y, win_w, win_h, pImg);
else if ( (mcu_y + win_h) >= tft.height())
JpegDec.abort(); // Image has run off bottom of screen so abort decoding
}
tft.setSwapBytes(swapBytes);
showTime(millis() - drawTime); //将图片显示到屏幕所用的时间(ms)
}
void jpegInfo() {
DebugPrintln("JPEG image info");
DebugPrintln("===============");
DebugPrint("Width :");
DebugPrintln(JpegDec.width);
DebugPrint("Height :");
DebugPrintln(JpegDec.height);
DebugPrint("Components :");
DebugPrintln(JpegDec.comps);
DebugPrint("MCU / row :");
DebugPrintln(JpegDec.MCUSPerRow);
DebugPrint("MCU / col :");
DebugPrintln(JpegDec.MCUSPerCol);
DebugPrint("Scan type :");
DebugPrintln(JpegDec.scanType);
DebugPrint("MCU width :");
DebugPrintln(JpegDec.MCUWidth);
DebugPrint("MCU height :");
DebugPrintln(JpegDec.MCUHeight);
DebugPrintln("===============");
DebugPrintln("");
}
void showTime(uint32_t msTime) {
DebugPrint(F(" JPEG drawn in "));
DebugPrint(msTime);
DebugPrintln(F(" ms "));
}
void SD_read_Time(uint32_t msTime) {
Serial.print(F(" SD JPEG read in "));
Serial.print(msTime);
Serial.println(F(" ms "));
}
问题出在了
//测试壁纸
for(int image_num = 1;image_num<=20;image_num++){
char FileName[15];
sprintf(FileName,"/gif/%d.jpg",image_num);
drawSdJpeg(FileName, 0, 0); // This draws a jpeg pulled off the SD Card
这段代码 放step()里面能够跑,哪怕for循环10次也可以。但是一放在loop里面 就会一直报错重启
求助 求助!!!! 解决了的话 可以发小红包
|