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

📄 urw.lst

📁 使用ATMEGA128加CH375对U盘扇区进行读写,本程序在ICCAVR上调试,并在相应硬件电路上调试通过!供参考用
💻 LST
📖 第 1 页 / 共 5 页
字号:
__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 + -