你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32单片机图片解码

[复制链接]
STMCU小助手 发布时间:2022-1-28 18:28
图片解码首先是最简单的bmp图片解码,关于bmp的结构可自行查阅,代码如下
  1. #ifndef __BMPDECODE_H_
  2. #define __BMPDECODE_H_

  3. #include "ff.h"
  4. #include "lcd.h"
  5. #include "stdlib.h"
  6. #include "usb_type.h"

  7. //重定义区
  8. typedef char            CHAR;                     //数据类型重定义,便于移植
  9. typedef short           SHORT;
  10. //typedef int            LONG;               
  11. //typedef unsigned int   DWORD;
  12. typedef int             BOOL;
  13. typedef u8              BYTE;
  14. typedef unsigned short  WORD;

  15. //#define FALSE 0
  16. //#define TRUE  1

  17. //BMP图象数据压缩的类型
  18. #define BI_RGB       0L          //无压缩
  19. #define BI_RLE8      1L          //每个像素四个bit
  20. #define BI_RLE4      2L          //每个像素8个bit
  21. #define BI_BITFIELDS 3L          //每个像素的bit由指定的掩码决定

  22. #define bufferToLong(buffer,t)   (LONG)((((u32)bmpbuffer[t])) + (((u32)bmpbuffer[t+1])<<8) +(((u32)bmpbuffer[t+2])<<16) + (((u32)bmpbuffer[t+3])<<24))
  23. #define bufferToWord(buffer,t)  (WORD)(((u32)(buffer[t])) + (((u32)(buffer[t+1]))<<8))
  24. #define bufferToDword(buffer,t)  (DWORD)((((u32)bmpbuffer[t])) + (((u32)bmpbuffer[t+1])<<8) +(((u32)bmpbuffer[t+2])<<16) + (((u32)bmpbuffer[t+3])<<24))

  25. #define RGB888buffertoRGB565(buffer,t)   ((((u16)buffer[t])>>3) + ((((u16)buffer[t+1])>>2)<<5) + ((((u16)buffer[t+2])>>3)<<11))


  26. //BMP文件头   14个字节
  27. typedef __packed struct     
  28. {
  29.     WORD  bfType ;     //文件标志.只对'BM',用来识别BMP位图类型 2
  30.     DWORD bfSize ;       //文件大小,占四个字节     4
  31.     WORD  bfReserved1 ;//保留            2
  32.     WORD  bfReserved2 ;//保留            2
  33.     DWORD bfOffBits ;  //从文件开始到位图数据(bitmap data)开始之间的的偏移量,这一段中存放的就是文件信息 4
  34. }BITMAPFILEHEADER ;            //位图文件头

  35. //位图信息头
  36. typedef __packed struct               
  37. {
  38.     DWORD biSize ;           //说明BITMAPINFOHEADER结构所需要的字数。
  39.     LONG  biWidth ;           //说明图象的宽度,以象素为单位
  40.     LONG  biHeight ;       //说明图象的高度,以象素为单位
  41.     WORD  biPlanes ;       //为目标设备说明位面数,其值将总是被设为1
  42.     WORD  biBitCount ;       //说明比特数/象素,其值为1、4、8、16、24、或32
  43.     DWORD biCompression ;  //说明图象数据压缩的类型。其值可以是下述值之一:
  44.     /*BI_RGB:没有压缩;
  45.      *BI_RLE8:每个象素8比特的RLE压缩编码,压缩格式由2字节组成(重复象素计数和颜色索引);  
  46.      *BI_RLE4:每个象素4比特的RLE压缩编码,压缩格式由2字节组成
  47.        *BI_BITFIELDS:每个象素的比特由指定的掩码决定。*/
  48.     DWORD biSizeImage ;//说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0  
  49.     LONG  biXPelsPerMeter ;//说明水平分辨率,用象素/米表示
  50.     LONG  biYPelsPerMeter ;//说明垂直分辨率,用象素/米表示
  51.     DWORD biClrUsed ;       //说明位图实际使用的彩色表中的颜色索引数
  52.     DWORD biClrImportant ; //说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
  53. }BITMAPINFOHEADER;

  54. //颜色索引表,每个颜色索引占4个字节,16位以及以下才会有这个数据 也就是说 最多65535个数据
  55. //当然,最好不要用16位色的,浪费空间
  56. typedef __packed struct
  57. {
  58.     BYTE rgbBlue ;    //指定蓝色强度
  59.     BYTE rgbGreen ;      //指定绿色强度
  60.     BYTE rgbRed ;      //指定红色强度
  61.     BYTE rgbReserved ;//保留,设置为0
  62. }RGBQUAD ;

  63. BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey);






  64. #endif
