智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 1570|回复: 0
打印 上一主题 下一主题

SD卡求助,求大神们帮助

[复制链接]

2

主题

3

帖子

0

精华

注册会员

Rank: 2

积分
44
威望
106
贡献
28
兑换币
0
注册时间
2012-5-23
在线时间
2 小时
毕业学校
北京师范大学珠海分校
跳转到指定楼层
1#
发表于 2012-5-23 17:48:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用的代码是龙丘的例程,但不知为何一直卡在byte SPI_RdWr_Byte(byte val)中的while(!(SPI0SR_SPIF));
已经检查过接线没问题,

#include "derivative.h"
#include "LQprintp.h"
#include "LQSDdriver.h"
         
#define SD_Sel()   PTM_PTM3=0        //低电平
#define SD_deSel() PTM_PTM3=1        //高电平
extern byte RXBUF[];
#pragma CODE_SEG DEFAULT  
void Dly_ms(int ms)
{   
   int ii,jj;
   if (ms<1) ms=1;
   for(ii=0;ii<ms;ii++)
     for(jj=0;jj<1335;jj++);  //16MHz--1ms
     
}
void New_Buf8(byte buffer[],byte ch)
{
    //-- Tx & Rx Buffer initialize
    int i, j=0;
    for(i=0;i<512;i++)
  *(buffer+i)=ch;   
}
void CLS_Buf8(byte buffer[])
{
    //-- Flushing Rx buffer
    int i;     
    for(i=0;i<512;i++)
  *(buffer+i)=0;
}
void View_Buf8(byte buffer[])
{
    int i=0;
    for(i=0;i<512;i++)
    {         
        if((i%32)==0)   printp( "\n" );
        printp("%02x,", buffer);
    }   
}  
/*******************************************
*                初始化部分                *
********************************************/  
void SCI_Init(void)
{
  SCI0CR2=0x2c; //enable Receive Full Interrupt,RX enable,Tx enable
  SCI0BDH=0x00; //busclk  8MHz,19200bps,SCI0BDL=0x1a
  SCI0BDL=0x34; //SCI0BDL=busclk/(16*SCI0BDL)=19200                 
}
void InitPorts(void)
{   
  DDRB= 0xff;          // set  port B bit0 as output
  PORTB=0X0;
}
void SetBusCLK_16M(void)
{   
    CLKSEL=0X00;    // disengage PLL to system
    PLLCTL_PLLON=1;   // turn on PLL
    SYNR=0x00 | 0x01;  // VCOFRQ[7:6];SYNDIV[5:0]
                        // fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1)
                        // fPLL= fVCO/(2 × POSTDIV)
                        // fBUS= fPLL/2
                        // VCOCLK Frequency Ranges  VCOFRQ[7:6]
                        // 32MHz <= fVCO <= 48MHz    00
                        // 48MHz <  fVCO <= 80MHz    01
                        // Reserved                  10
                        // 80MHz <  fVCO <= 120MHz   11   
    REFDV=0x80 | 0x01;  // REFFRQ[7:6];REFDIV[5:0]
                        // fREF=fOSC/(REFDIV + 1)
                        // REFCLK Frequency Ranges  REFFRQ[7:6]
                        // 1MHz <= fREF <=  2MHz       00
                        // 2MHz <  fREF <=  6MHz       01
                        // 6MHz <  fREF <= 12MHz       10
                        // fREF >  12MHz               11                        
                        // pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;
    POSTDIV=0x00;       // 4:0, fPLL= fVCO/(2xPOSTDIV)
                        // If POSTDIV = $00 then fPLL is identical to fVCO (divide by one).
    _asm(nop);          // BUS CLOCK=16M
    _asm(nop);
    while(!(CRGFLG_LOCK==1));   //when pll is steady ,then use it;
    CLKSEL_PLLSEL =1;          //engage PLL to system;
}
void Init_Dev(void)
{
  SetBusCLK_16M();
  InitPorts();
  PORTB=0;   
  SCI_Init();      
}   

//写、读一个字节
byte SPI_RdWr_Byte(byte val)
{
while (!SPI0SR_SPTEF);   
SPI0DRL = val;
while(!(SPI0SR_SPIF)); //debug时发现一直卡在这一句
return SPI0DRL;
}
void SPI_High_Rate(void)
{
  //最高操作速率不能高于25Mbps
  SPI0BR  = 0x02; //BR=busclk/((SPPR + 1)· 2^(SPR + 1))=16M/8=2M               
};
//sd卡初始化
void SD_Init(void)
{  
  MODRR_MODRR4 =1;   //使用M口
  DDRM    = 0x38;    //必须初始化IO方向  
  SPI0CR2 = 0x10;
  SPI0CR1 = 0x5e;    //
  SPI0BR  = 0x44;    //初始化用低速率
SD_deSel();
}
//sd卡写命令
byte SD_Send_Cmd(byte cmd, dword arg)
{
byte r1;
byte retry=0;

(void)SPI_RdWr_Byte(0xff);
SD_Sel();

(void)SPI_RdWr_Byte(cmd | 0x40);          //分别写入命令
(void)SPI_RdWr_Byte((byte)(arg>>24));
(void)SPI_RdWr_Byte((byte)(arg>>16));
(void)SPI_RdWr_Byte((byte)(arg>>8));
(void)SPI_RdWr_Byte((byte)(arg));
(void)SPI_RdWr_Byte(0x95);
r1 = SPI_RdWr_Byte(0xff);
while(r1== 0xff) //等待响应,
{
   r1 = SPI_RdWr_Byte(0xff);
  if(++retry > 100) break;                //超时退出
}
SD_deSel();
return r1;                                //返回状态值
}
//sd卡复位
byte SD_Reset(void)
{
byte i;
byte retry;
byte r1=0;
retry = 0;  
do
{
  for(i=0;i<10;i++)
    (void)SPI_RdWr_Byte(0xff);
  r1 = SD_Send_Cmd(0, 0);                 //发idle命令  
  if(++retry>100) return 1;               //超时退出
}while(r1 != 0x01);   
retry = 0;
do
{
  r1 = SD_Send_Cmd(1, 0);           //发active命令   
  if(++retry>100) return 1;         //超时退出
} while(r1);

r1 = SD_Send_Cmd(59, 0);            //关crc
r1 = SD_Send_Cmd(16, 512);          //设扇区大小512
return 0;                           //正常返回
}

