查看: 504|回复: 6

[未解决] 怎么在TFT上显示SD卡里的图片,试了很多版本都读取bmp失败

[复制链接]
  • TA的每日心情
    难过
    2018-6-5 17:36
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-6-1 20:14 | 显示全部楼层 |阅读模式
    本帖最后由 q28425361 于 2018-6-1 20:14 编辑

    我就不懂了,sd卡里的图片我再三对应了,bmp都是在example里自带的,program都是用example里的,尺寸都是2.4寸,library也是直接用他的,为什么还是显示不了图片?
    code 是源自于“Arduino Demo code_ArduinoUNO&Mega2560” 版本,我就不懂缺了什么了。还是说还要在sd卡或者library中做点什么?

    code:
    // IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
    // CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
    // SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
    //Technical support:goodtft@163.com

    #include <Adafruit_GFX.h>    // Core graphics library
    #include <Adafruit_TFTLCD.h> // Hardware-specific library
    #include <SD.h>
    #include <SPI.h>


    // The control pins for the LCD can be assigned to any digital or
    // analog pins...but we'll use the analog pins as this allows us to
    // double up the pins with the touch screen (see the TFT paint example).
    #define LCD_CS A3 // Chip Select goes to Analog 3
    #define LCD_CD A2 // Command/Data goes to Analog 2
    #define LCD_WR A1 // LCD Write goes to Analog 1
    #define LCD_RD A0 // LCD Read goes to Analog 0
    #define PIN_SD_CS 10 // Adafruit SD shields and modules: pin 10

    #define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

    // When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
    // For the Arduino Uno, Duemilanove, Diecimila, etc.:
    //   D0 connects to digital pin 8  (Notice these are
    //   D1 connects to digital pin 9   NOT in order!)
    //   D2 connects to digital pin 2
    //   D3 connects to digital pin 3
    //   D4 connects to digital pin 4
    //   D5 connects to digital pin 5
    //   D6 connects to digital pin 6
    //   D7 connects to digital pin 7
    // For the Arduino Mega, use digital pins 22 through 29
    // (on the 2-row header at the end of the board).

    // Assign human-readable names to some common 16-bit color values:
    #define        BLACK   0x0000
    #define        BLUE    0x001F
    #define        RED     0xF800
    #define        GREEN   0x07E0
    #define CYAN    0x07FF
    #define MAGENTA 0xF81F
    #define YELLOW  0xFFE0
    #define WHITE   0xFFFF

    Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
    // If using the shield, all control and data lines are fixed, and
    // a simpler declaration can optionally be used:
    // Adafruit_TFTLCD tft;


    #define MAX_BMP         10                      // bmp file num
    #define FILENAME_LEN    20                      // max file name length

    const int __Gnbmp_height = 320;                 // bmp hight
    const int __Gnbmp_width  = 240;                 // bmp width

    unsigned char __Gnbmp_image_offset  = 0;        // offset

    int __Gnfile_num = 4;                           // num of file

    char __Gsbmp_files[4][FILENAME_LEN] =           // add file name here
    {
    "flower.bmp",
    "tiger.bmp",
    "tree.bmp",
    "RedRose.bmp",
    };
    File bmpFile;

    /*********************************************/
    // This procedure reads a bitmap and draws it to the screen
    // its sped up by reading many pixels worth of data at a time
    // instead of just one pixel at a time. increading the buffer takes
    // more RAM but makes the drawing a little faster. 20 pixels' worth
    // is probably a good place

    #define BUFFPIXEL       60                      // must be a divisor of 240
    #define BUFFPIXEL_X3    180                     // BUFFPIXELx3

    void bmpdraw(File f, int x, int y)
    {
        bmpFile.seek(__Gnbmp_image_offset);

        uint32_t time = millis();

        uint8_t sdbuffer[BUFFPIXEL_X3];                 // 3 * pixels to buffer

        for (int i=0; i< __Gnbmp_height; i++) {
            for(int j=0; j<(240/BUFFPIXEL); j++) {
                bmpFile.read(sdbuffer, BUFFPIXEL_X3);

                uint8_t buffidx = 0;
                int offset_x = j*BUFFPIXEL;
                unsigned int __color[BUFFPIXEL];

                for(int k=0; k<BUFFPIXEL; k++) {
                    __color[k] = sdbuffer[buffidx+2]>>3;                        // read
                    __color[k] = __color[k]<<6 | (sdbuffer[buffidx+1]>>2);      // green
                    __color[k] = __color[k]<<5 | (sdbuffer[buffidx+0]>>3);      // blue

                    buffidx += 3;
                }

                for (int m = 0; m < BUFFPIXEL; m ++) {
                  tft.drawPixel(m+offset_x, i,__color[m]);
                }
            }
        }

        Serial.print(millis() - time, DEC);
        Serial.println(" ms");
    }

    boolean bmpReadHeader(File f)
    {
        // read header
        uint32_t tmp;
        uint8_t bmpDepth;

        if (read16(f) != 0x4D42) {
            // magic bytes missing
            return false;
        }

        // read file size
        tmp = read32(f);
        Serial.print("size 0x");
        Serial.println(tmp, HEX);

        // read and ignore creator bytes
        read32(f);

        __Gnbmp_image_offset = read32(f);
        Serial.print("offset ");
        Serial.println(__Gnbmp_image_offset, DEC);

        // read DIB header
        tmp = read32(f);
        Serial.print("header size ");
        Serial.println(tmp, DEC);

        int bmp_width = read32(f);
        int bmp_height = read32(f);

        if(bmp_width != __Gnbmp_width || bmp_height != __Gnbmp_height)  {    // if image is not 320x240, return false
            return false;
        }

        if (read16(f) != 1)
        return false;

        bmpDepth = read16(f);
        Serial.print("bitdepth ");
        Serial.println(bmpDepth, DEC);

        if (read32(f) != 0) {
            // compression not supported!
            return false;
        }

        Serial.print("compression ");
        Serial.println(tmp, DEC);

        return true;
    }

    /*********************************************/
    // These read data from the SD card file and convert them to big endian
    // (the data is stored in little endian format!)

    // LITTLE ENDIAN!
    uint16_t read16(File f)
    {
        uint16_t d;
        uint8_t b;
        b = f.read();
        d = f.read();
        d <<= 8;
        d |= b;
        return d;
    }

    // LITTLE ENDIAN!
    uint32_t read32(File f)
    {
        uint32_t d;
        uint16_t b;

        b = read16(f);
        d = read16(f);
        d <<= 16;
        d |= b;
        return d;
    }

    void setup(void) {
      Serial.begin(9600);
      Serial.println(F("TFT LCD test"));

    #ifdef USE_ADAFRUIT_SHIELD_PINOUT
      Serial.println(F("Using Adafruit 2.4\" TFT Arduino Shield Pinout"));
    #else
      Serial.println(F("Using Adafruit 2.4\" TFT Breakout Board Pinout"));
    #endif

      Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

      tft.reset();

      uint16_t identifier = tft.readID();
      if(identifier==0x0101)
          identifier=0x9341;

      if(identifier == 0x9325) {
        Serial.println(F("Found ILI9325 LCD driver"));
      } else if(identifier == 0x4535) {
        Serial.println(F("Found LGDP4535 LCD driver"));
      }else if(identifier == 0x9328) {
        Serial.println(F("Found ILI9328 LCD driver"));
      } else if(identifier == 0x7575) {
        Serial.println(F("Found HX8347G LCD driver"));
      } else if(identifier == 0x9341) {
        Serial.println(F("Found ILI9341 LCD driver"));
      } else if(identifier == 0x8357) {
        Serial.println(F("Found HX8357D LCD driver"));
      } else {
        Serial.print(F("Unknown LCD driver chip: "));
        Serial.println(identifier, HEX);
        Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));
        Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
        Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
        Serial.println(F("If using the breakout board, it should NOT be #defined!"));
        Serial.println(F("Also if using the breakout, double-check that all wiring"));
        Serial.println(F("matches the tutorial."));
        return;
      }

      tft.begin(identifier);
      tft.fillScreen(BLUE);



      //Init SD_Card
      pinMode(10, OUTPUT);

      if (!SD.begin(10)) {
        Serial.println("initialization failed!");
        tft.setCursor(0, 0);
        tft.setTextColor(WHITE);   
        tft.setTextSize(1);
        tft.println("SD Card Init fail.");   
      }else
      Serial.println("initialization done.");
    }

    void loop(void) {
         for(unsigned char i=0; i<__Gnfile_num; i++) {
            bmpFile = SD.open(__Gsbmp_files);
            if (! bmpFile) {
                Serial.println("didnt find image");
                tft.setTextColor(WHITE);    tft.setTextSize(1);
                tft.println("didnt find BMPimage");
                while (1);
            }

            if(! bmpReadHeader(bmpFile)) {
                Serial.println("bad bmp");
                tft.setTextColor(WHITE);    tft.setTextSize(1);
                tft.println("bad bmp");
                return;
            }

            bmpdraw(bmpFile, 0, 0);
            bmpFile.close();
            delay(1000);
            delay(1000);
        }

    }

  • TA的每日心情
    难过
    2018-6-5 17:36
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2018-6-1 20:14 | 显示全部楼层
    本帖最后由 q28425361 于 2018-6-1 20:15 编辑

    求救,没想到连参考用的program都没法用。
  • TA的每日心情
    开心
    2018-8-3 21:21
  • 签到天数: 286 天

    [LV.8]以坛为家I

    发表于 2018-6-2 13:41 | 显示全部楼层
    这是我之前研究的结果,看看有没有参考价值。文中提到的偏色问题,可能是颜色顺序应该是BGR而非RGB。另一个副作用是图像镜像显示了。
    https://www.arduino.cn/thread-43201-1-1.html
    打赏作者鼓励一下!
  • TA的每日心情
    擦汗
    2018-7-11 15:37
  • 签到天数: 36 天

    [LV.5]常住居民I

    发表于 2018-6-2 17:26 | 显示全部楼层
    发屏幕型号呀,其实只要能绘点就能显示图片,我发的贴有个web刷图的,那个就能显示bmp,把绘点的地方换成你的这个屏幕的绘点函数就行了
    看作者这么辛苦的份上,打赏鼓励一下!
  • TA的每日心情
    难过
    2018-6-5 17:36
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2018-6-3 18:20 | 显示全部楼层
    跑龙套的保 发表于 2018-6-2 17:26
    发屏幕型号呀,其实只要能绘点就能显示图片,我发的贴有个web刷图的,那个就能显示bmp,把绘点的地方换成你 ...

    种类是SPFD5408
  • TA的每日心情
    开心
    2018-6-9 17:57
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2018-6-9 18:17 | 显示全部楼层
    除了不能显示图片,那些文字、线能显示吗?能的话就肯定可以显示24位的BMP图片
  • TA的每日心情
    难过
    2018-6-5 17:36
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2018-6-14 16:06 | 显示全部楼层
    FrankMaker 发表于 2018-6-9 18:17
    除了不能显示图片,那些文字、线能显示吗?能的话就肯定可以显示24位的BMP图片 ...

    是读取不了,不是显示不了
    高级模式  
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    我住长江头,君住长江尾,恰有同道者,千里来相会
    我住长江头,君住长江尾,
    我住长江头,君住长江尾恰有同道者,千里来相会 OneNET开发者交流会邀你来参加啦~活动
    请问这个串口软件是什么
    请问这个串口软件是什么
    问大佬们,如图的串口软件叫什么呢,跟arduino官方IDE好像不太一样,好用吗
    基于红外接收器与1602的简化科学计算器
    基于红外接收器与1602的简
    上图展示效果 硬件: arduino uno r3 红外接收器和遥控器 1602显示屏 面包板 杜邦线
    请教一下安装esp8266扩展问题
    请教一下安装esp8266扩展
    通过这个地址http://arduino.esp8266.com/stable/package_esp8266com_index.json以在
    云闪付为了购物 小伙居然...
    云闪付为了购物 小伙居然.
    驱动云闪付的屏幕 该屏幕是因为熊孩子拆了云闪付pos机,pos机防拆的机制导致损坏,
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表