注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
上帝之手的个人空间 https://home.eeworld.com.cn/space-uid-404945.html [收藏] [复制] [分享] [RSS]
日志

请高手帮我看下SD读写程序哪里错误了,谢谢

已有 2614 次阅读2012-5-22 11:45 |个人分类:SD卡应用|

我用的是C8051F350单片机,完成AD转换后需要将采集数据存储到SD卡用的是SPI模式,但是再初始化过程中返回命令总是不对,请哪位懂的,帮我看看,非常谢谢您!以下是我的代码:
 
 
 #include <C8051F350.h>                 // SFR declarations
#include <stdio.h>
sfr16 TMR2RL = 0xCA;                   // Timer2 reload value
sfr16 TMR2 = 0xCC;                     // Timer2 counter
sfr16 ADC0DEC = 0x9A; 
#define SYSCLK       24500000
#define MDCLK         2457600
#define OWR                20
#define BAUDRATE       9600//115200
#define SPI_CLOCK     500000
sbit CS=P0^6;
void Oscillator_Init (void);
void Port_Init (void);
void UART0_Init (void);
void ADC0_Init(void);
void SPI0_Init (void);
void Reset_SD_Card(void);
void Init_SD_Card(void);
void Write_SD_Card(unsigned long addr,unsigned char *Buffer);
void Delay(void);
void Init_Device (void);
unsigned char SPI_Read (void);
unsigned char Reset_R1,Init_comdata,Write_middle_R1,Write_R1;
unsigned  char  *data_tst;

void main()
{    
 unsigned  i,j=0,k=0;
    unsigned long Laddr=0x00000001;
    char xdata sample[512];
    PCA0MD&=~0X40;
 Init_Device ();
 
   /* printf("c"); 
  do
  { 
   
  Init_SD_Card();
    
    Delay();
   
   }
   while(Init_comdata!=0x00);  */
 
   EA=1;
  
   printf("\nMeasurements using the 24-bit ADC in C8051F350\n");
      printf("\nCalibrating ...\n");
     
      EIE1&=~0x08;
   ADC0MD|=0x01;
   while(!AD0CALC);
   ADC0MD&=0x07;
     
    printf("Calibration complete\n\n");
    AD0INT=0;
    ADC0MD=0x83;
   // Reset_SD_Card();
    while(1)
    {
       printf ("Collecting 512 samples...\n");

            for (i = 0; i < 128; i++)
      {
         while(!AD0INT);                     // wait till conversion complete
          AD0INT = 0;                         // clear AD0 interrupt flag
          sample[j++]=ADC0H;
          sample[j++]=ADC0M;
          sample[j++]=ADC0L;
          sample[j++]=0X00;
      }
       for(k=0;k<512;k++)
        printf ("SAMPLE%d:%bx\n",k,sample[k]);
       
       data_tst=sample;
 Reset_SD_Card();
    printf("a");
   do
   {
    Init_SD_Card();
 printf("b");
    Delay();
   }
   while(Init_comdata != 0x00);
     Write_SD_Card(Laddr,data_tst);
 
     Laddr++;
       AD0INT=0;
       i=0;
       }
  
   
}
 
 

void Init_Device (void)
{   Port_Init ();
    Oscillator_Init ();
    UART0_Init ();
    ADC0_Init();
    SPI0_Init();
   }

 void Oscillator_Init (void)
 {
    OSCICN = 0x83; 
 RSTSRC = 0x04;
 
 }
 
      void Port_Init (void)
   {
    P0MDOUT=0X55;
   
    P0SKIP=0X40;
   
   /* P1MDOUT=0Xff;
   
    P1SKIP=0Xff;*/
   
    XBR0=0X03;
   
    XBR1=0X40;
   
    }
 
void UART0_Init (void)
{
      SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON |=  0x08;                  // T1M = 1; SCA1:0 = xx
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x01;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else if (SYSCLK/BAUDRATE/2/256 < 48) {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   } else {
      while (1);                       // Error.  Unsupported baud rate
   }
   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TR1 = 1;                            // START Timer1
   TI0 = 1;                            // Indicate TX0 ready
}
 
   void ADC0_Init (void)
{
   ADC0CN=0x00;
   ADC0CF=0x04;
   ADC0CLK=(SYSCLK/MDCLK)-1;
   ADC0DEC = ((unsigned long) MDCLK / (unsigned long) OWR /
              (unsigned long) 128) - 1;
   ADC0BUF = 0x00;
   ADC0MUX = 0x28; 
   REF0CN |= 0x03; 
  
   ADC0MD=0x81;
   while(AD0CALC != 1);                // Wait until calibration is complete
  
   EIE1   |= 0x08;                     // Enable ADC0 Interrupts
   ADC0MD  = 0x80;                     // Enable the ADC0 (IDLE Mode)
}

void SPI0_Init()
{
   SPI0CFG   = 0x70;                   // Enable the SPI as a Master ,SCK在空闲状态时处于高电平
   //SPI0CFG   = 0x50;                                    // CKPHA = '0', CKPOL = '1'
  
   SPI0CN    = 0x01;                   // 3 wire Single Master, SPI enabled
   // SPI clock frequency equation from the datasheet
   SPI0CKR   = (SYSCLK/(2*SPI_CLOCK))-1;
   ESPI0 = 1;                          // Enable SPI interrupts
}

