久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4447|回復: 1
收起左側

stm32 sd卡bootloader升級程序

[復制鏈接]
ID:473593 發表于 2019-3-13 11:01 | 顯示全部樓層 |閱讀模式
單片機源程序如下:
  1. #include "public.h"       

  2. //大篇幅修改V1.0代碼.參考fatfs代碼移植過來.
  3. //////////////////////////////////////////////////////////////////////////////////
  4. u8  SD_Type=0;//SD卡的類型



  5. ////////////////////////////////////移植修改區///////////////////////////////////
  6. //移植時候的接口
  7. //data:要寫入的數據
  8. //返回值:讀到的數據
  9. u8 SD_SPI_ReadWriteByte(u8 data)
  10. {
  11.         return SPIx_ReadWriteByte(data);
  12. }
  13. //SD卡初始化的時候,需要低速
  14. void SD_SPI_SpeedLow(void)
  15. {
  16.         SPIx_SetSpeed(SPI_SPEED_256);//設置到低速模式       
  17. }
  18. //SD卡正常工作的時候,可以高速了
  19. void SD_SPI_SpeedHigh(void)
  20. {
  21.         SPIx_SetSpeed(SPI_SPEED_4);//設置到高速模式       
  22. }
  23. //SPI硬件層初始化
  24. void SD_SPI_Init(void)
  25. {
  26.      //設置硬件上與SD卡相關聯的控制引腳輸出
  27.         //避免NRF24L01/W25X16等的影響
  28.         RCC->APB2ENR|=1<<2;       //PORTA時鐘使能
  29.         GPIOA->CRL&=0XFFF000FF;
  30.         GPIOA->CRL|=0X00033300;//PA2.3.4 推挽             
  31.         GPIOA->ODR|=0X7<<2;    //PA2.3.4上拉
  32.         SPIx_Init();
  33.         SD_SPI_SpeedLow();//設置到低速模式         
  34.         SD_CS=1;
  35. }
  36. ///////////////////////////////////////////////////////////////////////////////////
  37. //取消選擇,釋放SPI總線
  38. void SD_DisSelect(void)
  39. {
  40.         SD_CS=1;
  41.         SD_SPI_ReadWriteByte(0xff);//提供額外的8個時鐘
  42. }
  43. //選擇sd卡,并且等待卡準備OK
  44. //返回值:0,成功;1,失敗;
  45. u8 SD_Select(void)
  46. {
  47.         SD_CS=0;
  48.         if(SD_WaitReady()==0)return 0;//等待成功
  49.         SD_DisSelect();
  50.         return 1;//等待失敗
  51. }
  52. //等待卡準備好
  53. //返回值:0,準備好了;其他,錯誤代碼
  54. u8 SD_WaitReady(void)
  55. {
  56.         u32 t=0;
  57.         do
  58.         {
  59.                 if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
  60.                 t++;                         
  61.         }while(t<0XFFFFFF);//等待
  62.         return 1;
  63. }
  64. //等待SD卡回應
  65. //Response:要得到的回應值
  66. //返回值:0,成功得到了該回應值
  67. //    其他,得到回應值失敗
  68. u8 SD_GetResponse(u8 Response)
  69. {
  70.         u16 Count=0xFFF;//等待次數                                                             
  71.         while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到準確的回應            
  72.         if (Count==0)return MSD_RESPONSE_FAILURE;//得到回應失敗   
  73.         else return MSD_RESPONSE_NO_ERROR;//正確回應
  74. }
  75. //從sd卡讀取一個數據包的內容
  76. //buf:數據緩存區
  77. //len:要讀取的數據長度.
  78. //返回值:0,成功;其他,失敗;       
  79. u8 SD_RecvData(u8*buf,u16 len)
  80. {                                    
  81.         if(SD_GetResponse(0xFE))return 1;//等待SD卡發回數據起始令牌0xFE
  82.     while(len--)//開始接收數據
  83.     {
  84.         *buf=SD_SPI_ReadWriteByte(0xFF);
  85.         buf++;
  86.     }
  87.     //下面是2個偽CRC(dummy CRC)
  88.     SD_SPI_ReadWriteByte(0xFF);
  89.     SD_SPI_ReadWriteByte(0xFF);                                                                                                                      
  90.     return 0;//讀取成功
  91. }
  92. //向sd卡寫入一個數據包的內容 512字節
  93. //buf:數據緩存區
  94. //cmd:指令
  95. //返回值:0,成功;其他,失敗;       
  96. u8 SD_SendBlock(u8*buf,u8 cmd)
  97. {       
  98.         u16 t;                            
  99.         if(SD_WaitReady())return 1;//等待準備失效
  100.         SD_SPI_ReadWriteByte(cmd);
  101.         if(cmd!=0XFD)//不是結束指令
  102.         {
  103.                 for(t=0;t<512;t++)SD_SPI_ReadWriteByte(buf[t]);//提高速度,減少函數傳參時間
  104.             SD_SPI_ReadWriteByte(0xFF);//忽略crc
  105.             SD_SPI_ReadWriteByte(0xFF);
  106.                 t=SD_SPI_ReadWriteByte(0xFF);//接收響應
  107.                 if((t&0x1F)!=0x05)return 2;//響應錯誤                                                                                                                      
  108.         }                                                                                                                                                                       
  109.     return 0;//寫入成功
  110. }

  111. //向SD卡發送一個命令
  112. //輸入: u8 cmd   命令
  113. //      u32 arg  命令參數
  114. //      u8 crc   crc校驗值          
  115. //返回值:SD卡返回的響應                                                                                                                          
  116. u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
  117. {
  118.     u8 r1;       
  119.         u8 Retry=0;
  120.         SD_DisSelect();//取消上次片選
  121.         if(SD_Select())return 0XFF;//片選失效
  122.         //發送
  123.     SD_SPI_ReadWriteByte(cmd | 0x40);//分別寫入命令
  124.     SD_SPI_ReadWriteByte(arg >> 24);
  125.     SD_SPI_ReadWriteByte(arg >> 16);
  126.     SD_SPI_ReadWriteByte(arg >> 8);
  127.     SD_SPI_ReadWriteByte(arg);          
  128.     SD_SPI_ReadWriteByte(crc);
  129.         if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
  130.     //等待響應,或超時退出
  131.         Retry=0X1F;
  132.         do
  133.         {
  134.                 r1=SD_SPI_ReadWriteByte(0xFF);
  135.         }while((r1&0X80) && Retry--);         
  136.         //返回狀態值
  137.     return r1;
  138. }                                                                                                                                                                              
  139. //獲取SD卡的CID信息,包括制造商信息
  140. //輸入: u8 *cid_data(存放CID的內存,至少16Byte)          
  141. //返回值:0:NO_ERR
  142. //                 1:錯誤                                                                                                                  
  143. u8 SD_GetCID(u8 *cid_data)
  144. {
  145.     u8 r1;          
  146.     //發CMD10命令,讀CID
  147.     r1=SD_SendCmd(CMD10,0,0x01);
  148.     if(r1==0x00)
  149.         {
  150.                 r1=SD_RecvData(cid_data,16);//接收16個字節的數據         
  151.     }
  152.         SD_DisSelect();//取消片選
  153.         if(r1)return 1;
  154.         else return 0;
  155. }                                                                                                                                                                  
  156. //獲取SD卡的CSD信息,包括容量和速度信息
  157. //輸入:u8 *cid_data(存放CID的內存,至少16Byte)            
  158. //返回值:0:NO_ERR
  159. //                 1:錯誤                                                                                                                  
  160. u8 SD_GetCSD(u8 *csd_data)
  161. {
  162.     u8 r1;         
  163.     r1=SD_SendCmd(CMD9,0,0x01);//發CMD9命令,讀CSD
  164.     if(r1==0)
  165.         {
  166.             r1=SD_RecvData(csd_data, 16);//接收16個字節的數據
  167.     }
  168.         SD_DisSelect();//取消片選
  169.         if(r1)return 1;
  170.         else return 0;
  171. }  
  172. //獲取SD卡的總扇區數(扇區數)   
  173. //返回值:0: 取容量出錯
  174. //       其他:SD卡的容量(扇區數/512字節)
  175. //每扇區的字節數必為512,因為如果不是512,則初始化不能通過.                                                                                                                  
  176. u32 SD_GetSectorCount(void)
  177. {
  178.     u8 csd[16];
  179.     u32 Capacity;  
  180.     u8 n;
  181.         u16 csize;                                              
  182.         //取CSD信息,如果期間出錯,返回0
  183.     if(SD_GetCSD(csd)!=0) return 0;            
  184.     //如果為SDHC卡,按照下面方式計算
  185.     if((csd[0]&0xC0)==0x40)         //V2.00的卡
  186.     {       
  187.                 csize = csd[9] + ((u16)csd[8] << 8) + 1;
  188.                 Capacity = (u32)csize << 10;//得到扇區數                           
  189.     }else//V1.XX的卡
  190.     {       
  191.                 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
  192.                 csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
  193.                 Capacity= (u32)csize << (n - 9);//得到扇區數   
  194.     }
  195.     return Capacity;
  196. }
  197. //初始化SD卡
  198. //返回值:0,正常.
  199. //                 其他,不正常.
  200. u8 SD_Initialize(void)
  201. {
  202.     u8 r1;      // 存放SD卡的返回值
  203.     u16 retry;  // 用來進行超時計數
  204.     u8 buf[4];  
  205.         u16 i;

  206.         SD_SPI_Init();                //初始化IO
  207.         SD_SPI_SpeedLow();        //設置到低速模式
  208.     //for(i=0;i<0xf00;i++);//純延時,等待SD卡上電完成          
  209.         for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//發送最少74個脈沖
  210.         retry=20;
  211.         do
  212.         {
  213.                 r1=SD_SendCmd(CMD0,0,0x95);//進入IDLE狀態
  214.         }while((r1!=0X01) && retry--);
  215.         SD_Type=0;//默認無卡
  216.         if(r1==0X01)
  217.         {
  218.                 if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
  219.                 {
  220.                         for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);        //Get trailing return value of R7 resp
  221.                         if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V
  222.                         {
  223.                                 retry=0XFFFE;
  224.                                 do
  225.                                 {
  226.                                         SD_SendCmd(CMD55,0,0X01);        //發送CMD55
  227.                                         r1=SD_SendCmd(CMD41,0x40000000,0X01);//發送CMD41
  228.                                 }while(r1&&retry--);
  229.                                 if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//鑒別SD2.0卡版本開始
  230.                                 {
  231.                                         for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到OCR值
  232.                                         if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //檢查CCS
  233.                                         else SD_Type=SD_TYPE_V2;   
  234.                                 }
  235.                         }
  236.                 }else//SD V1.x/ MMC        V3
  237.                 {
  238.                         SD_SendCmd(CMD55,0,0X01);                //發送CMD55
  239.                         r1=SD_SendCmd(CMD41,0,0X01);        //發送CMD41
  240.                         if(r1<=1)
  241.                         {               
  242.                                 SD_Type=SD_TYPE_V1;
  243.                                 retry=0XFFFE;
  244.                                 do //等待退出IDLE模式
  245.                                 {
  246.                                         SD_SendCmd(CMD55,0,0X01);        //發送CMD55
  247.                                         r1=SD_SendCmd(CMD41,0,0X01);//發送CMD41
  248.                                 }while(r1&&retry--);
  249.                         }else
  250.                         {
  251.                                 SD_Type=SD_TYPE_MMC;//MMC V3
  252.                                 retry=0XFFFE;
  253.                                 do //等待退出IDLE模式
  254.                                 {                                                                                            
  255.                                         r1=SD_SendCmd(CMD1,0,0X01);//發送CMD1
  256.                                 }while(r1&&retry--);  
  257.                         }
  258.                         if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//錯誤的卡
  259.                 }
  260.         }
  261.         SD_DisSelect();//取消片選
  262.         SD_SPI_SpeedHigh();//高速
  263.         if(SD_Type)return 0;
  264.         else if(r1)return r1;           
  265.         return 0xaa;//其他錯誤
  266. }
  267. //讀SD卡
  268. //buf:數據緩存區
  269. //sector:扇區
  270. //cnt:扇區數
  271. //返回值:0,ok;其他,失敗.
  272. u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
  273. {
  274.         u8 r1;
  275.         if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//轉換為字節地址
  276.         if(cnt==1)
  277.         {
  278.                 r1=SD_SendCmd(CMD17,sector,0X01);//讀命令
  279.                 if(r1==0)//指令發送成功
  280.                 {
  281.                         r1=SD_RecvData(buf,512);//接收512個字節          
  282.                 }
  283.         }else
  284.         {
  285.                 r1=SD_SendCmd(CMD18,sector,0X01);//連續讀命令
  286.                 do
  287.                 {
  288.                         r1=SD_RecvData(buf,512);//接收512個字節         
  289.                         buf+=512;  
  290.                 }while(--cnt && r1==0);        
  291.                 SD_SendCmd(CMD12,0,0X01);        //發送停止命令
  292.         }   
  293.         SD_DisSelect();//取消片選
  294.         return r1;//
  295. }
  296. //寫SD卡
  297. //buf:數據緩存區
  298. //sector:起始扇區
  299. //cnt:扇區數
  300. //返回值:0,ok;其他,失敗.
  301. u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
  302. {
  303.         u8 r1;
  304.         if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//轉換為字節地址
  305.         if(cnt==1)
  306.         {
  307.                 r1=SD_SendCmd(CMD24,sector,0X01);//讀命令
  308.                 if(r1==0)//指令發送成功
  309.                 {
  310.                         r1=SD_SendBlock(buf,0xFE);//寫512個字節          
  311.                 }
  312.         }else
  313.         {
  314.                 if(SD_Type!=SD_TYPE_MMC)
  315.                 {
  316.                         SD_SendCmd(CMD55,0,0X01);       
  317.                         SD_SendCmd(CMD23,cnt,0X01);//發送指令       
  318.                 }
  319.                 r1=SD_SendCmd(CMD25,sector,0X01);//連續讀命令
  320.                 if(r1==0)
  321.                 {
  322.                         do
  323.                         {
  324.                                 r1=SD_SendBlock(buf,0xFC);//接收512個字節         
  325.                                 buf+=512;  
  326.                         }while(--cnt && r1==0);
  327.                         r1=SD_SendBlock(0,0xFD);//接收512個字節
  328.                 }
  329.         }   
  330.         SD_DisSelect();//取消片選
  331.         return r1;//
  332. }
復制代碼

所有資料51hei提供下載:
bootloader.7z (325.73 KB, 下載次數: 76)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:130559 發表于 2019-4-9 16:17 | 顯示全部樓層
找不到lib.h
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产69精品久久99不卡免费版 | 精品日韩一区二区三区av动图 | 国产一区二区在线看 | 精品中文字幕在线 | 我想看一级黄色毛片 | 亚洲一区二区久久 | 久久久国产一区 | 亚洲国产成人精品女人久久久 | 韩国久久 | 亚洲精品免费在线 | 涩涩99| 成人毛片在线观看 | 欧美日韩一区不卡 | 成人在线中文字幕 | 精精国产xxxx视频在线 | 男人天堂网址 | 国产精品国产三级国产aⅴ浪潮 | 久久精品亚洲精品 | 亚洲欧洲一区二区 | 毛片av免费在线观看 | 超碰97在线免费 | 欧美激情综合五月色丁香小说 | 国产成人免费视频网站高清观看视频 | 麻豆av片 | 综合久久99 | 中文字幕在线观看一区 | 中文字幕久久久 | 欧美精品video | 中文字幕在线观看一区 | 日屁视频 | 国产乡下妇女做爰 | 在线中文字幕av | 亚洲国产成人精品女人久久久野战 | 国产精品乱码一区二三区小蝌蚪 | 亚洲一区二区三区免费观看 | 日韩精品 电影一区 亚洲 | 精品久久久久久国产 | 欧美二区在线 | 国产一级精品毛片 | 国产福利在线视频 | 91免费电影 |