找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3931|回復(fù): 2
收起左側(cè)

求代碼 單片機(jī)控制MMC存儲(chǔ)卡讀寫(xiě)測(cè)試源程序+Proteus仿真文件

[復(fù)制鏈接]
ID:430780 發(fā)表于 2019-3-13 19:23 | 顯示全部樓層 |閱讀模式
K1:從開(kāi)始位置開(kāi)始寫(xiě)入0x00-0xFF, 0x00-0xFF(512字節(jié))
K2:從第512字節(jié)位置開(kāi)始寫(xiě)入512個(gè)隨機(jī)字節(jié)
K3:讀取前512個(gè)字節(jié)并顯示
K4:讀取后512個(gè)字節(jié)并顯示
操作過(guò)程中可嘗試"熱插撥"MMC卡,觀察運(yùn)行效果

MMC存儲(chǔ)卡仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png 0.png

單片機(jī)控制MMC存儲(chǔ)卡源程序如下:
  1. //-----------------------------------------------------------------
  2. // 名稱: MMC卡塊讀寫(xiě)程序
  3. //-----------------------------------------------------------------
  4. #include <reg51.h>
  5. #include <intrins.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <absacc.h>
  10. #define INT8U  unsigned char
  11. #define INT16U unsigned int
  12. #define INT32U unsigned long
  13. //SPI接口存儲(chǔ)器引腳定義
  14. sbit CS  = P3^2;                                //片選
  15. sbit DI  = P3^3;                                //串行數(shù)據(jù)輸入
  16. sbit DO  = P3^4;                                //串行數(shù)據(jù)輸出
  17. sbit CLK = P3^5;                                //串行時(shí)鐘控制腳
  18. //MMC卡使能與禁止操作
  19. #define MMC_CS_EN() CS = 0
  20. #define MMC_CS_DI() CS = 1
  21. //MMC卡操作命令幀(6字節(jié),48位)
  22. INT8U cmd[6] = { 0x00,0x00,0x00,0x00,0x00,0x00 };
  23. extern void delay_ms(INT16U);
  24. //塊字節(jié)讀寫(xiě)緩沖
  25. #define Block_Date &XBYTE[0x0000]
  26. #define delay_10us() {_nop_();_nop_();_nop_();_nop_();_nop_();\
  27.                                                 _nop_();_nop_();_nop_();_nop_();_nop_();}
  28. //-----------------------------------------------------------------
  29. // 打開(kāi)SPI
  30. //-----------------------------------------------------------------
  31. void OpenSPI() { CS = 1; CLK = 0; }
  32. //-----------------------------------------------------------------
  33. // 從當(dāng)前地址讀取一字節(jié)數(shù)據(jù)
  34. //-----------------------------------------------------------------
  35. INT8U getcSPI()
  36. {


  37. }

  38. //-----------------------------------------------------------------
  39. // 向當(dāng)前地址寫(xiě)入一字節(jié)數(shù)據(jù)
  40. //-----------------------------------------------------------------
  41. void putcSPI(INT8U dat)
  42. {


  43. }

  44. //-----------------------------------------------------------------
  45. // MMC命令幀清0
  46. //-----------------------------------------------------------------
  47. void clear_cmd_frame()
  48. {


  49. }

  50. //-----------------------------------------------------------------
  51. // 寫(xiě)MMC命令
  52. //-----------------------------------------------------------------
  53. INT8U MMC_Write_Command(INT8U *cmd_frame)
  54. {


  55. }

  56. //-----------------------------------------------------------------
  57. // MMC初始化
  58. //-----------------------------------------------------------------
  59. INT8U MMC_Initialise()
  60. {


  61. }

  62. //-----------------------------------------------------------------
  63. // 從指定的塊地址讀取單個(gè)塊字節(jié)數(shù)據(jù)
  64. //-----------------------------------------------------------------
  65. INT8U MMC_Read_Block(INT32U address)
  66. {
  67.         INT16U i;
  68.         clear_cmd_frame();                                                //命令幀清0
  69.         cmd[0] = 0x51;                                                        //設(shè)置CMD17(0x51....0xFF)(讀單個(gè)塊)
  70.         cmd[5] = 0xFF;
  71.         address = address<<9;                                        //地址<<9位,取512的整數(shù)倍
  72.         cmd[1]  = address>>24;                                        //將address分解到
  73.         cmd[2]  = address>>16;                                        //四字節(jié)的命令幀參數(shù)中
  74.         cmd[3]  = address>>8;
  75.         cmd[4]  = address>>0;
  76.         if(MMC_Write_Command(cmd) != 0x00) return 0; //發(fā)送CMD17
  77.         while(getcSPI() != 0xFE) _nop_();                //等待數(shù)據(jù)接受開(kāi)始(0xFE)
  78.         for(i = 0;i < 512; i++)                                        //讀取塊數(shù)據(jù)(512字節(jié))
  79.           XBYTE[i] = getcSPI();
  80.         getcSPI();getcSPI();                                        //取走2字節(jié)的CRC
  81.         return 1;
  82. }
  83.         
  84. //-----------------------------------------------------------------
  85. // 向指定的塊地址開(kāi)始寫(xiě)入單個(gè)塊字節(jié)數(shù)據(jù)
  86. //-----------------------------------------------------------------
  87. INT8U MMC_Write_Block(INT32U address)
  88. {
  89.         INT16U i,Dout;
  90.         clear_cmd_frame();                                                //命令幀清0
  91.         cmd[0] = 0x58;                                                        //設(shè)置CMD24(0x58....0xFF)(寫(xiě)單個(gè)塊)
  92.         cmd[5] = 0xFF;
  93.         address = address<<9;                                        //地址<<9位,取512的整數(shù)倍
  94.         cmd[1]  = address>>24;                                        //將address分解到
  95.         cmd[2]  = address>>16;                                        //四字節(jié)的命令幀參數(shù)中
  96.         cmd[3]  = address>>8;
  97.         cmd[4]  = address>>0;
  98.         if(MMC_Write_Command(cmd) != 0x00) return 0; //發(fā)送CMD24
  99.         putcSPI(0xFF);                                                        //發(fā)送填沖字節(jié)
  100.         putcSPI(0xFE);                                                        //發(fā)送數(shù)據(jù)開(kāi)始標(biāo)志0xFE
  101.         //將塊讀寫(xiě)緩沖Block_bytes中的512字節(jié)數(shù)據(jù)寫(xiě)入MMC
  102.         for(i = 0;i < 512; i++) putcSPI(XBYTE[i]);
  103.         putcSPI(0xFF);                                                        //寫(xiě)入2字節(jié)CRC(未計(jì)算)
  104.         putcSPI(0xFF);
  105.         Dout = getcSPI() & 0x1F;                                //讀取返回?cái)?shù)據(jù)中的低5位
  106.         if(Dout != 0x05) return 0;                                //如果未能讀到XXX0 0101則寫(xiě)入失敗
  107.         while(getcSPI() == 0x00) _nop_();                 //忙等待
  108.         return 1;
  109. }
