⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_rw2.lst

📁 PIC18读取sd卡的程序
💻 LST
📖 第 1 页 / 共 2 页
字号:
     1: //**************************************************

     2: // 项目:PIC单片机对SD卡进行单块数据的读写操作

     3: // 系统:PIC18F877A, 16MHz,   SPI(主)

     4: // 编程:2005-12

     5: //**************************************************

     6: 

     7: #include <pic18.h>

     8: //  __CONFIG (HS & PROTECT & PWRTEN & BOREN & WDTDIS);

     9: #define  SD_TEST

    10: 

    11: void  crcInit(void);

    12: unsigned int crcCompute(unsigned char * message, unsigned int nBytes);

    13: 

    14: 

    15: #define  CMD0     0x00                    //GO IDLE STATE

    16: #define  CMD1     0x01                    //SEND OP COND

    17: #define  CMD9     0x09                    //SEND CSD

    18: #define  CMD13    0x0d                    //SEND STATUS

    19: #define  CMD16    0x10                    //SET BLOCK LENGTH

    20: #define  CMD17    0x11                    //READ SINGLE BLOCK

    21: #define  CMD24    0x18                    //WRITE BLOCK

    22: #define  CMD59    0x3B                    //CRC_ON_OFF

    23: 

    24: #define  W_ADDR   0x00000001                  //写地址

    25: #define  R_ADDR   0x00000001                  //读地址

    26: #define  BLOCKlEN    0x000a               //设置读写块的长度为10,默认的块长度在CSD中

    27: 

    28: #define  SPICtrl   RB0                     //SPI片选,待定

    29: #define  H_FF      0xff                    //发送FF,MISO模式

    30: #define  NOARG    0x00000000               //命令无参数

    31: #define  C_R1     1                        //响应字节数1

    32: #define  C_R1b    2                        //响应字节数1,有busy信号,写操作

    33: #define  NSAC     8                                                     //在CSD中设定

    34: #define BL_LEN    12

    35: 

    36: #define FD_FE    0xfe                    //发送首字节为0xFE

    37: //开辟两个缓冲区,大小均为一个块地址的大小,对发送缓冲区的前十个数据赋初值

    38: 

    39: unsigned char  w_buf[BL_LEN-2]={0Xfe,1,2,3,4,5,6,7,8,9};    //发送缓冲区

    40: unsigned char  r_buf[BL_LEN];           //接受缓冲区,不包括CRC校验值

    41: unsigned int   *wr_crc;     //缓冲区CRC值存放区

    42: unsigned char  * WB_re ;             //接收写数据块的响应

    43: 

    44: unsigned char  SW_rst[6]  =  {0x40,0x0,0x0,0x0,0x0,0x95};   //软件复位命令

    45: 

    46: #ifdef SD_TEST

    47: unsigned char  csd[16] ;            //存放CSD寄存器的信息

    48: /***************************************************************************/

    49: //         CSD 128bit register      P64 definition

    50: //         [119:112] TAAC           

    51: //         [83:80] READ_BL_LEN    [79] READ_BL_PARTIAL   (allways = 1 in SD Memory Card)最小数据块可为1Byte

    52: //         [25:22] WRITE_BL_LEN   [21] WRIE_BL_PARTIAL    [7:1] CRC

    53: /***************************************************************************/

    54: #endif

    55: 

    56: bit   b_sdw;                        //写操作完成标志位

    57: bit   b_sdr;                        //读操作完成标志位

    58: bit   b_cmdnr;                      //命令无响应标志位

    59: bit   b_dnr;                        //数据接收无响应标志位

    60: bit       b_cmdr_er;                                    //命令响应错误标志位

    61: 

    62: 

    63: //系统初始化

    64:  void Sys_Init(void) 

    65:    {   

    66:         

    67:    SSPSTAT=0 ;         //SMP=0,CKE=0,BF=0

    68:    SSPCON1=0b00100010; //SSPEN=1,CKP=0,FOSC/64

    69: 

    70:    TRISB=0b11111100; //RB0,RB1输出

    71:    TRISC=0b10010111; //RC3,5,6输出

    72:    RBPU=1;           //RB弱上拉关闭

    73:         

    74:    b_sdw=0;                        //写操作完成标志位

    75:    b_sdr=0;                        //读操作完成标志位

    76:    b_cmdnr=0;                      //命令无响应标志

    77:    b_dnr=0;

    78:    WB_re = 0x00;                    //清空寄存器

    79:    wr_crc = 0x0000;

    80:  

    81:    }

    82: 

    83:    //中断初始化

    84:    void Int_Init(void) 

    85:    {

    86:       //SPI中断

    87:        SSPIF=0;         //清除SPI中断标志

    88:        SSPIE=1;         //中断允许?采用查询方式  

    89: 

    90:       //总中断

    91:        PEIE=0;          //外围中断禁止

    92:        GIE=0;           //总中断禁止

    93:    }

    94:    

    95:   /************************************************************/

    96:   /*   PIC发送数据

    97:   /************************************************************/

    98:    void PIC_W ( char * w_ad , int nByte)        //PIC发送,首地址,字节数

    99:    {

   100:       unsigned char * w_ptr;

   101:       unsigned int i;

   102:       w_ptr = w_ad;

   103:       for ( i = 0; i < nByte; i++ )

   104:       {

   105:             SSPBUF = * w_ptr;

   106:             while (!SSPIF) {;}

   107:             SSPIF = 0;

   108:             w_ptr ++;

   109:       }

   110: 

   111:    }

   112:    

   113:    /************************************************************/

   114:   /*   PIC接收数据

   115:   /************************************************************/

   116:    void PIC_R ( char * r_ad , int nByte)        //PIC接收,首地址,字节数

   117:    {

   118:       unsigned char * r_ptr;

   119:       unsigned int i;

   120:       r_ptr = r_ad;

   121:       for ( i = 0; i < nByte; i++ )

   122:       {

   123:             SSPBUF = H_FF ;

   124:             while (!SSPIF) {;}

   125:             SSPIF = 0;

   126:             * r_ptr = SSPBUF;

   127:             r_ptr ++;

   128:       }

   129: 

   130:    }

   131:   

   132:    /*****************************************************************/

   133:    //In the non-protected mode   the CRC bits of the command,

   134:    //response and data tokens are still required in the tokens.

   135:    // However, they are defined as ‘don’t care’ for the transmitter

   136:    // and ignored by the receiver

   137:    /*****************************************************************/

   138:    unsigned char CMD_CRC(char * cmdcrc)

   139:         {

   140:       unsigned char crc7;

   141:       unsigned int crc_res;                   //存放crc计算结果

   142:       crc_res = crcCompute( cmdcrc, 5);          //计算结果为16bit

   143:     ////////////////////////                             //如何取期中的一个字节作为返回值

   144:           crc7 = (char)(crc_res>>8 &0xff | 0x01);

   145:           return crc7;

   146:    }

   147:    

   148:   /************************************************************/

   149:   /*   等待周期,表示等待周期

   150:   /************************************************************/

   151:   void SPI_wt(int n)                       //SD卡准备好

   152:       {

   153:          char * busy;

   154:          unsigned i;

   155:          PIC_R (busy,i);

   156:       }

   157:   

   158:   

   159:   /************************************************************/

   160:   /*   发送命令字

   161:   /************************************************************/

   162: 

   163:    struct COM1                               //命令控制结构

   164:    {

   165:      char c;

   166:      unsigned long l;

   167:      char e;

   168:    };

   169: 

   170:    union COM2

   171:    {

   172:       struct COM1 c6;

   173:       char c1[6];

   174:    };

   175: 

   176:    void SD_CMD ( char CMD,  unsigned long ARG )        //发送命令控制,响应类型为R1

   177:    {

   178:       char c_crc;

   179:       char * cmd_r1;

   180:       unsigned int tncr;

   181:       union COM2 command;

   182:       command.c6.c = 0x40 | CMD;

   183:       command.c6.l = ARG;

   184:       c_crc = CMD_CRC(command.c1);             //命令字节的首地址

   185:       command.c6.e = c_crc;

   186:       tncr = 0;

   187:       b_cmdnr = 0;                            //发送前对标志位进行初始化

   188:       b_cmdr_er = 0;

   189:       PIC_W( command.c1 , 6 );                 //send cmd 

   190: 

   191:       while(1)

   192:       {  

   193:          PIC_R ( cmd_r1 , 1); 

   194:          if( * cmd_r1 != 0xff )

   195:           {   break; }

   196:          else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -