搜索
bottom↓
回复: 11

SD卡 读取数据与 winhex软件数据不一致

[复制链接]

出0入0汤圆

发表于 2010-6-17 23:50:30 | 显示全部楼层 |阅读模式
老师你好 :
       我重新发帖了 第一次发帖对论坛的管理不是很清楚
       多谢几位网友的回复。。。。
       最近一直在整SD卡 已经好几天了 也不知道问题出在哪里我使用的是AVRmega128单片机 SD卡 使用的是SanDisk 1G 的MicroSD卡  复位和初始化 都已经成功 在读数据0扇区的时候 读出来的数据与 WINHEX软件里看到的数据不一样 我检查了很多遍程序 也找不到原因 请求老师抽空帮忙看一下 !

我的SD卡与AVR128 接口原理用电阻分压得到3.3V  (原文件名:ourdev_562197.png)
我把程序也贴出来了
/////////////主函数
#include <iom128v.h>
#include <macros.h>
#include "spi.h"

#include"SD_.h"
#include "uart1.c"
unsigned char temp;
uchar rx_data;
unsigned char FAT32_Buffer[512];

void delay(uint ms)
{  
        uint i,j;
for(i=0;i<ms;i++)
   {
   for(j=0;j<1141;j++);
       }
}

void main(void)
{


uchar Reset_retry;
uint i;
delay(200);
delay(200);delay(200);delay(200);
DDRA=0XFF;
PORTA=0XFF;
uart_init();
SPI_masterINIT(128); //128分频
for(Reset_retry=0;Reset_retry<5;Reset_retry++)//多复位 增加兼容性
{
SD_Reset();//sd卡复位  
  
}
SPI_masterINIT(2); //2分频

SD_Read_Sector(0,FAT32_Buffer);

for(i=0;i<512;i++)
{
  uart_tx(FAT32_Buffer);

}
while(1);
}

/////////////SD卡程序
void uart_init(void)
{
UBRR1L=0x67;   //osc=16M ,U2X=0,bit/s=9600
UBRR1H=0x00;
UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);    //RX Enable,TX Enable,RX interrupt Enable
UCSR1C=(1<<UCSZ01)|(1<<UCSZ00);              //8bit data ,1bit stop
}

void uart_tx(uchar txc)      //send a uchar data
{
while(!(UCSR1A&(1<<UDRE1)));   //check send enable
UDR1=txc;               
}
unsigned char Write_Com(unsigned char com,unsigned long addr)  //写命令
{
unsigned char count,r1;
count=0;
//addr<<=9;
SD_CS_H;            //////片选定义 PORTB.0
SPI_R_W_BYTE(0xff);
    SD_CS_L ;
SPI_R_W_BYTE(com|0x40);
SPI_R_W_BYTE(addr>>24);
SPI_R_W_BYTE(addr>>16);
SPI_R_W_BYTE(addr>>8);
SPI_R_W_BYTE(addr&0xff);
if(com==0)
SPI_R_W_BYTE(0x95);
else
SPI_R_W_BYTE(0xff);
while((r1=SPI_R_W_BYTE(0xff))==0xff)
{
if((count++)==200)
   
break;

}  
SD_CS_H;
SPI_R_W_BYTE(0xff);
return r1;   
}

//sd卡的复位
void SD_Reset(void)
{  
    unsigned char i,r1;
unsigned int retry=0;
uart_tx(0x55);
uart_tx(0x55);
uart_tx(0x55);
uart_tx(0x55);
    do
{
for(i=0;i<20;i++)
{
SPI_R_W_BYTE(0xff);
}
r1=Write_Com(0,0);     //写CMD0

if(r1==0x01)
{
  PORTA&=~BIT(0);
}

}
while((r1!=0x01)&&((retry++)<1000));
retry=0;


    do
{
r1=Write_Com(1,0);    //写CMD1

}
while((r1!=0x00)&&((retry++)<300));
r1=Write_Com(59,0);
r1=Write_Com(16,512);
}

//读一个扇区
void SD_Read_Sector(unsigned long SD_addr,unsigned char *buffer)
{
unsigned char i,r1;
unsigned int x;
i=0;

do
{
r1=Write_Com(17,SD_addr<<9);
  

i++;
}
while((r1!=0x00)&&(i<200));
SD_CS_L ;
while(SPI_R_W_BYTE(0xff)!=0xfe);

PORTA&=~BIT(1);
for(x=0;x<512;x++)
{
buffer[x]=SPI_R_W_BYTE(0XFF);

}
i=SPI_R_W_BYTE(0xff);
i=SPI_R_W_BYTE(0xff);
  SD_CS_H ;
SPI_R_W_BYTE(0xff);
}

SPI部分

void SPI_masterINIT(unsigned char x)
{
    PORTB=(1<<3)|(1<<0)|(1<<4)|(1<<5)|(1<<6);  //miso开启上拉  ss输出高电平
DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<4)|(1<<5)|(1<<6);//设置mosi  sck   ss输出

    switch(x)
    {
         case 128:                       //avr技术文档说明其分频数  
            SPSR&=~(1<<0);SPCR=0x53;break;          //128分频率   
         case 2:
            SPSR|=(1<<0);SPCR=0x50;break;          //2分频率  
     }

}
unsigned char SPI_R_W_BYTE(unsigned char spi_data)
{
SPDR=spi_data;
while(!(SPSR&(1<<7)));
return SPDR;
}
程序运行好 如果 SD 卡复位成功 连接在PORTA.0的LED发光 如果初始化成功 PORTA.1的LED发光  
读取数据后 通过串口发回 512个字节 到计算机   
可是我每次看的数据都一样 但是就跟 WINHEX软件里看到的数据不一致。。。。。。
我读回来的数据
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
C0 00 1F FF 3F 00 00 00 01 00 60 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00 00 00 00 00 02 C7 FF FF <<<<<------这里明显不对  应该是 55 AA  其他的地方也有错误

能想到的 我都想到了 我也看了很多程序了 大同小异  硬件我的 写保护和 卡检测没有接 我想应该没有问题吧   
在线等吧 懂得大侠们 也给出出招吧!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-6-17 23:53:59 | 显示全部楼层
自己顶个 多谢阿莫老师+老板的 建议及回复 感动ING!

出0入0汤圆

发表于 2010-6-18 06:44:39 | 显示全部楼层
降低spi速度看看 推荐阅读Pic24和Pic32的2本书  本论坛有 我手机上网不好传 需要的话我上传

出0入0汤圆

发表于 2010-6-18 07:27:15 | 显示全部楼层
频率太高的话,我只能收到FF.....

读扇区写错了~~~~~~

SD_CS_L ; <--------------------实际应该在的位置
do  
{  
r1=Write_Com(17,SD_addr<<9);  
   

i++;  
}  
while((r1!=0x00)&&(i<200));  
//SD_CS_L ; <--------------------原来位置

出0入0汤圆

 楼主| 发表于 2010-6-18 08:14:59 | 显示全部楼层
回复【3楼】90999 QzeroQQQ
-----------------------------------------------------------------------

这个频率 我从 最快的 2分频 到128分频试过 读出来的数据时一样的 所以我感觉 SPI速度没有关系  2分频的时候容易错

还有这个片选  应该也没有问题 r1=Write_Com(17,SD_addr<<9);  这个函数里有片选拉低  不过运行完又给拉高了 所以在后面的while后面又加了 一个拉得片选 这个问题我在论坛别人的帖子里说过

出0入0汤圆

 楼主| 发表于 2010-6-18 08:16:53 | 显示全部楼层
回复【2楼】vipcff
-----------------------------------------------------------------------

感谢回复 但是我感觉跟SPI速度 关系不大  我软件SPI模拟过 读出来的数据跟这个一样 软件已经很慢了  硬件128分频读出来的也一样  2分频也一样 个别的时候有错的

出110入26汤圆

发表于 2010-6-18 10:29:28 | 显示全部楼层
楼主把读扇区那部分写一个独立的子程序--包括:写命令那部分,注意片选要贯穿整个读取操作。
读取对时序要求很高。


(参考)

另外确保你的TF卡已经在电脑格式化…

出0入0汤圆

 楼主| 发表于 2010-6-18 11:07:44 | 显示全部楼层
回复【6楼】kinoko
-----------------------------------------------------------------------

恩谢谢你 我试试吧 其实我那个程序是我一个朋友的我直接拿来用的 不过他的好事我的就不好使呢  可能是硬件原因 还有一个事SD卡的问题 我在仔细研究一下 THANKS!

出0入0汤圆

 楼主| 发表于 2010-6-19 08:08:26 | 显示全部楼层
顶上去 别沉了啊 好不容易发个帖子  问题还没解决 谁在帮帮忙啊 !

出0入0汤圆

发表于 2010-6-19 10:15:33 | 显示全部楼层
回复【4楼】liyanlong55  紫川秀_MISS
-----------------------------------------------------------------------

错,片选是整体的,不是发命令时候或收命令时候独立出来的~~~~~~

出0入0汤圆

 楼主| 发表于 2010-6-19 11:00:01 | 显示全部楼层
回复【9楼】90999 QzeroQQQ
-----------------------------------------------------------------------

恩我明白你的意思 就是这个函数 从进入 到最后 才能 片选拉高  是这个意思吧 哎郁闷死了 现在连 0Xfe都读不出来了

出0入0汤圆

发表于 2013-10-23 10:02:10 | 显示全部楼层
挖坟。。。楼主解决了没有?我也遇到了同样的问题啊。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 00:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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