復(fù)制代碼
  1. //-----------------------------------------------------------------
  2. //  名稱: MMC存儲(chǔ)卡測(cè)試
  3. //-----------------------------------------------------------------
  4. //  說(shuō)明: 本例運(yùn)行時(shí),按下K1將向MMC卡第0塊寫(xiě)入512個(gè)有序字節(jié),按下K2時(shí)
  5. //                將向第1塊寫(xiě)入512個(gè)隨機(jī)字節(jié),按下K3與K4時(shí)將分別讀取并通過(guò)
  6. //                虛擬終端顯示這些字節(jié)數(shù)據(jù).
  7. //
  8. //-----------------------------------------------------------------
  9. #include <reg51.h>
  10. #include <intrins.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14. #include <absacc.h>
  15. #define INT8U  unsigned char
  16. #define INT16U unsigned int
  17. #define INT32U unsigned long
  18. //定義按鍵操作
  19. #define K1_DOWN() !(P1 & (1<<0))
  20. #define K2_DOWN() !(P1 & (1<<2))
  21. #define K3_DOWN() !(P1 & (1<<4))
  22. #define K4_DOWN() !(P1 & (1<<6))
  23. //MMC相關(guān)函數(shù)
  24. extern void OpenSPI();
  25. extern INT8U MMC_Initialise();
  26. extern INT8U MMC_Read_Block(INT32U address);
  27. extern INT8U MMC_Write_Block(INT32U address);
  28. //串口相關(guān)函數(shù)
  29. extern void Init_USART();
  30. extern void PutChar(char c);
  31. extern void PutStr(char *s);
  32. INT8U OP = 0;                        //當(dāng)前按鍵操作代號(hào)
  33. INT8U ERROR_Flag = 1;        //MMC卡操作錯(cuò)誤標(biāo)識(shí)(為1表示正常,為0表示出錯(cuò))
  34. //-----------------------------------------------------------------
  35. // 延時(shí)函數(shù)
  36. //-----------------------------------------------------------------
  37. void delay_ms(INT16U x) {INT8U t; while(x--) for(t = 0; t<120; t++);}
  38. //-----------------------------------------------------------------
  39. // 以十六進(jìn)制形式顯示所讀取的字節(jié)
  40. //-----------------------------------------------------------------
  41. void Show_Byte_by_HEX(INT32U Len)
  42. {
  43.         INT32U i; char s[] = "   ";//字符串初始為三個(gè)空格
  44.         for (i = 0; i < Len; i++)
  45.         {




  46.         }
  47.         PutStr("\r--------Finished!--------\r");
  48. }

  49. //-----------------------------------------------------------------
  50. // 向串口輸出一個(gè)字符
  51. //-----------------------------------------------------------------
  52. void PutChar(INT8U c) { SBUF = c; while (TI == 0); TI = 0; }
  53. //------------------------------------------------------------------
  54. // 串口輸出字符串
  55. //------------------------------------------------------------------
  56. void PutStr(char *s) { while (*s) PutChar(*s++); }
  57. //-----------------------------------------------------------------
  58. // 串口配置
  59. //-----------------------------------------------------------------
  60. void Init_USART()
  61. {


  62. }

  63. //-----------------------------------------------------------------
  64. // 主程序
  65. //-----------------------------------------------------------------
  66. void main()
  67. {
  68.         INT32U i,j;
  69.         //SPI,USART初始化
  70.         OpenSPI(); Init_USART(); delay_ms(100);
  71.         //初始化MMC
  72.         PutStr("Initialise MMC, Please Waiting.....");
  73.         ERROR_Flag = MMC_Initialise();
  74.         if (ERROR_Flag) PutStr("OK!\r\r"); else PutStr("ERROR!\r\r");
  75.         //提示進(jìn)行K1-K4操作
  76.         PutStr("Plase Press K1,K2,K3 or K4 to Play MMC Test...\r\r");
  77.         //設(shè)置隨機(jī)種子
  78.         srand(300);
  79.         while(1)
  80.         {        while (P1 == 0xFF); //未按鍵則等待-------------------------
  81.                 if                (K1_DOWN()) { delay_ms(10); if (K1_DOWN()) OP = 1; }
  82.                 else if (K2_DOWN()) { delay_ms(10); if (K2_DOWN()) OP = 2; }
  83.                 else if (K3_DOWN()) { delay_ms(10); if (K3_DOWN()) OP = 3; }
  84.                 else if (K4_DOWN()) { delay_ms(10); if (K4_DOWN()) OP = 4; }
  85.                 //如果上次MMC出錯(cuò)則重新初始化SPI接口與MMC卡
  86.                 if (ERROR_Flag == 0) //------------------------------------
  87.                 {


  88.                 }
  89.                 //根據(jù)按鍵操作代號(hào)分別進(jìn)行操作,因?yàn)樯鲜隹赡艿闹匦鲁跏蓟瘯?huì)耗費(fèi)較多時(shí)間,
  90.                 //如果在這里仍用K1~K4的DOWN判斷,按鍵可能已經(jīng)釋放,從而導(dǎo)致判斷失效.
  91.                 //因此這里使用的是提前獲取的按鍵操作代號(hào)
  92.                 if (OP == 1) //--------------------------------------------
  93.                 {


  94.                 }
  95.                 else if (OP == 2) //---------------------------------------
  96.                 {


  97.                 }
  98.                 else if (OP == 3) //---------------------------------------
  99.                 {


  100.                 }
  101.                 else if (OP == 4) //---------------------------------------
  102.                 {


  103.                 }
  104.                 next: while (P1 != 0xFF);                 //等待釋放按鍵-----------------
  105.         }
  106. }
復(fù)制代碼


所有資料51hei提供下載:
50 MMC存儲(chǔ)卡測(cè)試.zip (33.82 KB, 下載次數(shù): 39)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:104982 發(fā)表于 2019-3-14 09:25 | 顯示全部樓層
代碼不完整,還要找配套的書(shū)才可以
回復(fù)

使用道具 舉報(bào)

ID:625070 發(fā)表于 2020-4-17 16:17 | 顯示全部樓層
請(qǐng)問(wèn)樓主,mmc映像文件怎么生成的呢
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表