复制代码
  1. u8 bmpbuffer[1024] = {0};       //存储bmp文件的数组

  2. //解码这个BMP文件
  3. //设定显示起始位置以及终止位置                                             
  4. BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey)
  5. {
  6.     FIL f_bmp;              //文件系统变量,用于读取bmp文件
  7.     u16 filereadnum = 0;    //用于记录文件字节读取数量
  8.     FRESULT res;            //文件读取返回信息
  9.     BITMAPFILEHEADER bmpfileHead;  //位图文件头
  10.     BITMAPINFOHEADER bmpinfoHead;  //位图信息头
  11.     u8 colorByte = 0;               //用于标记颜色位
  12.     u16 index = 0;          //读取文件信息时候用来定位
  13.     u16 uitemp = 0;         //记录实际数据一行有多少个点
  14.     u16 xtemp = 0;
  15.     u16 ytemp = 0;          //显示时辅助计数
  16.     u16 colortemp = 0;      //颜色缓冲
  17.    
  18.     res=f_open(&f_bmp,(const TCHAR*)filename,FA_READ);  //打开文件   
  19.     if(res!=FR_OK) return FALSE;
  20.      res = f_read(&f_bmp,bmpbuffer,1024,(UINT*)&filereadnum); //读取文件
  21.     if(res!=FR_OK) return FALSE;
  22.    
  23.     //获取位图文件头
  24.     bmpfileHead.bfType =  (WORD)((((u16)bmpbuffer[0])<<8) + bmpbuffer[1+1]);
  25.     bmpfileHead.bfSize = bufferToDword(bmpbuffer,2);
  26.     bmpfileHead.bfReserved1 = bufferToWord(bmpbuffer,6);
  27.     bmpfileHead.bfReserved2 = bufferToWord(bmpbuffer,8);
  28.     bmpfileHead.bfOffBits = bufferToDword(bmpbuffer,10);    //数据段开始地址
  29.     //获取位图信息头
  30.     bmpinfoHead.biSize = bufferToDword(bmpbuffer,14);   
  31.     bmpinfoHead.biWidth = bufferToLong(bmpbuffer,18);   
  32.     bmpinfoHead.biHeight = bufferToLong(bmpbuffer,22);  
  33.     bmpinfoHead.biPlanes = bufferToWord(bmpbuffer,26);   
  34.     bmpinfoHead.biBitCount = bufferToWord(bmpbuffer,28);    //颜色位  
  35.     bmpinfoHead.biCompression = bufferToDword(bmpbuffer,30);
  36.     bmpinfoHead.biSizeImage = bufferToDword(bmpbuffer,34);
  37.     bmpinfoHead.biXPelsPerMeter = bufferToLong(bmpbuffer,38);
  38.     bmpinfoHead.biYPelsPerMeter = bufferToLong(bmpbuffer,42);
  39.     bmpinfoHead.biClrUsed = bufferToDword(bmpbuffer,46);  
  40.     bmpinfoHead.biClrImportant = bufferToDword(bmpbuffer,50);
  41.     index = bmpfileHead.bfOffBits;
  42.     //所有信息得到,这里应该进行测试了
  43.    
  44.     colorByte =  bmpinfoHead.biBitCount/8;      //颜色位数 16 / 24 / 32 得到2/3/4
  45.     if((bmpinfoHead.biWidth%4) != 0)   //不是4的倍数
  46.     {
  47.         uitemp = (((bmpinfoHead.biWidth/4) + 1) * 4);
  48.     }
  49.     else                        //是4的倍数
  50.     {
  51.         uitemp = bmpinfoHead.biWidth ;
  52.     }
  53.     if(colorByte == 3)  //24位颜色
  54.     {
  55.         while(1)
  56.         {
  57.             if(index <= 1021)
  58.             {
  59.                 colortemp = RGB888buffertoRGB565(bmpbuffer,index);
  60.                 index = index +3;
  61.                 if(sx+xtemp <ex && sy+ytemp < ey)
  62.                 LCD_Draw_Point_Buffer(sx+xtemp,sy+ytemp,colortemp);
  63.                 xtemp++;
  64.                 if(xtemp >= uitemp)
  65.                 {
  66.                     xtemp = 0;
  67.                     ytemp++;
  68.                 }
  69.             }
  70.             else
  71.             {
  72.                 if(index == 1022)
  73.                 {
  74.                     if(sx+xtemp <ex && sy+ytemp < ey)
  75.                     LCD_Draw_Point_Buffer(sx+xtemp,sy+ytemp,colortemp);
  76.                     xtemp++;
  77.                     if(xtemp >= uitemp)
  78.                     {
  79.                         xtemp = 0;
  80.                         ytemp++;
  81.                     }
  82.                     index = 1;
  83.                 }
  84.                 else if(index == 1023)
  85.                 {
  86.                     if(sx+xtemp <ex && sy+ytemp < ey)
  87.                     LCD_Draw_Point_Buffer(sx+xtemp,sy+ytemp,colortemp);
  88.                     xtemp++;
  89.                     if(xtemp >= uitemp)
  90.                     {
  91.                         xtemp = 0;
  92.                         ytemp++;
  93.                     }
  94.                     index = 2;
  95.                 }
  96.                 else index = 0;
  97.                 res = f_read(&f_bmp,bmpbuffer,1024,(UINT*)&filereadnum); //读取文件
  98.                 if(res||filereadnum==0)break;        //读取出错
  99.             }
  100.         }        
  101.     }
  102.     f_close(&f_bmp);     /* 关闭打开的文件 */
  103.    
  104.     LCD_Flush();
  105.     return TRUE;
  106. }
