TFT LCD数据存储为BMP文件的C语言代码

在硬件平台:STM32 +SSD1963+4.3TFT(TP)+TFcard 实现了将显示数据存储为bmp文件的应用。

TFT应用为RGB565格式的16位色显示480*272分辨率,bmp文件RGB565格式的位图很多软件打不开,大部分是只支持RGB555的。因此做了两种类型 的代码。bmp文件存储在TF卡,以下代码已通过调试。

#define LCD_READ_BUFFER_SIZE 2048//1024

#define FILE_HEADER_SIZE 0x36//0x3E//0x36

#define RGB565_FILE_HEADER_SIZE 0x46//0x3E//0x36

uint8_t  LCDReadDataBuffer[LCD_READ_BUFFER_SIZE];//[WAVEFRAMEBUFFERSIZE+1];
const char bmpname[21][11]={"DSO01.bmp","DSO02.bmp","DSO03.bmp","DSO04.bmp","DSO05.bmp","DSO06.bmp","DSO07.bmp","DSO08.bmp","DSO09.bmp","DSO10.bmp","DSO11.bmp","DSO12.bmp","DSO13.bmp","DSO14.bmp","DSO15.bmp","DSO16.bmp","DSO17.bmp","DSO18.bmp","DSO19.bmp","DSO20.bmp","DSO21.bmp"};

#ifdef RGB565_FILE
const char BmpHeaderRGB565[RGB565_FILE_HEADER_SIZE]={
//file header 
0x42,0x4D,     //0x00~0x01,type"BM"
0x48,0xFC,0x03,0x00, //0x02~0x05,file size:16bit:480x2(RGB565)x272+0x36+2(result need Divisible by 4)
0x00,0x00,0x00,0x00, //0x06~0x09,reserved 0x00
0x46,0x00,0x00,0x00, //0x0A~0x0D,bmp data offset
0x38,0x00,0x00,0x00, //0x0E~0x11,bmp header size
0xE0,0x01,0x00,0x00, //0x12~0x15,480
0x10,0x01,0x00,0x00, //0x16~0x19,height:272
0x01,0x00,      //0x1A~0x1B,planes:always"1"
//information header
0x10,0x00,   //0x1C~0x1D,bits per pixel:16bits;
0x03,0x00,0x00,0x00, //0x1E~0x21,compression:no
0x02,0xFC,0x03,0x00, //0x22~0x25,bmp data size:480*2(R5G6B5)*272+2(result need Divisible by 4)
0x00,0x00,0x00,0x00, //0x26~0x29,HResolution
0x00,0x00,0x00,0x00, //0x2A~0x2D,VResolution
0x00,0x00,0x00,0x00, //0x2E~0x31,colors
0x00,0x00,0x00,0x00, //0x32~0x35,important
//Palettte: RGB565
///*
0x00,0xF8,0x00,  //0x36~0x38,Blue mask:& 0xF800)>>8
0x00,0xE0,0x07,  //0x39~0x3B,Green mask:& 0x07E0)>>3
0x00,0x00,0x1F,  //0x3C~0x3E,Red mask:& 0x001F)<<3;
0x00,0x00,0x00,  //0x3F~0x41,Alpha
0x00,0x00,0x00,0x00,  //0x42~0x45,reserved
//*/
};
#else //RGB555 bmp file
const char BmpHeader[FILE_HEADER_SIZE]={
//file header 
0x42,0x4D,     //0x00~0x01,type"BM"
0x38,0xFC,0x03,0x00, //0x02~0x05,file size:16bit:480x2(RGB565)x272+0x36+2(result need Divisible by 4)
0x00,0x00,0x00,0x00, //0x06~0x09,reserved 0x00
0x36,0x00,0x00,0x00, //0x0A~0x0D,bmp data offset
0x28,0x00,0x00,0x00, //0x0E~0x11,bmp header size
0xE0,0x01,0x00,0x00, //0x12~0x15,480
0x10,0x01,0x00,0x00, //0x16~0x19,height:272
0x01,0x00,      //0x1A~0x1B,planes:always"1"
//information header
0x10,0x00,   //0x1C~0x1D,bits per pixel:16bits;
0x00,0x00,0x00,0x00, //0x1E~0x21,compression:no
0x02,0xFC,0x03,0x00, //0x22~0x25,bmp data size:480*2(R5G6B5)*272+2(result need Divisible by 4)
0x00,0x00,0x00,0x00, //0x26~0x29,HResolution
0x00,0x00,0x00,0x00, //0x2A~0x2D,VResolution
0x00,0x00,0x00,0x00, //0x2E~0x31,colors
0x00,0x00,0x00,0x00, //0x32~0x35,important
//Palettte: RGB555 :no

};
#endif

