📄 ch375.lst
字号:
C51 COMPILER V7.06 CH375 11/22/2004 22:08:30 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE CH375
OBJECT MODULE PLACED IN CH375.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE CH375.C DEBUG OBJECTEXTEND CODE
stmt level source
1 /* 2004.03.05
2 ****************************************
3 ** **
4 ** **
5 ****************************************
6 ** USB 1.1 Host Examples for CH375 **
7 ** KC7.0@MCS-51 **
8 ****************************************
9 */
10 /* CH375作为USB主机接口的程序示例 */
11
12 /* MCS-51单片机C语言的示例程序, U盘数据读写 */
13
14 #include "common.h"
15
16 unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
17 unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */
18 extern unsigned char xdata DBUF[BUFFER_LENGTH];
19
20 //sbit LED_OUT = 0x90^4; /* P1.4 低电平驱动LED显示,用于监控演示程序的进度 */
21 sbit CH375_INT_WIRE = 0xB0^2; /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */
22
23
24 #define mDelay1uS( ) /* 对于MCS51单片机,通常不需要1uS延时 */
25
26 /* 延时2微秒,请根据单片机速度 */
27 //void mDelay1uS( )
28 //{
29 // unsigned char i;
30 // for ( i = 1; i != 0; i -- );
31 //}
32
33 /* 延时2微秒,请根据单片机速度 */
34 void mDelay2uS( )
35 {
36 1 unsigned char i;
37 1 for ( i = 2; i != 0; i -- );
38 1 }
39
40 /* 向CH375命令端口写命令数据 */
41 void CH375_CMD_PORT_d_out( INT8 d_out )
42 {
43 1 mDelay1uS( );
44 1 CH375_CMD_PORT=d_out;
45 1 mDelay2uS( ); /* 至少延时2uS */
46 1 }
47
48 /* 向CH375数据端口写数据 */
49 void CH375_DAT_PORT_d_out( INT8 d_out )
50 {
51 1 CH375_DAT_PORT=d_out;
52 1 mDelay1uS( );
53 1 }
54
55 /* 从CH375命令端口读数据 */
C51 COMPILER V7.06 CH375 11/22/2004 22:08:30 PAGE 2
56 INT8 CH375_DAT_PORT_in( )
57 {
58 1 mDelay1uS( );
59 1 return( CH375_DAT_PORT );
60 1 }
61
62 /* 延时毫秒,不精确 */
63 void DelayMs(unsigned char nFactor)
64 {
65 1 unsigned char i;
66 1 unsigned int j;
67 1 for(i=0; i<nFactor; i++) for(j=0;j<1000;j++) j=j;
68 1 }
69
70 /* 等待CH375中断并获取状态 */
71 unsigned char mWaitInterrupt( )
72 {
73 1 unsigned char c;
74 1 while ( CH375_INT_WIRE ); /* 如果CH375的中断引脚输出高电平则等待 */
75 1 CH375_CMD_PORT_d_out( CMD_GET_STATUS); /* 获取当前中断状态 */
76 1 c = CH375_DAT_PORT_in(); /* 返回中断状态 */
77 1 /* if ( c == USB_INT_DISCONNECT ) /* 检测到USB设备断开事件 */
78 1 /* else if ( c == USB_INT_CONNECT ) /* 检测到USB设备连接事件 */
79 1 return( c );
80 1 }
81
82 /* 设置CH375为USB主机方式 */
83 unsigned char mCH375Init( )
84 {
85 1 unsigned char i;
86 1 #ifdef TEST_CH375_PORT
unsigned char c;
CH375_CMD_PORT_d_out(CMD_CHECK_EXIST); /* 测试工作状态 */
CH375_DAT_PORT_d_out( 0x55); /* 测试数据 */
c = CH375_DAT_PORT_in(); /* 返回数据应该是测试数据取反 */
if ( c != 0xaa ) { /* CH375出错 */
for ( i = 100; i != 0; i -- ) { /* 强制数据同步 */
CH375_CMD_PORT_d_out( CMD_RESET_ALL ); /* CH375执行硬件复位 */
c = CH375_DAT_PORT_in(); /* 延时 */
}
DelayMs( 50 ); /* 延时至少30mS */
}
#endif
99 1 CH375_CMD_PORT_d_out( CMD_SET_USB_MODE); /* 设置USB工作模式 */
100 1 CH375_DAT_PORT_d_out( 6); /* 模式代码,自动检测USB设备连接 */
101 1 for ( i = 0xff; i != 0; i -- ) { /* 等待操作成功,通常需要等待10uS-20uS */
102 2 if ( CH375_DAT_PORT_in() == CMD_RET_SUCCESS ) break; /* 操作成功 */
103 2 }
104 1 if ( i != 0 ) return( 0 ); /* 操作成功 */
105 1 else return( 0xff ); /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */
106 1 }
107
108 /* 初始化磁盘 */
109 unsigned char mInitDisk( )
110 {
111 1 unsigned char mIntStatus;
112 1 CH375_CMD_PORT_d_out( CMD_DISK_INIT); /* 初始化USB存储器 */
113 1 mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
114 1 //if ( mIntStatus == USB_INT_SUCCESS ) return( 0 ); /* U盘已经成功初始化 */
115 1 return mIntStatus ; /* 出现错误 */
116 1 }
117
C51 COMPILER V7.06 CH375 11/22/2004 22:08:30 PAGE 3
118 unsigned char ReadCapacity(void)
119 {
120 1 unsigned char *mBufferPoint;
121 1 unsigned char mIntStatus,mLength;
122 1 CH375_CMD_PORT_d_out( CMD_DISK_SIZE); /* 读取容量 */
123 1 mBufferPoint=DBUF;
124 1 mIntStatus = mWaitInterrupt( );
125 1 if ( mIntStatus == USB_INT_DISK_READ )
126 1 { /* USB存储器读数据块,请求数据读出 */
127 2 CH375_CMD_PORT_d_out( CMD_RD_USB_DATA); /* 从CH375缓冲区读取数据块 */
128 2 mLength = CH375_DAT_PORT_in(); /* 后续数据的长度 */
129 2 while ( mLength ) { /* 根据长度读取数据 */
130 3 *mBufferPoint = CH375_DAT_PORT_in(); /* 读出数据并保存 */
131 3 mBufferPoint ++;
132 3 mLength --;
133 3 }
134 2 return 1;
135 2 }
136 1 }
137
138 unsigned long SwapINT32(unsigned long dData)
139 {
140 1 dData = (dData&0xff)<<24|(dData&0xff00)<<8|(dData&0xff000000)>>24|(dData&0xff0000)>>8;
141 1 return dData;
142 1 }
143
144 unsigned int SwapINT16(unsigned int dData)
145 {
146 1 dData = (dData&0xff00)>>8|(dData&0x00ff)<<8;
147 1 return dData;
148 1 }
149
150 /* 从U盘中读取多个扇区的数据块到缓冲区中 */
151 unsigned char RBC_Read(unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *mBufferPoint)
152 /* iLbaStart 是读取的线起始性扇区号, iSectorCount 是读取的扇区数 */
153 {
154 1 unsigned char mIntStatus;
155 1 unsigned int mBlockCount;
156 1 unsigned char mLength;
157 1 CH375_CMD_PORT_d_out(CMD_DISK_READ); /* 从USB存储器读数据块 */
158 1 CH375_DAT_PORT_d_out((unsigned char)iLbaStart); /* LBA的最低8位 */
159 1 CH375_DAT_PORT_d_out ((unsigned char)( iLbaStart >> 8 ));
160 1 CH375_DAT_PORT_d_out((unsigned char)( iLbaStart >> 16 ));
161 1 CH375_DAT_PORT_d_out((unsigned char)( iLbaStart >> 24 )); /* LBA的最高8位 */
162 1 CH375_DAT_PORT_d_out( iSectorCount); /* 扇区数 */
163 1 // mBufferPoint = &DATA_BUFFER; /* 指向缓冲区起始地址 */
164 1 for ( mBlockCount = iSectorCount * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- ) { /* 数据块计数
- */
165 2 mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
166 2 if ( mIntStatus == USB_INT_DISK_READ ) { /* USB存储器读数据块,请求数据读出 */
167 3 CH375_CMD_PORT_d_out(CMD_RD_USB_DATA); /* 从CH375缓冲区读取数据块 */
168 3 mLength = CH375_DAT_PORT_in(); /* 后续数据的长度 */
169 3 /* 通常数据长度是64,有些U盘要求单片机必须在2mS之内取走64字节数据,否则U盘可能数据丢失 */
170 3 /* 建议优化下面的循环程序,确保单片机在1mS之内完成64字节的数据传输 */
171 3 if ( mLength ) { /* 根据长度读取数据 */
172 4 do { // 对于C51,这个DO+WHILE结构效率高,速度快
173 5 *mBufferPoint = CH375_DAT_PORT_in(); /* 读出数据并保存 */
174 5 mBufferPoint ++;
175 5 } while ( -- mLength );
176 4 }
177 3 CH375_CMD_PORT_d_out( CMD_DISK_RD_GO); /* 继续执行USB存储器的读操作 */
178 3 }
C51 COMPILER V7.06 CH375 11/22/2004 22:08:30 PAGE 4
179 2 else break; /* 返回错误状态 */
180 2 }
181 1 if ( mBlockCount == 0 ) mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
182 1 if ( mIntStatus == USB_INT_SUCCESS ) return 1; /* 操作成功 */
183 1 else return 0; /* 操作失败 */
184 1 }
185
186 /* 将缓冲区中的多个扇区的数据块写入U盘 */
187 unsigned char RBC_Write( unsigned long iLbaStart, unsigned char iSectorCount,unsigned char *mBufferPoint )
188 /* iLbaStart 是写入的线起始性扇区号, iSectorCount 是写入的扇区数 */
189 {
190 1 unsigned char mIntStatus;
191 1 unsigned int mBlockCount;
192 1 unsigned char mLength;
193 1 CH375_CMD_PORT_d_out( CMD_DISK_WRITE); /* 向USB存储器写数据块 */
194 1 CH375_DAT_PORT_d_out((unsigned char)iLbaStart); /* LBA的最低8位 */
195 1 CH375_DAT_PORT_d_out((unsigned char)( iLbaStart >> 8 ));
196 1 CH375_DAT_PORT_d_out((unsigned char)( iLbaStart >> 16 ));
197 1 CH375_DAT_PORT_d_out((unsigned char)( iLbaStart >> 24 )); /* LBA的最高8位 */
198 1 CH375_DAT_PORT_d_out(iSectorCount); /* 扇区数 */
199 1 //mBufferPoint = &DATA_BUFFER; /* 指向缓冲区起始地址 */
200 1 for ( mBlockCount = iSectorCount * CH375_BLK_PER_SEC; mBlockCount != 0; mBlockCount -- ) { /* 数据块计数
- */
201 2 mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
202 2 if ( mIntStatus == USB_INT_DISK_WRITE ) { /* USB存储器写数据块,请求数据写入 */
203 3 CH375_CMD_PORT_d_out( CMD_WR_USB_DATA7); /* 向CH375缓冲区写入数据块 */
204 3 mLength = CH375_BLOCK_SIZE;
205 3 CH375_DAT_PORT_d_out(mLength); /* 后续数据的长度 */
206 3 /* 通常数据长度是64,有些U盘要求单片机必须在2mS之内写入64字节数据,否则U盘可能数据丢失 */
207 3 /* 建议优化下面的循环程序,确保单片机在1mS之内完成64字节的数据传输 */
208 3 do { // 对于C51,这个DO+WHILE结构效率高,速度快
209 4 CH375_DAT_PORT_d_out(*mBufferPoint); /* 将数据写入 */
210 4 mBufferPoint ++;
211 4 } while ( -- mLength );
212 3 CH375_CMD_PORT_d_out( CMD_DISK_WR_GO); /* 继续执行USB存储器的写操作 */
213 3 }
214 2 else break; /* 返回错误状态 */
215 2 }
216 1 if ( mBlockCount == 0 ) mIntStatus = mWaitInterrupt( ); /* 等待中断并获取状态 */
217 1 if ( mIntStatus == USB_INT_SUCCESS ) return 1; /* 操作成功 */
218 1 else return 0; /* 操作失败 */
219 1 }
220
221 INT8 mCH375Read( INT8 mAddr )
222 {
223 1 CH375_CMD_PORT_d_out( 0x0A );
224 1 CH375_DAT_PORT_d_out( mAddr );
225 1 if ( mAddr ) return( CH375_DAT_PORT_in( ) );
226 1 else return( 0 );
227 1 }
228
229 void mCH375Write( INT8 mAddr, INT8 mData )
230 {
231 1 CH375_CMD_PORT_d_out( 0x0B );
232 1 CH375_DAT_PORT_d_out( mAddr );
233 1 CH375_DAT_PORT_d_out( mData );
234 1 }
235
236 INT8 epBulkSend( INT8 *mBuffer, INT8 mLength )
237 {
238 1 unsigned char mBulkOut;
239 1 unsigned char CH375IntStatus;
C51 COMPILER V7.06 CH375 11/22/2004 22:08:30 PAGE 5
240 1 CH375_CMD_PORT_d_out( CMD_WR_USB_DATA7 ); /* 向CH375的端点缓冲区写入准备发送的数据 */
241 1 CH375_DAT_PORT_d_out( mLength ); /* 后续数据长度4 */
242 1 while( mLength ) {
243 2 CH375_DAT_PORT_d_out( *mBuffer );
244 2 mBuffer ++;
245 2 mLength --;
246 2 }
247 1 mCH375Write( SFR_USB_H_ENDP, mCH375Read( VAR_UDISK_TOGGLE ) );
248 1 mBulkOut = mCH375Read( VAR_UDISK_BULK_OUT );
249 1 CH375IntStatus = 0; /* 清操作完成的中断状态 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -