智能车制作

标题: 我自己写的SD卡读写 就是不能用 求大哥大姐们帮帮忙 ? [打印本页]

作者: 笑对人生    时间: 2012-10-27 21:40
标题: 我自己写的SD卡读写 就是不能用 求大哥大姐们帮帮忙 ?
#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include   <mc9s12xs128.h>                                     //128
#define INIT_CMD0_ERROR   0X01
#define INIT_CMD1_ERROR   0X02
#define Write_Block_ERROR 0X03
#define Read_Block_ERROR  0X04
uchar   is_init;              //初始化数据为1
uchar   pbuf[512] ;              //数据缓存区
//#include "SD_Card.h"
#define CS     PTS_PTS7
#define SD_IDLE   0X01
#define SD_OK     0X00
#define SD_CMD0   0X40
#define SD_CMD55  0X79
#define SD_CMD41  0X41
#define SD_CMD16  0X50
#define SD_CMD9   0X49
#define SD_CMD17  0X51
#define SD_CMD24  0X58
void      delay_0(uint z)             //延时函数
{
          uint x,y;
          for(z;z>0;z--)
          for(x=110;x>0;x--)
          for(y=25;y>0;y--);
}
//PLL初始化
void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{
    //PLLCLK=2*16M*(2+1)/(0+1)= 96M
    SYNR = 0xC2; //总线频率为PLL频率的一半48M
    REFDV = 0xC0;
    ECLKCTL &= ~0x80;
    while(!(CRGFLG&0x08)); //自循环语句,等待时钟频率稳定后允许锁相环时钟作为系统时钟
    CLKSEL=0x80; //选择锁相环频率为系统时钟频率
}
/****************************************************
  
//功    能:  IO口初始化()函数
//入口参数: 无
//出口函数: 无

****************************************************/
void IO_INIT(void)
{
     DDRM=0XFF;
     DDRS=0XEF;
     PTM=0XFF;
}
//SPI初始化
void SPI_Init(void)
{
    MODRR = 0x00;
    MODRR_MODRR4=0; //使用PM 口
    //DDRM |= 0x38; //可知SCK0=1,MOSI=1,SS0=1 本步可以忽略,这样做复位可以抗干扰下,并且直接让
    //片选无效
    SPI0CR1 = 0x5e; //CPOL=1,时钟选择低有效,spsck空闲时为高电平
    //CPHA=1 会在发送 8 位数据开始 sck就发生一次跳变
    SPI0CR2 = 0x10; //modfen=1 .和上面 ssoe=1 确定 spi在 master 模式下 ss 位从机选择输出。并允许 modf标志设置
    SPI0BR = 0x17; //波特率设置波特率= BR=busclk/((SPPR + 1)· 2^(SPR + 1))=48M / (1+1)*2^(7+1) = 93KHz
}
//设置 spi 高速
void SPI_High(void)
{
      SPI0BR = 0x01; //BR=busclk/((SPPR + 1)· 2^(SPR + 1))=48M / 4= 12m
}
//用SPI写1byte
void SPI_Write(unsigned char date)
{
      while (!SPI0SR_SPTEF); //等待发送器空
      (void)SPI0SR;
      SPI0DRL = date;
      while (!SPI0SR_SPIF); //等待发送完成
      (void)SPI0DRL;
}
//用SPI读1byte
unsigned char SPI_Read(void)
{
      while (!SPI0SR_SPTEF); //等待发送器空
      (void)SPI0SR;
      SPI0DRL = 0xff;
      while (!SPI0SR_SPIF); //等待发送完成
      (void)SPI0DRL;
      return SPI0DRL;
}
uchar Write_Cmd(uchar *pcmd)
{
   uchar temp,time=0,i;
  for(i=0;i<6;i++)            //写6个命令字节
{
   SPI_Write(pcmd[i]);        //写SD卡的8个命令
}
do
{
    temp=SPI_Read();          //读字节,直道读出数不是0xff 或者 超时
    time++;
}
while((temp==0xff)&&(time<100));
return temp;
}
uchar SD_Reset()             //SD卡复位 ,进入SPI协议,写入CMD0号命令
{
   uchar temp=0,time,i;
   uchar pcmd[]={0x40,0x00,0x00,0x00,0x00,0x95};
   
   CS=1;         //高电平,等待时钟
   for(i=0;i<15;i++)
   {
    SPI_Write(0xff);       //必须至少保持74个时钟,才可以读写SD卡
   }
   CS=0;         //低电平,片选成功,
   time=0;         //次数清零
   do
   {
    temp=Write_Cmd(pcmd);    //写入6个命令字节,写入CMD0号命令
    time++;
    if(time==200)  
    {
       return (INIT_CMD0_ERROR);   //写入CMD0失败
    }
   }
   while(temp!=0x01);
   CS=1;         
   SPI_Write(0xff);              //高电平,补8个时钟
   return 0;        //写入成功
}
uchar SD_INIT()               //SD卡初始化,写入CMD1号命令
{
   uchar temp=0,time;
   uchar pcmd[]={0x41,0x00,0x00,0x00,0x00,0xff};//CMD1号命令
   
   CS=0;           //低电平,片选成功,
   time=0;         //次数清零
   do
   {
    temp=Write_Cmd(pcmd);    //写入6个命令字节,写入CMD1号命令
    time++;
   
    if(time==100)  
    {
       return (INIT_CMD1_ERROR);   //写入CMD1失败
    }
   }
   while(temp!=0);
   SPI_High();         // 高速模式
   CS=1;        //关闭片选
   SPI_Write(0xff);    //高电平,补8个时钟
   return 0;      //成功初始化
}
uchar SD_Write_Sector(ulong add,uchar *Buffer)//SD卡写扇区地址add,
{
   uchar temp=0,time;
   uint i;
   uchar pcmd[]={0x58,0x00,0x00,0x00,0x00,0xff} ; //CMD24号命令
   add<<=9;        //add=add*512;每个扇区是512字节,
   pcmd[1]=((add&0xff000000)>>24);   //把扇区地址转化为字节地址
   pcmd[2]=((add&0xff000000)>>16);
   pcmd[3]=((add&0xff000000)>>8);
   CS=0;         //低电平,片选成功,
   time=0;         //次数清零
   do
   {
    temp=Write_Cmd(pcmd);   //写入6个命令字节,写入CMD24号命令
    time++;
    if(time==100)  
    {
       return temp;              //写入命令失败
    }
   }
   while(temp!=0);
   for(i=0;i<100;i++)
   {
    SPI_Read();              //这里插入若干个时钟
   }
   SPI_Write(0xfe);             //写入开始标志,然后写512字节
   for(i=0;i<512;i++)
   {
    SPI_Write(*Buffer++);      // 写512字节
   }
   SPI_Write(0xff);      //写入两个CRC校验
   SPI_Write(0xff);
   temp=SPI_Read();      //读取值
   if((temp&0x1f)!=0x05)
   {
       CS=1;        //关闭片选
    return (Write_Block_ERROR);   //返回写错误
   }
   while(SPI_Read()!=0xff);   //等待高电平为不忙状态,低电平为忙线
   CS=1;        //关闭片选
   SPI_Write(0xff);             //高电平,补8个时钟
   return 0;       //成功写入块数据
}

