📄 sd_rw2.lst
字号:
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 + -