复制代码
为了防止图片刷新速度过慢可以在内存中建立一个屏幕缓存,解码完成后一次性刷入屏幕
JPEG图片解码使用网络上一个tjpgdec的库,该库的移植如下
  1. #ifndef __JPGDEC_CALLBACK_H_
  2. #define __JPGDEC_CALLBACK_H_

  3. #include "lcd.h"
  4. #include "ff.h"
  5. #include "tjpgd.h"
  6. #include "stdlib.h"

  7. void load_jpg (FIL *fp,void *work,UINT sz_work);

  8. void load_file (const char *fn);


  9. #endif
复制代码
  1. // 以下3句宏定义在tjpgd.h中修改
  2. static int MaskL = 0;
  3. static int MaskR = LCD_X_SIZE - 1;
  4. static int MaskT = 0;
  5. static int MaskB = LCD_Y_SIZE - 1;

  6. #define SIZE_OF_FILE_BUFFER        4096

  7. BYTE* jpegbuffer; //图像文件数据缓冲区

  8. /*********************************************************************************************
  9.   函数名称:    STM32_Display
  10.   函数功能:    在TFTLCD屏幕上显示图片
  11.   入口参数:    见函数头
  12.   出口参数:    无
  13.   全局变量:       无
  14.   备注说明:    无
  15. *********************************************************************************************/
  16. void Lcd_Display_Rect(
  17.                             int left,                            /*图片左方起始点,即一行的起始点 */
  18.                             int right,                           /*图片右方的结束点,即一行的结束点*/
  19.                             int top,                             /* 图片上方的起始点,即一列的起始点 */
  20.                             int bottom,                          /*图像下方的结束点,即一列的结束点 */
  21.                             const uint16_t * RGB_Data_Pointer    /* 待显示的图像数据,RGB格式*/
  22.                         )
  23. {
  24.     int yc, xc, xl, xs;
  25.     unsigned short pd;

  26.     if (left > right || top > bottom)  
  27.     {
  28.         return;             // Check varidity
  29.     }
  30.    
  31.     if (left > MaskR || right < MaskL  || top > MaskB || bottom < MaskT)  
  32.     {
  33.         return;                // Check if in active area  
  34.     }     
  35.     yc = bottom - top + 1 ;            /* Vertical size */
  36.     xc = right - left + 1; xs = 0;    /* Horizontal size and skip */
  37.    
  38.     // 已经计算出了要绘制的x方向pixels和y方向pixels
  39.     // 上下左右的值已经校正为,为屏幕上的绝对位置,由此可以算出屏幕缓冲区的起始位置
  40.     do {    /* Send image data */
  41.         xl = xc;
  42.         do {
  43.             pd = *RGB_Data_Pointer++;
  44.             LCD_Draw_Point_Buffer(right - xl,bottom - yc,pd);            //显示像素
  45.         } while (--xl);
  46.         RGB_Data_Pointer += xs;
  47.     } while (--yc);
  48. }


  49. BYTE Buff[1024] __attribute__ ((aligned(4)));    //定义全局数组变量,作为输入的缓冲区,强制4字节对齐
  50. /*********************************************************************************************
  51.   函数名称:    Jpeg_Data_in_func
  52.   函数功能:    用户自定义的用于输入文件数据的功能函数
  53.   入口参数:    见函数头
  54.   出口参数:    读取或者删除的数据量
  55.   全局变量:       无
  56.   备注说明:    本函数在解码准备工作中用于读取文件头信息
  57. *********************************************************************************************/
  58. UINT Jpeg_Data_in_func (
  59.                             JDEC* jd,        /*储存待解码的对象信息的结构体 */
  60.                             BYTE* buff,        /* 输入数据缓冲区 (NULL:删除数据) */
  61.                             UINT nd            /*需要从输入数据流读出/删除的数据量*/
  62.                       )
  63. {
  64.     UINT  rb;
  65.     FIL * dev = (FIL *)jd->device;    /* 待解码的文件的信息,使用FATFS中的FIL结构类型进行定义 */   
  66.     if (buff)     /*读取数据有效,开始读取数据 */
  67.     {
  68.         f_read(dev, buff, nd, &rb); //调用FATFS的f_read函数,用于把jpeg文件的数据读取出来
  69.         return rb;        /* 返回读取到的字节数目*/
  70.     }  
  71.     else  
  72.     {
  73.         return (f_lseek(dev, f_tell(dev) + nd) == FR_OK) ? nd : 0;/* 重新定位数据点,相当于删除之前的n字节数据 */
  74.     }
  75. }


  76. /*********************************************************************************************
  77.   函数名称:    STM32_out_func
  78.   函数功能:    用户自定义的用于输出RGB位图数据的功能函数
  79.   入口参数:    见函数头
  80.   出口参数:    1:令解码函数继续执行
  81.   全局变量:       无
  82.   备注说明:    无
  83. *********************************************************************************************/
  84. UINT Jpeg_Data_out_func (
  85.                          JDEC*   jd,        /*储存待解码的对象信息的结构体*/
  86.                          void*   bitmap,    /* 指向等待输出的RGB位图数据 的指针*/
  87.                          JRECT*  rect      /* 等待输出的矩形图像的参数 */
  88.                         )
  89. {
  90.     jd = jd;    /* 说明:输出函数中JDEC结构体没有用到 */

  91.     //显示一块区域到LCD上
  92.     Lcd_Display_Rect(rect->left, rect->right, rect->top, rect->bottom, (uint16_t*)bitmap);
  93.    
  94.     return 1;    /*返回1,使解码工作继续执行 */
  95. }


  96. //加载并显示jpg文件
  97. void load_jpg (
  98.     FIL *fp,        /* 指向打开的文件执政 */
  99.     void *work,        /*指向四字节对其的工作区缓存 */
  100.     UINT sz_work    /*工作区的大小 */
  101. )
  102. {
  103.     JDEC jd;        /* Decoder object (124 bytes) */
  104.     JRESULT rc;
  105.     BYTE scale;


  106.     /* Prepare to decompress the file */
  107.     rc = jd_prepare(&jd, Jpeg_Data_in_func, work, sz_work, fp);
  108.     if (rc == JDR_OK)
  109.     {
  110.         /* 根据图片大小选选择一个刚刚好能够缩放的图片比例 */
  111.         for (scale = 0; scale < 3; scale++)
  112.         {
  113.             if ((jd.width >> scale) <= LCD_X_SIZE && (jd.height >> scale) <= LCD_Y_SIZE) break;
  114.         }
  115.         rc = jd_decomp(&jd, Jpeg_Data_out_func, scale);    /* Start to decompress */
  116.     } else
  117.     {
  118.         //显示错误,将错误信息打印在屏幕上
  119.         printf("jpg error %d\r\n",rc);
  120.     }
  121. }

  122. /*参数:指向文件名 */
  123. void load_file (const char *fn)
  124. {
  125.     FIL fil;            /* Pointer to a file object */

  126.     if (f_open(&fil, fn, FA_READ) == FR_OK)
  127.     {
  128.         jpegbuffer = NULL;
  129.         jpegbuffer = malloc(SIZE_OF_FILE_BUFFER);
  130.         if(jpegbuffer != NULL)
  131.         {
  132.             LCD_Fill_Buffer(LCD_BLACK);
  133.             load_jpg(&fil, (void *)jpegbuffer, SIZE_OF_FILE_BUFFER );  //打开jpg文件并解码显示   
  134.         }
  135.         f_close(&fil);
  136.         if(jpegbuffer != NULL)free(jpegbuffer);
  137.         LCD_Flush();
  138.     }
  139.     else
  140.     {
  141.         printf("open file failed\r\n");
  142.     }
  143. }
复制代码
该库的解码性能还不错,使用了图片流的概念来进行解码操作,剩下的是一个GIF图片解码,如下
  1. #ifndef __GIFDECODE_H_
  2. #define __GIFDECODE_H_

  3. #include "ff.h"
  4. #include "lcd.h"
  5. #include "stdlib.h"


  6. #define MAX_NUM_LWZ_BITS     12
  7. #define LCD_MAX_LOG_COLORS  256

  8. #define GIF_INTRO_TERMINATOR ';'    //0X3B   GIF文件结束符
  9. #define GIF_INTRO_EXTENSION  '!'    //0X21
  10. #define GIF_INTRO_IMAGE      ','    //0X2C

  11. #define GIF_COMMENT         0xFE
  12. #define GIF_APPLICATION     0xFF
  13. #define GIF_PLAINTEXT       0x01
  14. #define GIF_GRAPHICCTL      0xF9

  15. #define PIC_FORMAT_ERR        0x27    //格式错误
  16. #define PIC_SIZE_ERR        0x28    //图片尺寸错误
  17. #define PIC_WINDOW_ERR        0x29    //窗口设定错误
  18. #define PIC_MEM_ERR            0x11    //内存错误

  19. typedef struct
  20. {
  21.     u8    aBuffer[258];                     // Input buffer for data block
  22.     short aCode  [(1 << MAX_NUM_LWZ_BITS)]; // This array stores the LZW codes for the compressed strings
  23.     u8    aPrefix[(1 << MAX_NUM_LWZ_BITS)]; // Prefix character of the LZW code.
  24.     u8    aDecompBuffer[3000];              // Decompression buffer. The higher the compression, the more bytes are needed in the buffer.
  25.     u8 *  sp;                               // Pointer into the decompression buffer
  26.     int   CurBit;
  27.     int   LastBit;
  28.     int   GetDone;
  29.     int   LastByte;
  30.     int   ReturnClear;
  31.     int   CodeSize;
  32.     int   SetCodeSize;
  33.     int   MaxCode;
  34.     int   MaxCodeSize;
  35.     int   ClearCode;
  36.     int   EndCode;
  37.     int   FirstCode;
  38.     int   OldCode;
  39. }LZW_INFO;

  40. //逻辑屏幕描述块
  41. __packed typedef struct
  42. {
  43.     u16 width;        //GIF宽度
  44.     u16 height;        //GIF高度
  45.     u8 flag;        //标识符  1:3:1:3=全局颜色表标志(1):颜色深度(3):分类标志(1):全局颜色表大小(3)
  46.     u8 bkcindex;    //背景色在全局颜色表中的索引(仅当存在全局颜色表时有效)
  47.     u8 pixratio;    //像素宽高比
  48. }LogicalScreenDescriptor;


  49. //图像描述块
  50. __packed typedef struct
  51. {
  52.     u16 xoff;        //x方向偏移
  53.     u16 yoff;        //y方向偏移
  54.     u16 width;        //宽度
  55.     u16 height;        //高度
  56.     u8 flag;        //标识符  1:1:1:2:3=局部颜色表标志(1):交织标志(1):保留(2):局部颜色表大小(3)
  57. }ImageScreenDescriptor;

  58. //图像描述
  59. __packed typedef struct
  60. {
  61.     LogicalScreenDescriptor gifLSD;    //逻辑屏幕描述块
  62.     ImageScreenDescriptor gifISD;    //图像描述快
  63.     u16 colortbl[256];                //当前使用颜色表
  64.     u16 bkpcolortbl[256];            //备份颜色表.当存在局部颜色表时使用
  65.     u16 numcolors;                    //颜色表大小
  66.     u16 delay;                        //延迟时间
  67.     LZW_INFO *lzw;                    //LZW信息
  68. }gif89a;

  69. extern u8 gifdecoding;    //GIF正在解码标记.

  70. u8 gif_check_head(FIL *file);                                                            //检测GIF头
  71. u16 gif_getrgb565(u8 *ctb);                                                                //将RGB888转为RGB565
  72. u8 gif_readcolortbl(FIL *file,gif89a * gif,u16 num);                                    //读取颜色表
  73. u8 gif_getinfo(FIL *file,gif89a * gif);                                                    //得到逻辑屏幕描述,图像尺寸等
  74. void gif_savegctbl(gif89a* gif);                                                        //保存全局颜色表
  75. void gif_recovergctbl(gif89a* gif);                                                        //恢复全局颜色表
  76. void gif_initlzw(gif89a* gif,u8 codesize);                                                //初始化LZW相关参数
  77. u16 gif_getdatablock(FIL *gfile,u8 *buf,u16 maxnum);                                       //读取一个数据块
  78. u8 gif_readextension(FIL *gfile,gif89a* gif, int *pTransIndex,u8 *pDisposal);               //读取扩展部分
  79. int gif_getnextcode(FIL *gfile,gif89a* gif);                                               //从LZW缓存中得到下一个LZW码,每个码包含12位
  80. int gif_getnextbyte(FIL *gfile,gif89a* gif);                                            //得到LZW的下一个码
  81. u8 gif_dispimage(FIL *gfile,gif89a* gif,u16 x0,u16 y0,int Transparency, u8 Disposal);    //显示图片
  82. void gif_clear2bkcolor(u16 x,u16 y,gif89a* gif,ImageScreenDescriptor pimge);               //恢复成背景色
  83. u8 gif_drawimage(FIL *gfile,gif89a* gif,u16 x0,u16 y0);                                    //画GIF图像的一帧

  84. u8 gif_decode(const u8 *filename,u16 x,u16 y,u16 width,u16 height);//在指定区域解码一个GIF文件.
  85. void gif_quit(void);                                    //退出当前解码.











  86. #endif
复制代码
这是UCGUI的库,性能差一点的单片机解码起来有点慢,看起来有点卡,哦对了还是用了fatfs文件系统,移植接口如下
  1. /*-----------------------------------------------------------------------*/
  2. /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2014        */
  3. /*-----------------------------------------------------------------------*/
  4. /* If a working storage control module is available, it should be        */
  5. /* attached to the FatFs via a glue function rather than modifying it.   */
  6. /* This is an example of glue functions to attach various exsisting      */
  7. /* storage control modules to the FatFs module with a defined API.       */
  8. /*-----------------------------------------------------------------------*/

  9. #include "diskio.h"        /* FatFs lower layer API */
  10. #include "sdcard.h"        /* Example: MMC/SDC contorl */

  11. #define MMC        0    /* Example: Map MMC/SD card to drive number 1 */


  12. /*-----------------------------------------------------------------------*/
  13. /* Get Drive Status                                                      */
  14. /*-----------------------------------------------------------------------*/

  15. DSTATUS disk_status (
  16.     BYTE pdrv        /* Physical drive nmuber to identify the drive */
  17. )
  18. {
  19.     DSTATUS stat;
  20.     int result;

  21.     switch (pdrv)
  22.     {
  23.     case MMC :
  24.         result = SDCARD_Get_Sector_Count();
  25.         if(result == 0)stat = STA_NOINIT;
  26.         else stat = 0;//OK
  27.         return stat;
  28.     }
  29.     return STA_NOINIT;
  30. }



  31. /*-----------------------------------------------------------------------*/
  32. /* Inidialize a Drive                                                    */
  33. /*-----------------------------------------------------------------------*/

  34. DSTATUS disk_initialize (
  35.     BYTE pdrv                /* Physical drive nmuber to identify the drive */
  36. )
  37. {
  38.     DSTATUS stat;
  39.     int result;

  40.     switch (pdrv)
  41.     {
  42.     case MMC :
  43.         result = SDCARD_Init();
  44.         if(result == 0)stat = 0;
  45.         else //STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常
  46.         {
  47.             SPI2_Set_Speed(SPI_SPEED_256);
  48.             SPI2_Write_Read_Byte(0xff);//提供额外的8个时钟
  49.             SPI2_Set_Speed(SPI_SPEED_4);
  50.             stat = STA_NOINIT;//error
  51.         }
  52.         return stat;
  53.     }
  54.     return STA_NOINIT;
  55. }



  56. /*-----------------------------------------------------------------------*/
  57. /* Read Sector(s)                                                        */
  58. /*-----------------------------------------------------------------------*/

  59. DRESULT disk_read (
  60.     BYTE pdrv,        /* Physical drive nmuber to identify the drive */
  61.     BYTE *buff,        /* Data buffer to store read data */
  62.     DWORD sector,    /* Sector address in LBA */
  63.     UINT count        /* Number of sectors to read */
  64. )
  65. {
  66.     DRESULT res;
  67.     int result;

  68.     switch (pdrv)
  69.     {

  70.     case MMC :
  71.         result = SDCARD_Read_Sector(buff, sector, count);
  72.         if(result == 0)res = RES_OK;
  73.         else res = RES_ERROR;
  74.         return res;

  75.     }

  76.     return RES_PARERR;
  77. }



  78. /*-----------------------------------------------------------------------*/
  79. /* Write Sector(s)                                                       */
  80. /*-----------------------------------------------------------------------*/

  81. #if _USE_WRITE
  82. DRESULT disk_write (
  83.     BYTE pdrv,            /* Physical drive nmuber to identify the drive */
  84.     const BYTE *buff,    /* Data to be written */
  85.     DWORD sector,        /* Sector address in LBA */
  86.     UINT count            /* Number of sectors to write */
  87. )
  88. {
  89.     DRESULT res;
  90.     int result;

  91.     switch (pdrv)
  92.     {
  93.     case MMC :
  94.         result = SDCARD_Write_Sector((u8*)buff, sector, count);
  95.         if(result == 0)res = RES_OK;
  96.         else res = RES_ERROR;
  97.         return res;

  98.     }

  99.     return RES_PARERR;
  100. }
  101. #endif


  102. /*-----------------------------------------------------------------------*/
  103. /* Miscellaneous Functions                                               */
  104. /*-----------------------------------------------------------------------*/

  105. #if _USE_IOCTL
  106. DRESULT disk_ioctl (
  107.     BYTE pdrv,        /* Physical drive nmuber (0..) */
  108.     BYTE cmd,        /* Control code */
  109.     void *buff        /* Buffer to send/receive control data */
  110. )
  111. {
  112.     DRESULT res;

  113.     switch (pdrv)
  114.     {
  115.     case MMC :
  116.         switch(cmd)
  117.         {
  118.             case CTRL_SYNC:
  119.                 SD_CS=0;
  120.                 if(SDCARD_Wait_Ready()==0)res = RES_OK;
  121.                 else res = RES_ERROR;      
  122.                 SD_CS=1;
  123.                 break;     
  124.             case GET_SECTOR_SIZE:
  125.                 *(WORD*)buff = 512;
  126.                 res = RES_OK;
  127.                 break;     
  128.             case GET_BLOCK_SIZE:
  129.                 *(WORD*)buff = 8;
  130.                 res = RES_OK;
  131.                 break;     
  132.             case GET_SECTOR_COUNT:
  133.                 *(DWORD*)buff = SDCARD_Get_Sector_Count();
  134.                 res = RES_OK;
  135.                 break;
  136.             default:
  137.                 res = RES_PARERR;
  138.                 break;
  139.         }
  140.         return res;
  141.     }

  142.     return RES_PARERR;
  143. }
  144. #endif
复制代码


收藏 评论0 发布时间:2022-1-28 18:28

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版