void LCDReadLine(u16 x,u16 y)
{
    u32 i;
    u16 colordata;
 //u8  Rdata,Gdata;
 u8 Bdata;
 
 LcdSetArea(x,y,FRAMEBUFFER_COL-1,y);
 WriteCommand(0x2E);
    for(i = 0; i <FRAMEBUFFER_COL; i++)
    {
     colordata=ReadData();//LSB first
     #ifdef RGB565_FILE
  LCDReadDataBuffer[i*2]=(uint8_t)colordata;//LSB first 
  LCDReadDataBuffer[i*2+1]=(uint8_t)(colordata>>8);//LSB first 
  #else//RGB565==>RGB555
  //Rdata=(uint8_t)(colordata>>11);//mask:0xF800 
  //Gdata=(uint8_t)((colordata&0x07E0)>>5);//mask:0x07E0
  Bdata=(uint8_t)(colordata&0x001F);//mask:0x001F 
  LCDReadDataBuffer[i*2]=(uint8_t)(((colordata>>1)&0x03E0)|Bdata);//LSB first 
  LCDReadDataBuffer[i*2+1]=(uint8_t)(colordata>>9);//LSB first 
  #endif
  
    }   
}


/*******************************************************************************
LcdSaveBmp: 保存当前屏幕显示图像为BMP格式    输入:文件编号     返回值:0x00=成功
*******************************************************************************/
u8 LCDSaveBmp(u8 FileNum)
{
  FIL bmpfile;
  UINT bw;
 
  FATFS fs;
  FRESULT res;

  u16  x=0, y=0;
  u8   fileend[]={0x00,0x00,0x00,0x00};
 
//  u8   testbuffer[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
 // u8   i, j, k;
 
  if(FileNum>20) //max filenum:21
  {
   FileNum=0x00;
  }
//open file to write
  res = f_mount(0, &fs);  
  res = f_open(&bmpfile, bmpname[FileNum], FA_OPEN_EXISTING | FA_WRITE);   //open picture file 
  if(res != FR_OK)
  {
   res = f_open(&bmpfile, bmpname[FileNum], FA_CREATE_ALWAYS| FA_WRITE);   //open picture file 
  }

  if(res != FR_OK)
  {
   return res;
  } 
 
  //header//FILE_HEADER_SIZE//BmpHeader
  //  f_write(fil, &c, 1, &bw);   /* Write a byte to the file */
#ifdef RGB565_FILE
  res = f_write(&bmpfile,BmpHeaderRGB565,RGB565_FILE_HEADER_SIZE,&bw);
  if( res != FR_OK )
  {
   return res;
  }
#else
 res = f_write(&bmpfile,BmpHeader,FILE_HEADER_SIZE,&bw);
 if( res != FR_OK )
 {
  return res;
 }

#endif 
// 
//   0x0036; //data RGB555
//   0x0046; //data RGB565

  for(y=0; y<272; y++)
  {
    x=0;
 //LCDReadBuffer(x,y,480*2);//line 480*2//480*RGB
 LCDReadLine(x,(271-y));//read data to LCDReadDataBuffer
 res = f_write(&bmpfile,LCDReadDataBuffer,480*2,&bw);
 if( res != FR_OK )
 {
  return res;
 }
  }
  f_write(&bmpfile,fileend, 2, &bw);   /* Write  bytes to the file */
//read test  
  //  res = f_lseek(&bmpfile, bmpfile.fsize);  /* Move to end of the file to append data */
  //  res = f_lseek(&bmpfile, 0);/* Put file header */ 
/*
  f_close(&bmpfile);
  f_open(&bmpfile, bmpname[FileNum], FA_OPEN_EXISTING | FA_READ); 
  f_read(&bmpfile,LCDReadDataBuffer,LCD_READ_BUFFER_SIZE,&bw);
*/
//close open file
  f_close(&bmpfile);
  f_mount(0, NULL);  


  return FR_OK;
 
}

原文地址:https://www.cnblogs.com/glguan/p/2343034.html