arduino/mixly TFT显示SD卡的图片

一、器材

SD卡模块

 1.8寸TFT屏,ST7735

arduino uno开发板

SD卡

 

 

二、接线

     TFT屏arduino uno

GND

GND
VCC5V
SCLD13
SDAD11
RESD8
DCD10
CSD9
BLD7

 

SD卡模块arduino uno
GNDGND
VCC5V
MISOD12
MOSID11
CLKD13
CSD4

三、正式开始

首先我们从网上找到一张想要显示的图片,比如下面这一张

 然后我们打开电脑自带的画图工具打开这张图片

然后重新调整像素大小到以下图所示160*128

 然后保存为。bmp格式的图片,这里我保存为x.bmp然后移动到SD卡中,再把SD卡插到SD卡模块中即可。

再复制以下程序,下载到arduino中



#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SD.h>
#include <SPI.h>

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

// TFT display and SD card will share the hardware SPI interface.
// Hardware SPI pins are specific to the Arduino board type and
// cannot be remapped to alternate pins.  For Arduino Uno,
// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK.
#define SD_CS    4  // Chip select line for SD card
#define TFT_CS  9  // Chip select line for TFT display
#define TFT_DC   10  // Data/command line for TFT
#define TFT_RST  8  // Reset line for TFT (or connect to +5V)

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

#define BUFFPIXEL 20

void bmpDraw(char *filename, uint8_t x, uint8_t y) {

  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();

  if((x >= tft.width()) || (y >= tft.height())) return;

  Serial.println();
  Serial.print("Loading image '");
  Serial.print(filename);
  Serial.println('\'');

  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    Serial.print("File not found");
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) { // BMP signature
    Serial.print("File size: "); Serial.println(read32(bmpFile));
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    Serial.print("Image Offset: "); Serial.println(bmpImageoffset, DEC);
    // Read DIB header
    Serial.print("Header size: "); Serial.println(read32(bmpFile));
    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      Serial.print("Bit Depth: "); Serial.println(bmpDepth);
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        Serial.print("Image size: ");
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);

        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;

        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width())  w = tft.width()  - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;

        // Set TFT address window to clipped image bounds
        tft.startWrite();
        tft.setAddrWindow(x, y, w, h);

        for (row=0; row<h; row++) { // For each scanline...

          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            tft.endWrite();
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each pixel...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
              tft.startWrite();
            }

            // Convert pixel from BMP to TFT format, push to display
            r = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            b = sdbuffer[buffidx++];
            tft.pushColor(tft.color565(r,g,b));
          } // end pixel
        } // end scanline
        tft.endWrite();
        Serial.print("Loaded in ");
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) Serial.println("BMP format not recognized.");
}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}

void setup(void) {
  pinMode(12,INPUT); // Set SD's MISO IO State, VERY IMPORTANT!
  Serial.begin(9600);

  // Initialize 1.8" TFT
  tft.initR(INITR_GREENTAB);   // initialize a ST7735S chip, green tab
  tft.setRotation(3);

  Serial.println("OK!");
  tft.fillScreen(ST7735_BLACK);
}

void loop() {
    Serial.print("Initializing SD card...");
    if (!SD.begin(SD_CS)) {
      Serial.println("failed!");
      tft.setTextSize(2);
      tft.fillScreen(ST7735_BLACK);
      tft.setCursor(0, 0);
      tft.setTextColor(ST7735_BLUE);
      tft.print("SD Card init error!");
      return;
    }
 bmpDraw("x.bmp", 0, 0);
}

效果

 

  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要在Arduino上使用TFT屏幕显示图片,需要进行以下步骤: 1. 准备一个兼容ArduinoTFT屏幕和相应的库文件。常用的TFT屏幕包括ILI9341和ST7735等,可以在网上购买。对应的库文件可以在Arduino的库管理器中搜索并安装。 2. 将TFT屏幕连接到Arduino板子上。具体连接方式可以参考相应的引脚图,一般需要连接SPI接口和相应的引脚。 3. 编写Arduino代码,在代码中引入TFT库文件并初始化TFT屏幕。初始化时需要设置屏幕的宽度、高度和颜色模式等参数。 4. 将要显示图片转换为数组形式,并将数组中的像素点依次写入TFT屏幕的缓存中。这个过程可以使用图片处理软件进行转换和处理。 5. 在代码中调用TFT库中的显示函数,将缓存中的像素点显示TFT屏幕上。 下面是一个简单的例子,展示了如何在Arduino上使用TFT屏幕显示一张图片: ```C++ #include <Adafruit_GFX.h> // GFX库,用于绘制图形 #include <Adafruit_ILI9341.h> // ILI9341 LCD库,用于驱动TFT屏幕 // 定义TFT屏幕的引脚连接 #define TFT_CS 10 #define TFT_DC 9 #define TFT_MOSI 11 #define TFT_CLK 13 #define TFT_RST 8 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST); // 定义要显示图片 const uint16_t IMAGE_WIDTH = 160; // 图片宽度 const uint16_t IMAGE_HEIGHT = 128; // 图片高度 const uint16_t image[] = { // 图片数组 // 在这里添加图片的像素点,每个像素点需要用16位的数据表示 }; void setup() { tft.begin(); // 初始化TFT屏幕 tft.setRotation(3); // 设置屏幕旋转方向 } void loop() { // 将图片像素点写入TFT屏幕的缓存中 tft.startWrite(); for (uint16_t y = 0; y < IMAGE_HEIGHT; y++) { for (uint16_t x = 0; x < IMAGE_WIDTH; x++) { uint16_t pixel = image[y * IMAGE_WIDTH + x]; tft.writePixel(x, y, pixel); } } tft.endWrite(); // 结束写入 delay(5000); // 等待5秒钟后重新显示图片 } ``` 在这个例子中,首先定义了TFT屏幕的引脚连接和要显示图片数组。然后在`setup()`函数中初始化TFT屏幕,并在`loop()`函数中将图片像素点写入TFT屏幕的缓存中,并显示在屏幕上。最后等待5秒钟后重新显示图片

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值