📄 urw.lst
字号:
__text_start:
__start:
0096 EFCF LDI R28,0xFF
0097 E1D0 LDI R29,0x10
0098 BFCD OUT 0x3D,R28
0099 BFDE OUT 0x3E,R29
009A 51C0 SUBI R28,0x10
009B 40D0 SBCI R29,0
009C EA0A LDI R16,0xAA
009D 8308 STD Y+0,R16
009E 2400 CLR R0
009F EAE0 LDI R30,0xA0
00A0 E0F1 LDI R31,1
00A1 E019 LDI R17,0x9
00A2 3AE3 CPI R30,0xA3
00A3 07F1 CPC R31,R17
00A4 F011 BEQ 0x00A7
00A5 9201 ST R0,Z+
00A6 CFFB RJMP 0x00A2
00A7 8300 STD Z+0,R16
00A8 E8EC LDI R30,0x8C
00A9 E0F0 LDI R31,0
00AA E0A0 LDI R26,0
00AB E0B1 LDI R27,1
00AC E011 LDI R17,1
00AD 32EC CPI R30,0x2C
00AE 07F1 CPC R31,R17
00AF F021 BEQ 0x00B4
00B0 95C8 LPM
00B1 9631 ADIW R30,1
00B2 920D ST R0,X+
00B3 CFF9 RJMP 0x00AD
00B4 940E02E4 CALL _main
_exit:
00B6 CFFF RJMP _exit
FILE: E:\ICC128\2008控制台\2008console0TEST\U盘扇区读写\CH375EV0.C
(0001) /* 2004.03.05
(0002) 修改记录:
(0003) 2007.08支持大扇区, 适用于CH375B芯片, 修改了: mInitDisk, mReadSector, mWriteSector, 增加了解: mClearError
(0004) ****************************************
(0005) ** Copyright (C) W.ch 1999-2004 **
(0006) ** Web: http://www.winchiphead.com **
(0007) ****************************************
(0008) ** USB 1.1 Host Examples for CH375 **
(0009) ** KC7.0@MCS-51 **
(0010) ****************************************
(0011) */
(0012) /* CH375作为USB主机接口的程序示例 */
(0013)
(0014) /* MCS-51单片机C语言的示例程序, U盘数据读写 */
(0015)
(0016) #include <iom128v.h>
(0017) #include <string.h>
(0018) #include <stdio.h>
(0019)
(0020) #define MAX_SECTOR_SIZE 2048 /* 以512字节每扇区为主,部分有2K字节每扇区,最大为4K字节 */
(0021)
(0022) /* 定义CH375命令代码及返回状态 */
(0023) #include "CH375INC.H"
(0024) /* CH375特性 */
(0025) #define CH375_BLOCK_SIZE 64 /* CH375 maximum data block size */
(0026)
(0027) /* 以下定义适用于MCS-51单片机,其它单片机参照修改,为了提供C语言的速度需要对本程序进行优化 */
(0028) //#include <reg51.h>
(0029) //unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
(0030) //unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */
(0031) //unsigned char xdata DATA_BUFFER[ MAX_SECTOR_SIZE ] _at_ 0x0000; /* 外部RAM数据缓冲区的起始地址,长度不少于一次读写的数据长度 */
(0032) //sbit CH375_INT_WIRE = 0xB0^2; /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */
(0033)
(0034) unsigned char DATA_BUFFER[ MAX_SECTOR_SIZE ];
(0035)
(0036) #define CH375_INT_WIRE ( PIND & 0x10 ) /* PINB.4, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
(0037)
(0038)
(0039) #define TXB8 0
(0040) #define FE 4
(0041) #define DOR 3
(0042) #define UPE 2
(0043) #define RXC 7
(0044)
(0045) unsigned short BytePerSector; /* 每扇区字节数,扇区大小 */
(0046) unsigned char BlockPerSector; /* 每扇区块数,指CH375读写时的块 BlockPerSector=BytePerSector/CH375_BLOCK_SIZE */
(0047)
(0048) /* 在P1.4连接一个LED用于监控演示程序的进度,低电平LED亮,当U盘插入后亮 */
(0049) //sbit P1_4 = P1^4;
(0050) //#define LED_OUT_ACT( ) { P1_4 = 0; } /* P1.4 低电平驱动LED显示 */
(0051) //#define LED_OUT_INACT( ) { P1_4 = 1; } /* P1.4 低电平驱动LED显示 */
(0052)
(0053) #define P1_4 PORTG ^= 0x10;
(0054) #define LED_OUT_ACT( ) { PORTG &= 0xEF; } /* PORTB.7 低电平驱动LED显示 */
(0055) #define LED_OUT_INACT( ) { PORTG |= 0x10; } /* PORTB.7 低电平驱动LED显示 */
(0056)
(0057) /* 延时2微秒,不精确 */
(0058) void delay2us( )
(0059) {
(0060) unsigned char i;
(0061) for ( i = 10; i != 0; i -- );
_delay2us:
i --> R16
00B7 E00A LDI R16,0xA
00B8 C001 RJMP 0x00BA
00B9 950A DEC R16
00BA 2300 TST R16
00BB F7E9 BNE 0x00B9
00BC 9508 RET
(0062) }
(0063)
(0064) /* 延时1微秒,不精确 */
(0065) void delay1us( )
(0066) {
(0067) unsigned int i;
(0068) for ( i = 5; i != 0; i -- );
_delay1us:
i --> R16
00BD E005 LDI R16,5
00BE E010 LDI R17,0
00BF C002 RJMP 0x00C2
00C0 5001 SUBI R16,1
00C1 4010 SBCI R17,0
00C2 3000 CPI R16,0
00C3 0701 CPC R16,R17
00C4 F7D9 BNE 0x00C0
00C5 9508 RET
_mDelaymS:
i --> R20
cnt --> R16
00C6 940E06FB CALL push_gset1
(0069) }
(0070)
(0071) /* 延时毫秒,不精确 */
(0072) void mDelaymS( unsigned char cnt )
(0073) {
00C8 C008 RJMP 0x00D1
(0074) unsigned int i;
(0075) while ( cnt -- ) {
(0076) for ( i = 2665; i != 0; i -- );
00C9 E649 LDI R20,0x69
00CA E05A LDI R21,0xA
00CB C002 RJMP 0x00CE
00CC 5041 SUBI R20,1
00CD 4050 SBCI R21,0
00CE 3040 CPI R20,0
00CF 0745 CPC R20,R21
00D0 F7D9 BNE 0x00CC
00D1 2E20 MOV R2,R16
00D2 2433 CLR R3
00D3 5001 SUBI R16,1
00D4 2022 TST R2
00D5 F799 BNE 0x00C9
00D6 940E06FE CALL pop_gset1
00D8 9508 RET
_CH375_WR_CMD_PORT:
cmd --> R20
00D9 940E06FB CALL push_gset1
00DB 2F40 MOV R20,R16
(0077) }
(0078) }
(0079)
(0080) /* 基本操作 */
(0081)
(0082) void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */
(0083) delay2us();
00DC DFDA RCALL _delay2us
(0084) //CH375_CMD_PORT=cmd;
(0085) UCSR1B |= 0X01; //将数据第9位置1,表示是地址帧
00DD 9180009A LDS R24,0x9A
00DF 6081 ORI R24,1
00E0 9380009A STS 0x9A,R24
(0086) while(!(UCSR1A&0x20));
00E2 9020009B LDS R2,0x9B
00E4 FE25 SBRS R2,5
00E5 CFFC RJMP 0x00E2
(0087) UDR1=cmd; //写命令
00E6 9340009C STS 0x9C,R20
(0088) mDelaymS( 30 ); /* 延时100毫秒 */
00E8 E10E LDI R16,0x1E
00E9 DFDC RCALL _mDelaymS
(0089) delay2us();
00EA DFCC RCALL _delay2us
00EB 940E06FE CALL pop_gset1
00ED 9508 RET
_CH375_WR_DAT_PORT:
dat --> R20
00EE 940E06FB CALL push_gset1
00F0 2F40 MOV R20,R16
(0090) }
(0091)
(0092) void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */
(0093) //CH375_DAT_PORT=dat;
(0094) UCSR1B &= 0XFE;
00F1 9180009A LDS R24,0x9A
00F3 7F8E ANDI R24,0xFE
00F4 9380009A STS 0x9A,R24
(0095) while(!(UCSR1A&0x20));
00F6 9020009B LDS R2,0x9B
00F8 FE25 SBRS R2,5
00F9 CFFC RJMP 0x00F6
(0096) UDR1= dat;
00FA 9340009C STS 0x9C,R20
(0097) mDelaymS( 30 ); /* 延时100毫秒 */
00FC E10E LDI R16,0x1E
00FD DFC8 RCALL _mDelaymS
(0098) delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */
00FE DFBE RCALL _delay1us
00FF 940E06FE CALL pop_gset1
0101 9508 RET
_CH375_RD_DAT_PORT:
status --> R20
resl --> R20
resh --> R22
0102 940E06F9 CALL push_gset2
(0099) }
(0100)
(0101) unsigned char CH375_RD_DAT_PORT()
(0102) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */
(0103) unsigned char status, resh;
(0104) unsigned char resl;
(0105) delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */
0104 DFB8 RCALL _delay1us
(0106) //while ( !(UCSR1A & (1<<RXC)) ) // 等待接收数据
(0107) //while ( !(UCSR1A & 0x80) ) // 等待接收数据
(0108) status = UCSR1A;// 从缓冲器中获得状态、第9 位及数据
0105 9140009B LDS R20,0x9B
(0109) resh = UCSR1B;
0107 9160009A LDS R22,0x9A
(0110) resl = UDR1;
0109 9140009C LDS R20,0x9C
(0111)
(0112) //if ( status & (1<<FE)|(1<<DOR)|(1<<UPE) ) //如果出错,返回 -1
(0113) //return -1;
(0114) /* 过滤第9 位数据,然后返回*/
(0115) resh = (resh >> 1) & 0x01;
010B 9566 LSR R22
010C 7061 ANDI R22,1
(0116) return ((resh << 8) | resl);
010D 2F16 MOV R17,R22
010E 2F04 MOV R16,R20
010F C002 RJMP 0x0112
(0117) mDelaymS( 6 ); /* 延时100毫秒 */
0110 E006 LDI R16,6
0111 DFB4 RCALL _mDelaymS
0112 940E06E7 CALL pop_gset2
0114 9508 RET
(0118) //return( CH375_DAT_PORT );
(0119) }
(0120)
(0121) /* 等待CH375中断并获取状态 */
(0122) unsigned char mWaitInterrupt()
(0123) { /* 主机端等待操作完成, 返回操作状态 */
_mWaitInterrupt:
0115 C00E RJMP 0x0124
(0124) while( CH375_INT_WIRE ) /* 查询等待CH375操作完成中断(INT#低电平) */
(0125) {
(0126) LED_OUT_ACT( ); /* LED闪烁 */
0116 91800065 LDS R24,0x65
0118 7E8F ANDI R24,0xEF
0119 93800065 STS 0x65,R24
(0127) mDelaymS( 80 );
011B E500 LDI R16,0x50
011C DFA9 RCALL _mDelaymS
(0128) LED_OUT_INACT( );
011D 91800065 LDS R24,0x65
011F 6180 ORI R24,0x10
0120 93800065 STS 0x65,R24
(0129) mDelaymS( 80 );
0122 E500 LDI R16,0x50
0123 DFA2 RCALL _mDelaymS
0124 9984 SBIC 0x10,4
0125 CFF0 RJMP 0x0116
(0130) }
(0131) CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */
0126 E202 LDI R16,0x22
0127 DFB1 RCALL _CH375_WR_CMD_PORT
(0132) return( CH375_RD_DAT_PORT( ) );
0128 DFD9 RCALL _CH375_RD_DAT_PORT
0129 9508 RET
_mCH375Init:
i --> R20
012A 940E06FB CALL push_gset1
012C 9722 SBIW R28,2
(0133) /* c = CH375_RD_DAT_PORT( ); 返回中断状态 */
(0134) /* if ( c == USB_INT_DISCONNECT ) ?; 检测到USB设备断开事件 */
(0135) /* else if ( c == USB_INT_CONNECT ) ?; 检测到USB设备连接事件 */
(0136) }
(0137)
(0138) /* 设置CH375为USB主机方式 */
(0139) unsigned char mCH375Init( )
(0140) {
(0141) unsigned char i;
(0142) #ifdef TEST_CH375_PORT
(0143) unsigned char c;
(0144) CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 测试工作状态 */
(0145) CH375_WR_DAT_PORT( 0x55 ); /* 测试数据 */
(0146) c = CH375_RD_DAT_PORT( ); /* 返回数据应该是测试数据取反 */
(0147) if ( c != 0xaa ) { /* CH375出错 */
(0148) for ( i = 100; i != 0; i -- ) { /* 强制数据同步 */
(0149) CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* CH375执行硬件复位 */
(0150) c = CH375_RD_DAT_PORT( ); /* 延时 */
(0151) ShowText(10,21,"初始化错误!");
(0152) while ( 1 )
(0153) {
(0154) LED_OUT_ACT( ); //LED闪烁
(0155) mDelaymS( 80 );
(0156) LED_OUT_INACT( );
(0157) mDelaymS( 80 );
(0158) }
(0159) }
(0160) mDelaymS( 50 ); /* 延时至少30mS */
(0161) }
(0162) #endif
(0163) CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); /* 设置USB工作模式 */
012D E105 LDI R16,0x15
012E DFAA RCALL _CH375_WR_CMD_PORT
(0164) CH375_WR_DAT_PORT( 6 ); /* 模式代码,自动检测USB设备连接 */
012F E006 LDI R16,6
0130 DFBD RCALL _CH375_WR_DAT_PORT
(0165) for ( i = 0xff; i != 0; i -- ) /* 等待操作成功,通常需要等待10uS-20uS */
0131 EF4F LDI R20,0xFF
0132 C005 RJMP 0x0138
(0166) if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; /* 操作成功 */
0133 DFCE RCALL _CH375_RD_DAT_PORT
0134 3501 CPI R16,0x51
0135 F409 BNE 0x0137
0136 C003 RJMP 0x013A
0137 954A DEC R20
0138 2344 TST R20
0139 F7C9 BNE 0x0133
(0167) if ( i != 0 )
013A 2344 TST R20
013B F011 BEQ 0x013E
(0168) { return( 0 ); } /* 操作成功 */
013C 2700 CLR R16
013D C01B RJMP 0x0159
(0169) else
(0170) {
(0171) ShowText(10,21,"CH375出错!");
013E E784 LDI R24,0x74
013F E091 LDI R25,1
0140 8399 STD Y+1,R25
0141 8388 STD Y+0,R24
0142 E125 LDI R18,0x15
0143 E030 LDI R19,0
0144 E00A LDI R16,0xA
0145 E010 LDI R17,0
0146 940E0548 CALL _ShowText
0148 C00E RJMP 0x0157
(0172) while ( 1 )
(0173) {
(0174) LED_OUT_ACT( ); //LED闪烁
0149 91800065 LDS R24,0x65
014B 7E8F ANDI R24,0xEF
014C 93800065 STS 0x65,R24
(0175) mDelaymS( 80 );
014E E500 LDI R16,0x50
014F DF76 RCALL _mDelaymS
(0176) LED_OUT_INACT( );
0150 91800065 LDS R24,0x65
0152 6180 ORI R24,0x10
0153 93800065 STS 0x65,R24
(0177) mDelaymS( 80 );
0155 E500 LDI R16,0x50
0156 DF6F RCALL _mDelaymS
0157 CFF1 RJMP 0x0149
(0178) }
(0179) return( 0xff );
0158 EF0F LDI R16,0xFF
0159 9622 ADIW R28,2
015A 940E06FE CALL pop_gset1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -