在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32的FATFS文件系統(tǒng)移植筆記

            STM32的FATFS文件系統(tǒng)移植筆記

            作者: 時(shí)間:2016-11-26 來源:網(wǎng)絡(luò) 收藏
            一、序言

            經(jīng)常在網(wǎng)上、群里看到很多人問關(guān)于STM32的FATFS文件系統(tǒng)移植的問題,剛好自己最近也在調(diào)試這個(gè)程序,為了讓大家少走彎路,我把我的調(diào)試過程和方法也貢獻(xiàn)給大家。

            二、FATFS簡(jiǎn)介
            FatFs Module是一種完全免費(fèi)開源的FAT文件系統(tǒng)模塊,專門為小型的嵌入式系統(tǒng)而設(shè)計(jì)。它完全用標(biāo)準(zhǔn)C語(yǔ)言編寫,所以具有良好的硬件平臺(tái)獨(dú)立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列單片機(jī)上而只需做簡(jiǎn)單的修改。它支持FATl2、FATl6和FAT32,支持多個(gè)存儲(chǔ)媒介;有獨(dú)立的緩沖區(qū),可以對(duì)多個(gè)文件進(jìn)行讀/寫,并特別對(duì)8位單片機(jī)和16位單片機(jī)做了優(yōu)化。

            三、移植準(zhǔn)備
            1、FATFS源代碼的獲取,可以到官網(wǎng)下載:http://elm-chan.org/fsw/ff/00index_e.html最新版本是R0.09版本,我們就移植這個(gè)版本的。
            2、解壓文件會(huì)得到兩個(gè)文件夾,一個(gè)是doc文件夾,這里是FATFS的一些使用文檔和說明,以后在文件編程的時(shí)候可以查看該文檔。另一個(gè)是src文件夾,里面就是我們所要的源文件。
            3、建立一個(gè)STM32的工程,為方便調(diào)試,我們應(yīng)重載printf()底層函數(shù)實(shí)現(xiàn)串口打印輸出??梢詤⒖家呀?jīng)建立好的printf()打印輸出工程:http://www.viewtool.com/bbs/foru ... d=77&extra=page%3D1
            四、開始移植
            1、在已經(jīng)建立好的工程目錄User文件夾下新建兩個(gè)文件夾,F(xiàn)ATFS_V0.09和SPI_SD_Card,F(xiàn)ATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驅(qū)動(dòng)文件。
            2、如圖1將ff.c添加到工程文件夾中,并新建diskio.c文件,在diskio.c文件中實(shí)現(xiàn)五個(gè)函數(shù):

            本文引用地址:http://www.biyoush.com/article/201611/321826.htm
            1. DSTATUS disk_initialize (BYTE);//SD卡的初始化
            2. DSTATUS disk_status (BYTE);//獲取SD卡的狀態(tài),這里可以不用管
            3. DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//從SD卡讀取數(shù)據(jù)
            4. DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//將數(shù)據(jù)寫入SD卡,若該文件系統(tǒng)為只讀文件系統(tǒng)則不用實(shí)現(xiàn)該函數(shù)
            5. DRESULT disk_ioctl (BYTE, BYTE, void*);//獲取SD卡文件系統(tǒng)相關(guān)信息
            復(fù)制代碼



            圖1
            3、初步實(shí)現(xiàn)以上五個(gè)函數(shù)
            FATFS初始化函數(shù):

            1. DSTATUS disk_initialize (
            2. BYTE drv /* Physical drive nmuber (0..) */
            3. )
            4. {
            5. switch (drv)
            6. {
            7. case 0 :
            8. return RES_OK;
            9. case 1 :
            10. return RES_OK;
            11. case 2 :
            12. return RES_OK;
            13. case 3 :
            14. return RES_OK;
            15. default:
            16. return STA_NOINIT;
            17. }
            18. }
            復(fù)制代碼

            FATFS狀態(tài)獲取函數(shù):

            1. DSTATUS disk_status (
            2. BYTE drv /* Physical drive nmuber (0..) */
            3. )
            4. {
            5. switch (drv)
            6. {
            7. case 0 :
            8. return RES_OK;
            9. case 1 :
            10. return RES_OK;
            11. case 2 :
            12. return RES_OK;
            13. default:
            14. return STA_NOINIT;
            15. }
            16. }
            復(fù)制代碼

            FATFS底層讀數(shù)據(jù)函數(shù):

            1. DRESULT disk_read (
            2. BYTE drv, /* Physical drive nmuber (0..) */
            3. BYTE *buff, /* Data buffer to store read data */
            4. DWORD sector, /* Sector address (LBA) */
            5. BYTE count /* Number of sectors to read (1..255) */
            6. )
            7. {
            8. if( !count )
            9. {
            10. return RES_PARERR;/* count不能等于0,否則返回參數(shù)錯(cuò)誤 */
            11. }
            12. switch (drv)
            13. {
            14. case 0:
            15. if(count==1) /* 1個(gè)sector的讀操作 */
            16. {
            17. return RES_OK;
            18. }
            19. else /* 多個(gè)sector的讀操作 */
            20. {
            21. return RES_OK;
            22. }
            23. case 1:
            24. if(count==1) /* 1個(gè)sector的讀操作 */
            25. {
            26. return RES_OK;
            27. }
            28. else /* 多個(gè)sector的讀操作 */
            29. {
            30. return RES_OK;
            31. }
            32. default:
            33. return RES_ERROR;
            34. }
            35. }
            復(fù)制代碼

            FATFS底層寫數(shù)據(jù)函數(shù):

            1. DRESULT disk_write (
            2. BYTE drv, /* Physical drive nmuber (0..) */
            3. const BYTE *buff, /* Data to be written */
            4. DWORD sector, /* Sector address (LBA) */
            5. BYTE count /* Number of sectors to write (1..255) */
            6. )
            7. {
            8. if( !count )
            9. {
            10. return RES_PARERR;/* count不能等于0,否則返回參數(shù)錯(cuò)誤 */
            11. }
            12. switch (drv)
            13. {
            14. case 0:
            15. if(count==1) /* 1個(gè)sector的寫操作 */
            16. {
            17. return RES_OK;
            18. }
            19. else /* 多個(gè)sector的寫操作 */
            20. {
            21. return RES_OK;
            22. }
            23. case 1:
            24. if(count==1) /* 1個(gè)sector的寫操作 */
            25. {
            26. return RES_OK;
            27. }
            28. else /* 多個(gè)sector的寫操作 */
            29. {
            30. return RES_OK;
            31. }
            32. default:return RES_ERROR;
            33. }
            34. }
            復(fù)制代碼

            FATFS磁盤控制函數(shù):

            1. DRESULT disk_ioctl (
            2. BYTE drv, /* Physical drive nmuber (0..) */
            3. BYTE ctrl, /* Control code */
            4. void *buff /* Buffer to send/receive control data */
            5. )
            6. {
            7. if (drv==0)
            8. {
            9. switch (ctrl)
            10. {
            11. case CTRL_SYNC :
            12. return RES_OK;
            13. case GET_SECTOR_COUNT :
            14. return RES_OK;
            15. case GET_BLOCK_SIZE :
            16. return RES_OK;
            17. case CTRL_POWER :
            18. break;
            19. case CTRL_LOCK :
            20. break;
            21. case CTRL_EJECT :
            22. break;
            23. /* MMC/SDC command */
            24. case MMC_GET_TYPE :
            25. break;
            26. case MMC_GET_CSD :
            27. break;
            28. case MMC_GET_CID :
            29. break;
            30. case MMC_GET_OCR :
            31. break;
            32. case MMC_GET_SDSTAT :
            33. break;
            34. }
            35. }else if(drv==1){
            36. switch (ctrl)
            37. {
            38. case CTRL_SYNC :
            39. return RES_OK;
            40. case GET_SECTOR_COUNT :
            41. return RES_OK;
            42. case GET_SECTOR_SIZE :
            43. return RES_OK;
            44. case GET_BLOCK_SIZE :
            45. return RES_OK;
            46. case CTRL_POWER :
            47. break;
            48. case CTRL_LOCK :
            49. break;
            50. case CTRL_EJECT :
            51. break;
            52. /* MMC/SDC command */
            53. case MMC_GET_TYPE :
            54. break;
            55. case MMC_GET_CSD :
            56. break;
            57. case MMC_GET_CID :
            58. break;
            59. case MMC_GET_OCR :
            60. break;
            61. case MMC_GET_SDSTAT :
            62. break;
            63. }
            64. }
            65. else{
            66. return RES_PARERR;
            67. }
            68. return RES_PARERR;
            69. }
            復(fù)制代碼

            以上函數(shù)都只是實(shí)現(xiàn)一個(gè)框架,并沒有做實(shí)際的事情,下一步就需要把操作SD卡的程序填充在這個(gè)框架里面。
            4、實(shí)現(xiàn)disk_initialize()函數(shù)
            該函數(shù)在掛載文件系統(tǒng)的時(shí)候會(huì)被調(diào)用,主要是實(shí)現(xiàn)讀寫SD卡前對(duì)SD卡進(jìn)行初始化,根據(jù)SD卡的傳輸協(xié)議,我們按照如下步驟初始化SD卡:
            a、判斷SD卡是否插入,可以通過檢查SD卡卡座的CD腳電平進(jìn)行判斷,一般插入卡后該引腳會(huì)變成低電平。
            b、稍微延時(shí)一段時(shí)間后發(fā)送至少74個(gè)時(shí)鐘給SD卡。
            c、發(fā)送CMD0命令給SD卡,直到SD卡返回0x01為止,這里可以循環(huán)多次發(fā)送。
            程序如下:

            1. /* Start send CMD0 till return 0x01 means in IDLE state */
            2. for(retry=0; retry<0xFFF; retry++)
            3. {
            4. r1 = MSD0_send_command(CMD0, 0, 0x95);
            5. if(r1 == 0x01)
            6. {
            7. retry = 0;
            8. break;
            9. }
            10. }
            復(fù)制代碼

            d、發(fā)送CMD8獲取卡的類型,不同類型的卡其初始化方式有所不同。
            e、根據(jù)卡的類型對(duì)卡進(jìn)行初始化。具體初始化方式可以參考附件程序。
            注:在初始化SD卡之前應(yīng)該初始化SPI接口和相關(guān)的管腳。
            實(shí)現(xiàn)后的程序如下:

            1. DSTATUS disk_initialize (
            2. BYTE drv /* Physical drive nmuber (0..) */
            3. )
            4. {
            5. int Status;
            6. switch (drv)
            7. {
            8. case 0 :
            9. Status = MSD0_Init();
            10. if(Status==0){
            11. return RES_OK;
            12. }else{
            13. return STA_NOINIT;
            14. }
            15. case 1 :
            16. return RES_OK;
            17. case 2 :
            18. return RES_OK;
            19. case 3 :
            20. return RES_OK;
            21. default:
            22. return STA_NOINIT;
            23. }
            24. }
            復(fù)制代碼

            MSD0_Init()函數(shù)在SPI_MSD0_Driver.c文件中實(shí)現(xiàn)。
            5、實(shí)現(xiàn)disk_read()函數(shù)
            該函數(shù)是讀取SD卡扇區(qū)數(shù)據(jù)的函數(shù),根據(jù)SD卡數(shù)據(jù)傳輸協(xié)議可知有讀取單扇區(qū)和讀取多扇區(qū)兩種操作模式,為提高讀文件的速度應(yīng)該實(shí)現(xiàn)讀取多扇區(qū)函數(shù)。
            實(shí)現(xiàn)后的程序如下:

            1. DRESULT disk_read (
            2. BYTE drv, /* Physical drive nmuber (0..) */
            3. BYTE *buff, /* Data buffer to store read data */
            4. DWORD sector, /* Sector address (LBA) */
            5. BYTE count /* Number of sectors to read (1..255) */
            6. )
            7. {
            8. int Status;
            9. if( !count )
            10. {
            11. return RES_PARERR;/* count不能等于0,否則返回參數(shù)錯(cuò)誤 */
            12. }
            13. switch (drv)
            14. {
            15. case 0:
            16. if(count==1) /* 1個(gè)sector的讀操作 */
            17. {
            18. Status =MSD0_ReadSingleBlock( sector ,buff );
            19. if(Status == 0){
            20. return RES_OK;
            21. }else{
            22. return RES_ERROR;
            23. }
            24. }
            25. else /* 多個(gè)sector的讀操作 */
            26. {
            27. Status = MSD0_ReadMultiBlock( sector , buff ,count);
            28. if(Status == 0){
            29. return RES_OK;
            30. }else{
            31. return RES_ERROR;
            32. }
            33. }
            34. case 1:
            35. if(count==1) /* 1個(gè)sector的讀操作 */
            36. {
            37. return RES_OK;
            38. }
            39. else /* 多個(gè)sector的讀操作 */
            40. {
            41. return RES_OK;
            42. }
            43. default:
            44. return RES_ERROR;
            45. }
            46. }
            復(fù)制代碼

            MSD0_ReadSingleBlock()和MSD0_ReadMultiBlock()函數(shù)都是SD卡操作的底層函數(shù),我們?cè)赟PI_MSD0_Driver.c文件中實(shí)現(xiàn)。
            6、實(shí)現(xiàn)disk_write()函數(shù)
            該函數(shù)主要實(shí)現(xiàn)對(duì)SD卡進(jìn)行寫數(shù)據(jù)操作,和讀數(shù)據(jù)操作一樣也分單塊寫和多塊寫,建議實(shí)現(xiàn)多塊寫的方式,這樣可以提高寫數(shù)據(jù)速度。
            實(shí)現(xiàn)后的程序如下:

            1. DRESULT disk_write (
            2. BYTE drv, /* Physical drive nmuber (0..) */
            3. const BYTE *buff, /* Data to be written */
            4. DWORD sector, /* Sector address (LBA) */
            5. BYTE count /* Number of sectors to write (1..255) */
            6. )
            7. {
            8. int Status;
            9. if( !count )
            10. {
            11. return RES_PARERR;/* count不能等于0,否則返回參數(shù)錯(cuò)誤 */
            12. }
            13. switch (drv)
            14. {
            15. case 0:
            16. if(count==1) /* 1個(gè)sector的寫操作 */
            17. {
            18. Status = MSD0_WriteSingleBlock( sector , (uint8_t *)(&buff[0]) );
            19. if(Status == 0){
            20. return RES_OK;
            21. }else{
            22. return RES_ERROR;
            23. }
            24. }
            25. else /* 多個(gè)sector的寫操作 */
            26. {
            27. Status = MSD0_WriteMultiBlock( sector , (uint8_t *)(&buff[0]) , count );
            28. if(Status == 0){
            29. return RES_OK;
            30. }else{
            31. return RES_ERROR;
            32. }
            33. }
            34. case 1:
            35. if(count==1) /* 1個(gè)sector的寫操作 */
            36. {
            37. return RES_OK;
            38. }
            39. else /* 多個(gè)sector的寫操作 */
            40. {
            41. return RES_OK;
            42. }
            43. default:return RES_ERROR;
            44. }
            45. }
              上一頁(yè) 1 2 下一頁(yè)

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