unsigned char SPI_Read (void)
{
     SPIF = 0;
     return SPI0DAT; 
}
void SPI_ISR (void) interrupt 6
{
  
}

void Delay (void)
{
   unsigned char count;
   for (count = 100; count > 0; count--);
}

void Reset_SD_Card(void)
{
 unsigned char i;
 ESPI0 = 0;         //关闭发送中断
 CS = 1;
 
 for(i=0;i<0x0f;i++)    //输出74个以上时钟周期
 {
   SPI0DAT = 0xff;               // Load the data into the buffer
      while (TXBMT != 1);               // Wait until the data is moved into XBMT buffer
 }
 Delay();
 CS = 0;            //开片选
 Delay();
 SPI0DAT = 0x40;    //CMD0
 while(TXBMT != 1);
 Delay();
 SPI0DAT = 0x00;    //输出8*4个clocks
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
 Delay();
 SPI0DAT = 0x95;      //crc
    while(TXBMT != 1);
 Delay();
 SPI0DAT = 0xff;   //8× multiples of 8 clocks   Ncr
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);
 Delay();
 Reset_R1 = SPI0DAT;     //读接受数据缓冲区,清空接收数据缓冲区,这样让sd卡响应数据可以顺利接收
 SPI0DAT = 0xff;   //输出dummy时钟周期,让sd卡响应字节进入接受缓冲区
    while(TXBMT != 1);
 CS = 1;        //关片选
 
 Reset_R1 = SPI0DAT;       //读出响应数据
 SPI0DAT = 0xff;
    while(TXBMT != 1);//确保操作完成
 SPIF = 0;          //清中断标志位
 ESPI0 = 1;         //开发送中断
}
//------------------------------------
//初始化 sd卡
//------------------------------------
void Init_SD_Card(void)
{
 unsigned char i;
 
 ESPI0 = 0;       //关闭发送中断
 /*SPI0DAT = 0xff;
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);*/
 CS = 0;          //开片选
 Delay();
 SPI0DAT = 0x41;       //CMD1
    while(TXBMT != 1);
 Delay();
 SPI0DAT = 0x00;    //输出8*4个clocks
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
 SPI0DAT = 0x00;
    while(TXBMT != 1);
Delay();
 SPI0DAT = 0xff;      //crc
    while(TXBMT != 1);
 Delay();
 SPI0DAT = 0xff;   //8× multiples of 8 clocks   Ncr
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);
 
 Delay();
 Init_comdata = SPI0DAT;
 Delay();
 i = SPI0DAT;     //读接受数据缓冲区,清空接收数据缓冲区,这样让sd卡响应数据可以顺利接收
 SPI0DAT = 0xff;   //输出dummy时钟周期,让sd卡响应字节进入接受缓冲区
    while(TXBMT != 1);
 
 CS = 1;          //关片选
 Init_comdata = SPI0DAT;
 SPI0DAT = 0xff;
    while(TXBMT != 1);
 SPIF = 0;          //清中断标志位
 ESPI0 = 1;       //开发送中断
}
 
void Write_SD_Card(unsigned long addr,unsigned char *Buffer )
{
   unsigned int i;
   unsigned char CMD[6]={0x58,0x00,0x00,0x00,0x00,0xff};
   unsigned char a,b,c,d;
   addr=addr<<9;
   a=((addr&0xff000000)>>24);
   b=((addr&0x00ff0000)>>16);
   c=((addr&0x0000ff00)>>8);
   d=((addr&0x000000ff)>>0);
   ESPI0=0;
  
   CS = 0;
   Delay();
   SPI0DAT=0x58;
   while(TXBMT!=1);
   Delay();
   SPI0DAT=a;
   
   while(TXBMT!=1);
   SPI0DAT=b;
 
   while(TXBMT!=1);
   SPI0DAT=c;
   while(TXBMT!=1);
   SPI0DAT=d;
   while(TXBMT!=1);
    Delay();
 SPI0DAT=0xff;
 while(TXBMT!=1);
  Delay();
 SPI0DAT = 0xff;   //8× multiples of 8 clocks   Ncr
    while(TXBMT != 1);
 
    SPI0DAT = 0xff;
    while(TXBMT != 1);
 Delay();
 do{
     Write_middle_R1=SPI0DAT;
  SPI0DAT=0xff;
  while(TXBMT!=1);
         printf("SPI0DAT:%bx\n",Write_middle_R1);
  }while(Write_middle_R1!=0x00);
    Delay();
 SPI0DAT = 0xff;   //8×multiples of 8 clocks   Nwr
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);
 Delay();
    SPI0DAT = 0xfe;      //start byte
   while(TXBMT != 1);
   for(i=0;i<512;i++)
 {
  SPI0DAT = *(Buffer++);
    while(TXBMT != 1);
 }
 
 SPI0DAT = 0xff;   //crc    don't care
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);
 Delay();
 do
 {
  Write_R1 = SPI0DAT;
  SPI0DAT = 0xff;   //输出dummy clocks,得到sd卡响应
    while(TXBMT != 1);
 }
 while((Write_R1 & 0x1f) != 0x05);

 SPI0DAT = 0xff;   //8×multiples of 8 clocks
    while(TXBMT != 1);
 SPI0DAT = 0xff;
    while(TXBMT != 1);
  Delay();
 CS = 1;  
 Delay();
SPI0DAT = 0xff;
    while(TXBMT != 1);
SPIF = 0;
 
 ESPI0 = 1; 
}
 
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章