OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3268|回复: 2

SD卡实验出现很奇怪现象(另外原子SD卡容量计算貌似有一处错误)

[复制链接]

15

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
294
金钱
294
注册时间
2015-11-30
在线时间
39 小时
发表于 2016-10-25 11:48:11 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 bumbdong 于 2016-10-25 11:50 编辑

先说说我出现的问题:
在主函数中,读取sector 0的数据的时候,原子哥是做了一个读取扇区的子程序
[mw_shl_code=applescript,true]
void SD_Read_Sectorx(u32 sec)
{
        u8 *buf;
        u16 i;
        buf=mymalloc(512);                                //申请内存
        if(SD_ReadDisk(buf,sec,1)==0)        //读取0扇区的内容
        {        
                LCD_ShowString(30,200,200,16,16,"USART1 Sending Data...");
                printf("SECTOR 0 DATA:\r\n");
                for(i=0;i<512;i++)printf("%x ",buf);//打印sec扇区数据               
                printf("\r\nDATA ENDED\r\n");
                LCD_ShowString(30,200,200,16,16,"USART1 Send Data Over!");
        }
        myfree(buf);//释放内存        
}
[/mw_shl_code]
我当时自己写程序就没有用单独作出这个子程序,直接在主函数中写了,while函数如下:
[mw_shl_code=applescript,true]
while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY0_PRESS)
                {
                        buf=mymalloc(512);
                        if(SD_ReadDisk(buf,0,1)==0)
                        {
                                LCD_ShowString(30,200,lcddev.width,16,16,"USART1 sending data...");
                                printf("SD carf sector 0 data:\r\n");
                                for(i=0;i<512;i++)
                                        printf("%x ",buf);
                                printf("\r\n Data end\r\n");
                                LCD_ShowString(30,200,lcddev.width,16,16,"USART1 sended over!   ");
                        }
                        myfree(buf);
                }
                t++;
                delay_ms(20);
                if(t>=20)
                {
                        LED0=!LED0;
                        t=0;
                }
        }
[/mw_shl_code]
运行的时候一直卡住,后来调试发现是卡在数据接收函数的*buf=SPI1_ReadWriteByte(0xFF);一直在这一句不能动了
[mw_shl_code=applescript,true]
u8 SD_ReciveData(u8 *buf,u16 len)
{
        u16 i=0;
        if(SD_GetResponse(0xFE))                //等待SD卡发送起始令牌0xFE
                return 1;
        while(len--)                        //开始接收数据
        {
                *buf=SPI1_ReadWriteByte(0xFF);
                buf++;
                i++;
        }
        //2个伪CRC(dummy CRC)
        SPI1_ReadWriteByte(0xFF);
        SPI1_ReadWriteByte(0xFF);
        return 0;
}[/mw_shl_code]
这个接收函数确定是没有问题的,容量获取初始化全都正常,当主函数改为原子哥的调用子函数的形式来实现这个功能,则一切正常如下就可以正常的:
[mw_shl_code=applescript,true]
while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY0_PRESS)
                {
                        SD_Read_Sectorx(0);
//                        buf=mymalloc(512);
//                        if(SD_ReadDisk(buf,0,1)==0)
//                        {
//                                LCD_ShowString(30,200,lcddev.width,16,16,"USART1 sending data...");
//                                printf("SD carf sector 0 data:\r\n");
//                                for(i=0;i<512;i++)
//                                        printf("%x ",buf);
//                                printf("\r\n Data end\r\n");
//                                LCD_ShowString(30,200,lcddev.width,16,16,"USART1 sended over!   ");
//                        }
                        myfree(buf);
                }
                t++;
                delay_ms(20);
                if(t>=20)
                {
                        LED0=!LED0;
                        t=0;
                }
        }[/mw_shl_code]
百思不得其解,请教这是怎么回事?



另外附上容量计算中,原子程序有问题的地方,原程序为:
[mw_shl_code=applescript,true]
u8 csd[16];
    u32 Capacity;  
    u8 n;
        u16 csize;                                             
        //取CSD信息,如果期间出错,返回0
    if(SD_GetCSD(csd)!=0) return 0;            
    //如果为SDHC卡,按照下面方式计算
    if((csd[0]&0xC0)==0x40)         //V2.00的卡
    {        
                csize = csd[9] + ((u16)csd[8] << 8) + 1;
                Capacity = (u32)csize << 10;//得到扇区数                           
    }else//V1.XX的卡
    {        
                n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
                csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
                Capacity= (u32)csize << (n - 9);//得到扇区数   
    }
    return Capacity;[/mw_shl_code]实际上V2.0的计算为:
sdcsize2.png
原程序没有使用到CSD[7]应该是考虑到目前SD卡的最大容量,所以这几位应为0,忽略掉了,但是后面在Capacity = (u32)csize << 10;//得到扇区数 这句就出现了错误,应该是<<9位及*512,原子程序在主函数中将容量换算成MB时>>11位,这里也是错误的,但是结合前面的,结果却是正确的,这里正确的应该是>>10位,即/1024,在1.xD的计算中也出现一样的问题,以下为我自己写的程序:
[mw_shl_code=applescript,true]
u32 SD_GetSectorCount(void)
{
        u8 csd[16];
        u32 capacity;
        u8 n;
        u32 csize;
        if(SD_GetCSD(csd)!=0)                                //获取CSD信息,接收由高位到低位
                return 0;
        if((csd[0]&0xC0)==0x40)                                //CSD版本判断,最高2位01则为V2.0,容量计算方法:(c_size+1)*512KByte
        {
                csize=csd[9]+((u32)csd[8]<<8)+((u32)(csd[7]&0x3F)<<16)+1;//获取容量大小(bit[69:48])
                capacity=(u32)csize<<9;                //乘上512,得到总容量KByte
        }
        else//CSD最高2位00则为V1.0,
                //BLOCKNR=(C_SIZE+1)*2^(C_SIZE_MULT+2),BLOCK_LEN=2^READ_BL_LEN,容量=BLOCKNR*BLOCK_LEN=(C_SIZE+1)*2^(READ_BL_LEN+C_SIZE_MULT+2)字节
        //read_bl_len[83:80],c_size[73:62],c_size_mult[49:47]
        {
                n=(csd[5]&15)+(csd[10]&0x80>>7)+((csd[9]&3)<<1)+2;//指数READ_BL_LEN+C_SIZE_MULT+2
                csize=(csd[8]>>6)+((u16)csd[7]<<2)+((u16)(csd[6]&3)<<10)+1;//C_SIZE+1
                capacity=(u32)csize<<(n-10);//减10(即/1024)将结果转换为KByte
        }
        return capacity;//返回容量值单位KByte
}
[/mw_shl_code]


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2016-10-27 23:08:07 | 显示全部楼层
你看我们函数的注释,返回值的意义是什么。
回复

使用道具 举报

15

主题

98

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
294
金钱
294
注册时间
2015-11-30
在线时间
39 小时
 楼主| 发表于 2016-10-28 14:01:35 | 显示全部楼层
正点原子 发表于 2016-10-27 23:08
你看我们函数的注释,返回值的意义是什么。

这个倒还没有注意看,不太好理解,不过原子哥我的上面出现的问题是怎么回事呢?

回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 16:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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