#pragma CODE_SEG DEFAULT
//写一个扇区
byte Wt_Block(dword sector, byte* buffer)
{
byte r1;
word i;
//byte retry=0;
  if(sector<1) return 0xff;         //为了保护SD卡引导区,跳过该区
r1 = SD_Send_Cmd(24, sector<<9);  //写命令
if(r1 != 0x00) return r1;
SD_Sel();

(void)SPI_RdWr_Byte(0xff);
(void)SPI_RdWr_Byte(0xff);
(void)SPI_RdWr_Byte(0xff);
(void)SPI_RdWr_Byte(0xfe);        //发开始符

for(i=0; i<512; i++)              //送512字节数据
{
  (void)SPI_RdWr_Byte(*buffer++);
}

(void)SPI_RdWr_Byte(0xff);
(void)SPI_RdWr_Byte(0xff);

r1 = SPI_RdWr_Byte(0xff);

if((r1&0x1f) != 0x05)             //等待是否成功
{
   SD_deSel();
  return r1;
}
//等待操作完
while(!SPI_RdWr_Byte(0xff));      //if(++retry > 50){SPI_CS_Deassert();return 1;}
  SD_deSel();
return 0;     
}

//读一个扇区
byte Rd_Block(dword sector, byte* buffer)
{
byte r1;         
word i;
//byte retry=0;
r1 = SD_Send_Cmd(17, sector<<9);//读命令  
if(r1 != 0x00)   return r1;
SD_Sel();
//等数据的开始
while(SPI_RdWr_Byte(0xff) != 0xfe);//if(++retry > 50){SD_deSel();return 1;}
for(i=0; i<512; i++)//读512个数据
{
  *buffer++ = SPI_RdWr_Byte(0xff);
}
(void)SPI_RdWr_Byte(0xff);//伪crc
(void)SPI_RdWr_Byte(0xff);   
SD_deSel();
return 0;
}

#pragma CODE_SEG DEFAULT

/////////////main.c/////////////////

#include "derivative.h"
#include "LQprintp.h"  
#include <stdio.h>         
#include <string.h>  
#include "LQSDdriver.h"
  
byte RXBUF[512]={0};

void CLS_Buf(byte buffer[],byte L)
{
    int i;     
    for(i=0;i<L;i++) //128[word]*16[blk]=8192[byte]
  *(buffer+i)=0;
}
#pragma CODE_SEG DEFAULT      
void main(void)
{  
word RdWrAdd=0xff,cnt=0;

Init_Dev();  
  PORTB=0x00;
  putstr("\nLongQiu s.&t. MicroSD reading and writing:\n");     
  EnableInterrupts;
  
  
  PORTB=0Xf0;
  SD_Init();            //初始化spi口   
  while(SD_Reset())     //复位是否成功,不成功LED灭一半  表现为不断执行while循环
  {           
   printp("\nSD card init failed!Please insert your card !\n"); 这句有执行
   Dly_ms(500);   
}
PORTB=0X00;          //复位是否成功,成功LED全部亮
  SPI_High_Rate();     //SPI进入高速操作模式  
  printp("\nSD card init is ok! \nStartint to reading...\n");   
Dly_ms(200);         //稍等片刻,让LED亮
  PORTB=0Xff;   
  
  //读取SD卡引导区数据
if(!(Rd_Block(0x00, RXBUF))){
   
   PORTB=RXBUF[511]; //LED显示倒数第二个字节的数值
   printp("\nSD card reading is ok!\nBootload area is as fellow:\n");
   View_Buf8(RXBUF);  
}
else
{
   PORTB_PB1=1;
    PORTB_PB0=0;      
   printp("\nSD card reading failed!\n");
}
  RdWrAdd=0X200;
  //写/清空SD卡0X1FF区的数据
  New_Buf8(RXBUF,'x');
  if(!(Wt_Block(RdWrAdd+2,RXBUF)))    //写0x202块
  {   
   PORTB=RXBUF[511]; //LED显示倒数第二个字节的数值
   printp("\nSD card writing is ok!\n");
}
else
{   
    PORTB_PB0=0;      
   printp("\nSD card writing failed!\n");
}
  Dly_ms(2000);  
  
  RdWrAdd=0X200;
  for(;;)
  { //在这里添加用户代码
    //随便读取0x200-0x20a这10个块的内容并输出
    for(cnt=0;cnt<10;cnt++)
      if(!(Rd_Block(cnt+RdWrAdd, RXBUF)))
      {        
       printp("\nBlock 0x%04x is as fellow:\n",cnt+RdWrAdd);
       View_Buf8(RXBUF);  
     }
  }
  return;
}//end
////////////////////////////////////////

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-10-5 16:19 , Processed in 0.066769 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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