找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2236|回复: 6
收起左侧

这个51单片机程序为什么不能写8G的TF卡?

[复制链接]
ID:382699 发表于 2020-10-31 14:44 | 显示全部楼层 |阅读模式
在网上找的SD卡程序和卖家给的程序,测试了一下都不能正常工作,不知道是不是因为卡是8G的原因?

f3652dade4f3831ec0b62919517f1da.jpg
单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5.     //错误码定义//
  6. #define cmd0_error 0x01
  7. #define cmd1_error 0x02
  8. #define write_error 0x03
  9. #define read_error 0x04
  10.     /*位定义*/
  11. sbit cs=P1^0; //定义片选位
  12. sbit clk=P1^1;  //定义时钟位
  13. sbit si=P1^2; //定义主机发送数据位
  14. sbit so=P1^3; //定义主机接收位
  15. uchar xdata shuju[512]={0};     //定义数据缓冲数组
  16. uchar flag_time;         
  17. //定义标志时间,因为当sd卡进行初始化时需要降低
  18. //通信速度,所以通过该标志来写1来降低速度
  19. void delay(uint x)       //通信延时函数
  20. {
  21.     while(x--)
  22.     _nop_();
  23. }
  24. void delay1(uint a)     
  25. {
  26.     uint i,j;
  27.     for(i=0;i<a;i++)
  28.         for(j=0;j<120;j++);
  29. }
  30. //写一字节数据//
  31. void write_sd(uchar date)  
  32. {
  33.     uchar i;
  34.     CY=0;
  35.     clk=1;
  36.     for(i=0;i<8;i++)
  37.     {
  38.         clk=0;
  39.         date=date<<1;
  40.         si=CY;
  41.         if(flag_time==1)  //用来判断是否处于初始化,如果是降低通信速度
  42.         delay(10);
  43.         _nop_();   //用来让io口数据更稳定,也可以省略
  44.         clk=1;
  45.         _nop_();
  46.         if(flag_time==1)
  47.         delay(10);
  48.     }
  49. }
  50. //读取sd卡一个字节数据//
  51. uchar read_sd()      
  52. {
  53.     uchar i,temp=0;
  54.     so=1;          //一定要先将其置1否则会出现错误
  55.     //因为如果先置0单片机io口寄存器相应位电平为低当
  56.     //当接收到高电平后可能sd卡电平不足使其io变为高电平
  57.     clk=1;
  58.     for(i=0;i<8;i++)
  59.     {
  60.         clk=0;
  61.         if(flag_time==1)
  62.         delay(10);
  63.         temp<<=1;
  64.         temp=temp|so;
  65.         _nop_();
  66.         clk=1;
  67.         _nop_();
  68.         if(flag_time==1)
  69.         delay(10);
  70.     }
  71.     return temp;
  72. }
  73. //向sd卡写命令//
  74. uchar write_cmd(uchar *cmd)
  75. {
  76.     uchar i,time,temp;  
  77.     si=1;
  78.     for(i=0;i<6;i++)  //发送六字节命令
  79.     {
  80.         write_sd(cmd[ i]);
  81.     }
  82.     time=0;
  83.     do
  84.     {  
  85.         temp=read_sd();
  86.         time++;
  87.     }
  88.     while((temp==0xff)&&(time<100));
  89.     //判断命令是否写入成功,当读取到so不为0xff时命令写入成功
  90.     //当temp==0xff时为真且没发送100次为真继续执行
  91.     //但是又不能无限制等待所以让命令写入100次结束
  92.     return temp;      //返回读取的数据
  93. }
  94. //复位函数//
  95. uchar sd_reset()
  96. {
  97.     uchar i,temp=0xff,time;
  98.     uchar table[]={0x40,0x00,0x00,0x00,0x00,0x95};
  99.     flag_time=1;
  100.     cs=1;
  101.     for(i=0;i<0x0f;i++)      //复位时最少写入74个时钟周期
  102.     {
  103.         write_sd(0xff);
  104.     }  
  105.     cs=0;
  106.     time=0;//打开片选
  107.     do
  108.     {
  109.         temp=write_cmd(table);   //写入cmd0
  110.         time++;
  111.         if(time==100)
  112.         return(cmd0_error);
  113.     }
  114.     while(temp!=0x01);       //等待命令CMD0的响应
  115.     cs=1;                  //关闭片选
  116.     write_sd(0xff);           //补偿8个时钟
  117.     return 0;
  118. }
  119. //初始化函数此函数决定SD卡的工作模式 选择SPI还是SD模式//
  120. uchar sd_init()
  121. {
  122.     uchar time=0,temp=0xff;
  123.     uchar table[]={0x41,0x00,0x00,0x00,0x00,0xff};       //命令码
  124.     flag_time=1;
  125.     cs=0;
  126.     time=0;
  127.     do
  128.     {
  129.         temp=write_cmd(table);
  130.         time++;
  131.         if(time==100)
  132.         return 0x02;
  133.     }
  134.     while(temp!=0x00);       //等待命令CMD1响应
  135.     flag_time=0;
  136.     cs=1;
  137.     write_sd(0xff);           //补偿8个时钟
  138.     return 0;
  139. }
  140. //写sd卡扇区//
  141. uchar xie_sd_shanqu(unsigned long int add,uchar *buffer)
  142. {
  143.     uchar temp,time;
  144.     uint i;
  145.     uchar table[]={0x58,0x00,0x00,0x00,0x00,0xff};
  146.     add=add<<9;       //add=add*512
  147.     //由于sd卡操作一次性只能写一个扇区也就是512个字节
  148.     //所以这里通过将长整型地址左移九位来将地址乘上512
  149.     //用于地址操作
  150.     table[1]=((add&0xff000000)>>24);
  151.     table[2]=((add&0x00ff0000)>>16);
  152.     table[3]=((add&0x0000ff00)>>8);
  153.     cs=0;
  154.     time=0;
  155.     do
  156.     {
  157.         temp=write_cmd(table);       //写入写扇区命令
  158.         time++;
  159.         if(time==100)
  160.         {
  161.             return(write_error);
  162.         }
  163.     }
  164.     while(temp!=0x00);               //判断命令是否写入成功成功时返回0x00
  165.     for(i=0;i<20;i++)     //补充若干时钟
  166.     {
  167.         write_sd(0xff);
  168.     }
  169.     write_sd(0xfe);       //写入开始字节0xfe,后面要写入512字节数据
  170.     for(i=0;i<512;i++)
  171.     {
  172.         write_sd(buffer[ i]);
  173.     }
  174.     write_sd(0xff);  
  175.     write_sd(0xff);           //两字节奇偶校验

  176.     temp=read_sd();           //读取返回值
  177.     if((temp&0x1f)!=0x05)        //如果返回值是 xxx00101 说明数据已经被写入
  178.     {
  179.         cs=1;
  180.         return(write_error);
  181.     }
  182.     while(read_sd()!=0xff);          //等待sd卡不忙 数据写入成功
  183.     cs=1;                  //关闭片选
  184.     write_sd(0xff);           //补偿8 个时钟
  185.     return 0;
  186. }
  187. //读取sd卡扇区//
  188. uchar duqushanqu(unsigned long add,uchar *buffer)
  189. {
  190.     uchar temp,time=0;
  191.     uint i;
  192.     uchar  table[]={0x51,0x00,0x00,0x00,0x00,0xff};
  193.     add=add<<9;
  194.     table[1]=((add&0xff000000)>>24);
  195.     table[2]=((add&0x00ff0000)>>16);
  196.     table[3]=((add&0x0000ff00)>>8);
  197.     cs=0;                          //打开片选
  198.     do
  199.     {
  200.         temp=write_cmd(table);       //写命令
  201.         time++;
  202.         if(time==100)
  203.         {
  204.             return read_error;
  205.         }
  206.     }
  207.     while(temp!=0);
  208.     write_sd(0xff);               //补偿8个时钟
  209.     while(read_sd()!=0xfe);      //一直读取等待0xfe
  210.     for(i=0;i<512;i++)
  211.     {
  212.         buffer[ i]=read_sd();
  213.     }
  214.     write_sd(0xff);           //两字节奇偶校验位
  215.     write_sd(0xff);
  216.     cs=1;
  217.     write_sd(0xff);           //补偿8个时钟
  218.     return 0;
  219. }
  220. /*在P0上接八个发光二极管用来显示读取到的数据
  221. 首先在数组(shuju)里面放入i用于显示,再将其
  222. 写入SD卡扇区,然后在读取出SD卡里的数据*/
  223. void main()
  224. {
  225.     uint i=0;
  226.         uint a=0xaa;
  227.     P1=0x00;
  228.     P0=0xff;
  229.     sd_reset();  
  230.     sd_init();     ///初始化sd卡
  231.     for(i=0;i<512;i++)
  232.     {
  233.         shuju[ i]=a;           //向数据数组里面写入数据
  234.     }
  235.     for(i=0;i<512;i++)
  236.     {
  237.         xie_sd_shanqu(1,shuju);      //将数据数组里面的数据写入sd卡
  238.     }
  239.     for(i=0;i<512;i++)
  240.     {
  241.         shuju[ i]=0;           //清零数据数组用来存储从sd卡读取到的数据
  242.     }         
  243.     duqushanqu(1,shuju);     //读取扇区数据
  244.     while(1)
  245.     {
  246.         for(i=0;i<512;i++)
  247.         {
  248.             P0=shuju[ i];      //显示扇区数据
  249.             delay1(200);
  250.         }
  251.     }
  252. }


  253.                                                                          /*
  254. * SD模块测试程序
  255. *
  256. * 用途:SD模块测试程序
  257. *
  258. * 作者                                        日期                                备注
  259. * Huafeng Lin                        20010/10/03                        新增
  260. * Huafeng Lin                        20010/10/03                        修改
  261. *
  262. */
  263. #include "REG52.H"
  264. ////////////////////////****************/
  265. unsigned char *SDInfo1="SD Init Success.";
  266. unsigned char *SDInfo2="SD Init Fail.";
  267. unsigned int xdata ReadBuffer[128]  ;
  268. unsigned int xdata WriteBuffer[128] ;
  269. unsigned int BlockSize;
  270. unsigned long int BlockNR;
  271. //sbit sd_clk=P3^2;
  272. //sbit sd_cse=P3^0;
  273. //sbit sd_dai=P3^3; //Do
  274. //sbit sd_dao=P3^1;  //DI
  275. sbit sd_cse=P1^0;
  276. sbit sd_dao=P1^2;//DI
  277. sbit sd_clk=P1^1;
  278. sbit sd_dai=P1^3;//Do
  279. void Delay5us()
  280. {
  281.         unsigned char a=0;
  282.         for(a=0;a<40;a++)
  283.         ;
  284. }
  285. //********************************************
  286. void SD_2Byte_Write(unsigned int IOData)
  287. {
  288.         unsigned char BitCounter;
  289.                
  290.         for (BitCounter=0;BitCounter<16;BitCounter++)
  291.         {
  292.                 sd_clk=0;//CLK Low
  293.                
  294.                 if(IOData&0x8000)//If the MSB of IOData is 1, then Do=1, else Do=0.
  295.                         sd_dao=1;//Do High
  296.                 else
  297.                         sd_dao=0;//Do Low
  298.                                 
  299.                 sd_clk=1;//CLK High
  300.                 Delay5us();
  301.                
  302.                 IOData=IOData<<1;//Because the MSB is transmitted firstly, shift to next lower bit.
  303.         }
  304. }
  305. //********************************************
  306. void SD_Write(unsigned int IOData)
  307. {
  308.         unsigned char BitCounter;
  309.         IOData=IOData<<8;
  310.         
  311.         for (BitCounter=0;BitCounter<8;BitCounter++)
  312.         {
  313.                 sd_clk=0;//CLK Low
  314.                
  315.                 if(IOData&0x8000)//If the MSB of IOData is 1, then Do=1, else Do=0.
  316.                         sd_dao=1;//Do High
  317.                 else
  318.                         sd_dao=0;//Do Low
  319.                                 
  320.                 sd_clk=1;//CLK High
  321.                 Delay5us();
  322.                
  323.                 IOData=IOData<<1;//Because the MSB is transmitted firstly, shift to next lower bit.
  324.         }
  325. }
  326. //********************************************
  327. unsigned int SD_2Byte_Read()
  328. {
  329.         unsigned int Buffer;
  330.         unsigned char BitCounter;
  331.         Buffer=0;
  332.         
  333.         for (BitCounter=0;BitCounter<16;BitCounter++)
  334.         {
  335.                 sd_clk=0;//CLK Low
  336.                 Delay5us();
  337.                 sd_clk=1;//CLK High
  338.                 Buffer=Buffer<<1;//Because the MSB is transmitted firstly, shift to next lower bit.
  339.                                  //Because the LSB will be damaged, we can not put this line under next line.
  340.                 if(sd_dai)
  341.                         Buffer++;//If SPI_Din=1 then the LSB_of_Buffer=1.               
  342.         }
  343.         
  344.         return Buffer;
  345. }
  346. //********************************************
  347. unsigned int SD_Read()
  348. {
  349.         unsigned int Buffer;
  350.         unsigned char BitCounter;
  351.         Buffer=0xffff;
  352.         
  353.         for (BitCounter=0;BitCounter<8;BitCounter++)
  354.         {
  355.                 sd_clk=0;//CLK Low
  356.                 Delay5us();
  357.                 sd_clk=1;//CLK High
  358.                 Buffer=Buffer<<1;//Because the MSB is transmitted firstly, shift to next lower bit.
  359.                                  //Because the LSB will be damaged, we can not put this line under next line.
  360.                 if(sd_dai)
  361.                         Buffer++;//If SPI_Din=1 then the LSB_of_Buffer=1.               
  362.         }
  363.         
  364.         return Buffer;
  365. }
  366. //********************************************
  367. unsigned int SD_CMD_Write(unsigned int CMDIndex,unsigned long CMDArg,unsigned int ResType,unsigned int CSLowRSV)//ResType:Response Type, send 1 for R1; send 2 for R1b; send 3 for R2.
  368. {        //There are 7 steps need to do.(marked by [1]-[7])
  369.         unsigned int temp,Response,Response2,CRC,MaximumTimes;
  370.         Response2=0;
  371.         MaximumTimes=10;
  372.         CRC=0x0095;//0x0095 is only valid for CMD0
  373.         if (CMDIndex!=0) CRC=0x00ff;
  374.         
  375.         sd_cse=0;//[1] CS Low
  376.         
  377.         SD_2Byte_Write(((CMDIndex|0x0040)<<8)+(CMDArg>>24));//[2] Transmit Command_Index & 1st Byte of Command_Argument.
  378.         SD_2Byte_Write((CMDArg&0x00ffff00)>>8);                                //[2] 2nd & 3rd Byte of Command_Argument
  379.         SD_2Byte_Write(((CMDArg&0x000000ff)<<8)+CRC);                //[2] 4th Byte of Command_Argument & CRC only for CMD0
  380.         
  381.         sd_dao=1;//[3] Do High
  382.                                                 //[3] Restore Do to High Level
  383.         
  384.          for (temp=0;temp<8;temp++)//[4] Provide 8 extra clock after CMD
  385.         {
  386.                 sd_clk=0;//CLK Low
  387.                 Delay5us();
  388.                 sd_clk=1;//CLK High
  389.                 Delay5us();
  390.         }
  391.         
  392.         switch (ResType)//[5] wait response
  393.         {
  394.                 case 1://R1
  395.                                 {
  396.                                         do
  397.                                                 Response=SD_Read();
  398.                                         while (Response==0xffff);
  399.                                         break;
  400.                                 }
  401.                 case 2://R1b
  402.                                 {
  403.                                         do
  404.                                                 Response=SD_Read();
  405.                                         while (Response==0xffff);//Read R1 firstly
  406.                                        
  407.                                         do
  408.                                                 Response2=SD_Read()-0xff00;
  409.                                         while (Response2!=0);//Wait until the Busy_Signal_Token is non-zero
  410.                                         break;        
  411.                                 }
  412.                 case 3: Response=SD_2Byte_Read();break;//R2
  413.         }
  414.         
  415.         if (CSLowRSV==0) sd_cse=1;//[6] CS High (if the CMD has data block response CS should be kept low)
  416.          
  417.          for (temp=0;temp<8;temp++)//[7] Provide 8 extra clock after card response
  418.         {
  419.                 sd_clk=0;//CLK Low
  420.                 Delay5us();
  421.                 sd_clk=1;//CLK High
  422.                 Delay5us();
  423.         }
  424.         return Response;
  425. }
  426. //********************************************
  427. unsigned int SD_Reset_Card()
  428. {
  429.         unsigned int temp,MaximumTimes;
  430.         MaximumTimes=10;
  431.         
  432.         for (temp=0;temp<80;temp++)//Send 74+ Clocks
  433.         {
  434.                 sd_clk=0;//CLK Low
  435.                 Delay5us();
  436.                 sd_clk=1;//CLK High
  437.                 Delay5us();
  438.         }
  439.                
  440.         return SD_CMD_Write(0x0000,0x00000000,1,0);//Send CMD0
  441. }
  442. //********************************************
  443. unsigned int SD_Initiate_Card()//Polling the card after reset
  444. {
  445.         unsigned int temp,Response,MaximumTimes;
  446.         MaximumTimes=50;
  447.         
  448.         for(temp=0;temp<MaximumTimes;temp++)
  449.         {
  450.                 Response=SD_CMD_Write(0x0037,0x00000000,1,0);//Send CMD55
  451.                 Response=SD_CMD_Write(0x0029,0x00000000,1,0);//Send ACMD41
  452.                 if (Response==0xff00)
  453.                         temp=MaximumTimes;
  454.         }
  455.         return Response;
  456. }
  457. //********************************************
  458. unsigned int SD_Get_CardInfo()//Read CSD register
  459. {
  460.         unsigned int temp,Response,MaximumTimes;
  461.         MaximumTimes=50;
  462.         
  463.         for(temp=0;temp<MaximumTimes;temp++)
  464.         {
  465.                 Response=SD_CMD_Write(9,0x00000000,1,1);//Send CMD9
  466.                 if (Response==0xff00)
  467.                         temp=MaximumTimes;
  468.         }
  469.         
  470.          for (temp=0;temp<8;temp++)//Provide 8 clock to romove the first byte of data response (0x00fe)
  471.         {
  472.                 sd_clk=0;//CLK Low
  473.                 Delay5us();
  474.                 sd_clk=1;//CLK High
  475.                 Delay5us();
  476.         }
  477.         
  478.         for (temp=0;temp<8;temp++) ReadBuffer[temp]=SD_2Byte_Read();//Get the CSD data
  479.         
  480.         for (temp=0;temp<16;temp++)//Provide 16 clock to remove the last 2 bytes of data response (CRC)
  481.         {
  482.                 sd_clk=0;//CLK Low
  483.                 Delay5us();
  484.                 sd_clk=1;//CLK High
  485.                 Delay5us();
  486.         }
  487.         
  488.         sd_cse=1;//CS_High()
  489.         
  490.         for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response
  491.         {
  492.                 sd_clk=0;//CLK Low
  493.                 Delay5us();
  494.                 sd_clk=1;//CLK High
  495.                 Delay5us();
  496.         }
  497.         
  498.         BlockNR=((ReadBuffer[3]<<2)&0x0fff)+((ReadBuffer[4]>>14)&0x0003)+1;//Calcuate MULT
  499.         BlockNR=BlockNR*(0x0002<<(((ReadBuffer[4]<<1)&0x0007)+((ReadBuffer[5]>>15)&0x0001)+1));//Calcuate Block_Number
  500.         return Response;
  501. }
  502. //********************************************
  503. unsigned int SD_Overall_Initiation()
  504. {
  505.         unsigned int Response,Response_2;
  506.         Response=0x0000;
  507.         Response_2=0xff00;
  508.         
  509.         sd_dao=1;//[1] Do High
  510.                                                 //[1] Do must be High when there is no transmition
  511.         do
  512.                 Response=SD_Reset_Card();//[2] Send CMD0
  513.         while (Response!=0xff01);
  514.         
  515.         if (Response!=0xff01) Response_2+=8;
  516.         
  517.         //Response=SD_CMD_Write(8,0x00000000,1,0);//Send CMD8
  518.         
  519.         Response=SD_Initiate_Card();//[3] Send CMD55+ACMD41
  520.         if (Response==0xff00)
  521.                 ;
  522.         else
  523.                 {
  524.                 Response_2+=4;
  525.                 ;
  526.                 }
  527.         
  528.         do
  529.                 Response=SD_Get_CardInfo();//[4] Read CSD
  530.         while (Response!=0xff00);
  531.         if (Response==0xff01) Response_2+=2;
  532.         
  533.         return Response_2;
  534. //        0000|0000||0000|0000 Response_2
  535. //                  |||_CSD Fail
  536. //                  ||__CMD55+ACMD41 Fail
  537. //                  |___CMD0 Fail
  538. }
  539. //********************************************
  540. unsigned int SD_Get_CardID()//Read CID register
  541. {
  542.         unsigned int temp,Response,MaximumTimes;
  543.         MaximumTimes=10;
  544.         
  545.         for(temp=0;temp<MaximumTimes;temp++)
  546.         {
  547.                 Response=SD_CMD_Write(10,0x00000000,1,1);//Send CMD9
  548.                 if (Response==0xff00)
  549.                         temp=MaximumTimes;
  550.         }
  551.         
  552.          for (temp=0;temp<8;temp++)//Provide 8 clock to romove the first byte of data response (0x00fe)
  553.         {
  554.                 sd_clk=0;//CLK Low
  555.                 Delay5us();
  556.                 sd_clk=1;//CLK High
  557.                 Delay5us();
  558.         }
  559.         
  560.         for (temp=0;temp<8;temp++) ReadBuffer[temp]=SD_2Byte_Read();//Get the CID data
  561.         
  562.         for (temp=0;temp<16;temp++)//Provide 16 clock to remove the last 2 bytes of data response (CRC)
  563.         {
  564.                 sd_clk=0;//CLK Low
  565.                 Delay5us();
  566.                 sd_clk=1;//CLK High
  567.                 Delay5us();
  568.         }
  569.         
  570.         sd_cse=1;//CS_High()
  571.         
  572.         for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response
  573.         {
  574.                 sd_clk=0;//CLK Low
  575.                 Delay5us();
  576.                 sd_clk=1;//CLK High
  577.                 Delay5us();
  578.         }
  579.         
  580.         return Response;
  581. }
  582. //********************************************
  583. unsigned int Read_Single_Block(unsigned long int BlockAddress)
  584. {
  585.         unsigned int temp,Response,MaximumTimes;
  586.         MaximumTimes=10;
  587.         
  588.         if (BlockAddress>BlockNR) return 0xff20;//whether BlockAddress out of range?
  589.         
  590.         for(temp=0;temp<MaximumTimes;temp++)
  591.         {
  592.                 Response=SD_CMD_Write(17,BlockAddress,1,1);//Send CMD17
  593.                 if (Response==0xff00)
  594.                         temp=MaximumTimes;
  595.         }
  596.         
  597.         while (SD_Read()!=0xfffe) {;}
  598.         //这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte
  599.         //如果您使用的单片机拥有1K以上的RAM请将"%128"去掉        
  600.         for (temp=0;temp<256;temp++) ReadBuffer[temp%128]=SD_2Byte_Read();//Get the readed data
  601.         
  602.         for (temp=0;temp<16;temp++)//Provide 16 clock to remove the last 2 bytes of data response (CRC)
  603.         {
  604.                 sd_clk=0;//CLK Low
  605.                 Delay5us();
  606.                 sd_clk=1;//CLK High
  607.                 Delay5us();
  608.         }
  609.         
  610.         sd_cse=1;//CS_High()
  611.         
  612.         for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response
  613.         {
  614.                 sd_clk=0;//CLK Low
  615.                 Delay5us();
  616.                 sd_clk=1;//CLK High
  617.                 Delay5us();
  618.         }
  619.         
  620.         return Response;
  621. }
  622. //********************************************
  623. unsigned int Write_Single_Block(unsigned long int BlockAddress)
  624. {
  625.         unsigned int temp,Response,MaximumTimes;
  626.         MaximumTimes=10;
  627.         
  628.         if (BlockAddress>BlockNR) return 0xff20;//whether BlockAddress out of range?
  629.         
  630.         for(temp=0;temp<MaximumTimes;temp++)
  631.         {
  632.                 Response=SD_CMD_Write(24,BlockAddress,1,1);//Send CMD24
  633.                 if (Response==0xff00)
  634.                         temp=MaximumTimes;
  635.         }
  636.         
  637.         for (temp=0;temp<8;temp++)//Provide 8 extra clock after CMD response
  638.         {
  639.                 sd_clk=0;//CLK Low
  640.                 Delay5us();
  641.                 sd_clk=1;//CLK High
  642.                 Delay5us();
  643.         }
  644.         
  645.         SD_Write(0x00fe);//Send Start Block Token
  646.         //这里为了使只有512byte的单片机能够读写SD卡,特意节省了RAM的使用量,每次读写只有两个重复的128byte
  647.         //如果您使用的单片机拥有1K以上的RAM请将"%128"去掉
  648.         for (temp=0;temp<256;temp++) SD_2Byte_Write(WriteBuffer[temp%128]);//Data Block
  649.         SD_2Byte_Write(0xffff);//Send 2 Bytes CRC
  650.         
  651.         Response=SD_Read();
  652.         while (SD_Read()!=0xffff) {;}
  653.         
  654.         sd_cse=1;//CS_High()
  655.         
  656.         for (temp=0;temp<8;temp++)//Provide 8 extra clock after data response
  657.         {
  658.                 sd_clk=0;//CLK Low
  659.                 Delay5us();
  660.                 sd_clk=1;//CLK High
  661.                 Delay5us();
  662.         }
  663.         
  664.         return Response;
  665. }
  666. /* 串行通信初始化*/
  667. void UartInit()
  668. {
  669.         SCON = 0x50;                    // uart 模式1 (8 bit), REN=1;
  670.         TMOD = TMOD | 0x20 ;        // 定时器1 模式2;
  671. //        TH1  = 0xF7;                // 9600 Bds at 32MHz
  672. //        TL1  = 0xF7;        

  673.         TH1  = 0xFD;                // 9600 Bds at 11.059MHz
  674.          TL1  = 0xFD;        
  675. //        TH1  = 0xFA;                // 9600 Bds at 22.1184MHz
  676. //        TL1  = 0xFA;        
  677.         ES = 1;                     //允许uart中断;
  678.         EA = 1;                            //允许CPU中断;
  679.         TR1 = 1;                    //运行定时器1:
  680. }
  681.         
  682. void send_char_com(unsigned char ch)  
  683. {
  684.     SBUF=ch;
  685.     while(TI==0);
  686.     TI=0;
  687. }
  688. //向串口发送一个字符串
  689. void send_string_com(unsigned char *str,unsigned int len)
  690. {
  691.     unsigned char k=0;
  692.     do
  693.     {
  694.         send_char_com(*(str + k));
  695.         k++;
  696.     } while(k <len);
  697. }
  698. main()
  699. {
  700.         unsigned int Data,M_Response;
  701.     unsigned char i;
  702.         //初始化要写入的数据
  703.     for(i=0;i<128;i++)
  704.         {
  705.       if (i < 64)
  706.           {
  707.             WriteBuffer[ i]=0x4141;
  708.           }
  709.           else
  710.           {
  711.                   WriteBuffer[ i]=0x4242;
  712.           }
  713.         }
  714.     UartInit();
  715.          TI = 0;        
  716.     M_Response=0x0000;
  717.          M_Response=SD_Overall_Initiation();
  718.         M_Response=SD_CMD_Write(16,512,1,0);
  719.           Data=SD_Get_CardID();
  720.          Write_Single_Block(0x0000);
  721.     Read_Single_Block(0x0000);
  722.     for(i=0; i<128; i++)
  723.         {         
  724.      send_char_com(ReadBuffer[ i]>>8)  ; //向串口发送高8位数据
  725.      send_char_com(ReadBuffer[ i] )  ;
  726.         }
  727.          
  728.         while(1);         
  729. }
复制代码
回复

使用道具 举报

ID:983266 发表于 2021-11-22 00:25 | 显示全部楼层
你好,后来你这个程序成功了吗?
回复

使用道具 举报

ID:96682 发表于 2021-11-22 15:04 来自手机 | 显示全部楼层
记得 10 年前的大部分手机还用不了 8G TF 卡,
回复

使用道具 举报

ID:96682 发表于 2021-11-22 15:08 来自手机 | 显示全部楼层
表现为读不出卡的大小,读不出全部内容
回复

使用道具 举报

ID:983444 发表于 2021-11-22 15:21 | 显示全部楼层
是不是寻址空间的原因?地址位数不够,或者处理不恰当
回复

使用道具 举报

ID:57657 发表于 2021-11-22 17:37 | 显示全部楼层
long为32位变量,32位最大4G,请拆分成两个long。
回复

使用道具 举报

ID:46065 发表于 2022-4-6 21:42 | 显示全部楼层
FAT32最大支持4G
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表