uchar SD_Read_Sector(ulong add,uchar *Buffer)//SD卡写扇区地址add,
{
   uchar temp=0,time;
   uint  j;
   uchar pcmd[]={0x51,0x00,0x00,0x00,0x00,0xff} ; //CMD17号命令
   add<<=9;        //add=add*512;每个扇区是512字节,
   pcmd[1]=((add&0xff000000)>>24);   //把扇区地址转化为字节地址
   pcmd[2]=((add&0xff000000)>>16);
   pcmd[3]=((add&0xff000000)>>8);
   CS=0;         //低电平,片选成功,
   time=0;         //次数清零
   do
   {
    temp=Write_Cmd(pcmd);   //写入6个命令字节,写入CMD17号命令
    time++;
    if(time==100)  
    {
       return (Read_Block_ERROR);   //读块失败
    }
   }
   while(temp!=0);
   while(SPI_Read()!=0xfe);   //一直在读取数据,直道数据为0xfe 后面就是512个字节读数据了
   for(j=0;j<512;j++)
   {
    Buffer[j]=SPI_Read();     //读取512字节
   }
   SPI_Read();        //读取 两个字节CRC校验
   SPI_Read();
   CS=1;        //关闭片选
   SPI_Write(0xff);             //高电平,补8个时钟
   return 0;       //成功写入块数据
}
  void main()  
  {   
       PLL_Init();
       IO_INIT();   
       SPI_Init();
       SD_Reset();
       if(SD_INIT()==0)PTM=0X00;
       else PTM=0Xf3;
       while(1)
       {
      
          SD_Read_Sector(80,pbuf);
      
      
       }
      
      
  
  }


作者: 笑对人生    时间: 2012-10-27 21:42
哪位大哥大姐们有xs128的读取SD卡的可以用的代码   求一份 ,我都快奔溃了,小弟在此谢谢了

作者: turf456    时间: 2012-10-27 22:34
SD卡不好玩的,先从网上多扒几个试试。都不行就换个卡试试。
作者: yukunlinykl    时间: 2012-10-27 22:44
我写了两年了,都不能做到100%成功。。。默默流泪。。。
作者: 0726silence    时间: 2012-10-28 09:49
sd卡怎么商人啊。我都没搞出来啊伤不起,这几天我也在搞
作者: 993809188    时间: 2012-10-28 18:53
我也只会对单扇区的读写,对文件系统一点不会,愁人那




欢迎光临 智能车制作 (http://dns.znczz.com/) Powered by Discuz! X3.2