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

📄 ch375ev0.s

📁 使用ATMEGA128加CH375对U盘扇区进行读写,本程序在ICCAVR上调试,并在相应硬件电路上调试通过!供参考用
💻 S
📖 第 1 页 / 共 3 页
字号:
	.module CH375EV0.C
	.area text(rom, con, rel)
	.dbfile E:\ICC128\2008控制台\2008console0TEST\U盘扇区读写\CH375EV0.C
	.dbfunc e delay2us _delay2us fV
;              i -> R16
	.even
_delay2us::
	.dbline -1
	.dbline 59
; /* 2004.03.05
;   修改记录:
;     2007.08支持大扇区, 适用于CH375B芯片, 修改了: mInitDisk, mReadSector, mWriteSector, 增加了解: mClearError
; ****************************************
; **  Copyright  (C)  W.ch  1999-2004   **
; **  Web:  http://www.winchiphead.com  **
; ****************************************
; **  USB 1.1 Host Examples for CH375   **
; **  KC7.0@MCS-51                      **
; ****************************************
; */
; /* CH375作为USB主机接口的程序示例 */
; 
; /* MCS-51单片机C语言的示例程序, U盘数据读写 */
; 
; #include <iom128v.h>
; #include <string.h>
; #include <stdio.h>  
; 
; #define		MAX_SECTOR_SIZE		2048	/* 以512字节每扇区为主,部分有2K字节每扇区,最大为4K字节 */
; 
; /* 定义CH375命令代码及返回状态 */
; #include "CH375INC.H"
; /* CH375特性 */
; #define CH375_BLOCK_SIZE		64		/* CH375 maximum data block size */
; 
; /* 以下定义适用于MCS-51单片机,其它单片机参照修改,为了提供C语言的速度需要对本程序进行优化 */
; //#include <reg51.h>
; //unsigned char volatile xdata	CH375_CMD_PORT _at_ 0xBDF1;	/* CH375命令端口的I/O地址 */
; //unsigned char volatile xdata	CH375_DAT_PORT _at_ 0xBCF0;	/* CH375数据端口的I/O地址 */
; //unsigned char xdata				DATA_BUFFER[ MAX_SECTOR_SIZE ]    _at_ 0x0000;	/* 外部RAM数据缓冲区的起始地址,长度不少于一次读写的数据长度 */
; //sbit	CH375_INT_WIRE	=		0xB0^2;	/* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */
; 
; unsigned char  DATA_BUFFER[ MAX_SECTOR_SIZE ];
; 
; #define CH375_INT_WIRE			( PIND & 0x10 )	/* PINB.4, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
; 
; 
; #define TXB8 0
; #define  FE    4
; #define  DOR   3
; #define  UPE   2
; #define  RXC   7
; 
; unsigned short  BytePerSector;		/* 每扇区字节数,扇区大小 */
; unsigned char   BlockPerSector;		/* 每扇区块数,指CH375读写时的块 BlockPerSector=BytePerSector/CH375_BLOCK_SIZE */
; 
; /* 在P1.4连接一个LED用于监控演示程序的进度,低电平LED亮,当U盘插入后亮 */
; //sbit P1_4  = P1^4;
; //#define LED_OUT_ACT( )		{ P1_4 = 0; }	/* P1.4 低电平驱动LED显示 */
; //#define LED_OUT_INACT( )	{ P1_4 = 1; }	/* P1.4 低电平驱动LED显示 */
; 
; #define P1_4    PORTG ^= 0x10;
; #define LED_OUT_ACT( )		{ PORTG &= 0xEF; }	/* PORTB.7 低电平驱动LED显示 */
; #define LED_OUT_INACT( )	{ PORTG |= 0x10; }	/* PORTB.7 低电平驱动LED显示 */
; 
; /* 延时2微秒,不精确 */
; void	delay2us( )
; {
	.dbline 61
	ldi R16,10
	xjmp L5
L2:
	.dbline 61
L3:
	.dbline 61
	dec R16
L5:
	.dbline 61
; 	unsigned char i;
; 	for ( i = 10; i != 0; i -- );
	tst R16
	brne L2
	.dbline -2
L1:
	.dbline 0 ; func end
	ret
	.dbsym r i 16 c
	.dbend
	.dbfunc e delay1us _delay1us fV
;              i -> R16,R17
	.even
_delay1us::
	.dbline -1
	.dbline 66
; }
; 
; /* 延时1微秒,不精确 */
; void	delay1us( )
; {
	.dbline 68
	ldi R16,5
	ldi R17,0
	xjmp L10
L7:
	.dbline 68
L8:
	.dbline 68
	subi R16,1
	sbci R17,0
L10:
	.dbline 68
; 	unsigned int i;
; 	for ( i = 5; i != 0; i -- );
	cpi R16,0
	cpc R16,R17
	brne L7
X0:
	.dbline -2
L6:
	.dbline 0 ; func end
	ret
	.dbsym r i 16 i
	.dbend
	.dbfunc e mDelaymS _mDelaymS fV
;              i -> R20,R21
;            cnt -> R16
	.even
_mDelaymS::
	xcall push_gset1
	.dbline -1
	.dbline 73
; }
; 
; /* 延时毫秒,不精确 */
; void	mDelaymS( unsigned char cnt )
; {
	xjmp L13
L12:
	.dbline 75
; 	unsigned int	i;
; 	while ( cnt -- ) {
	.dbline 76
	ldi R20,2665
	ldi R21,10
	xjmp L18
L15:
	.dbline 76
L16:
	.dbline 76
	subi R20,1
	sbci R21,0
L18:
	.dbline 76
	cpi R20,0
	cpc R20,R21
	brne L15
X1:
	.dbline 77
L13:
	.dbline 75
	mov R2,R16
	clr R3
	subi R16,1
	tst R2
	brne L12
	.dbline -2
L11:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r i 20 i
	.dbsym r cnt 16 c
	.dbend
	.dbfunc e CH375_WR_CMD_PORT _CH375_WR_CMD_PORT fV
;            cmd -> R20
	.even
_CH375_WR_CMD_PORT::
	xcall push_gset1
	mov R20,R16
	.dbline -1
	.dbline 82
; 		for ( i = 2665; i != 0; i -- );
; 	}
; }
; 
; /* 基本操作 */
; 
; void CH375_WR_CMD_PORT( unsigned char cmd ) {  /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */
	.dbline 83
; 	delay2us();
	xcall _delay2us
	.dbline 85
; 	//CH375_CMD_PORT=cmd;
;   UCSR1B |= 0X01;   //将数据第9位置1,表示是地址帧 
	lds R24,154
	ori R24,1
	sts 154,R24
L20:
	.dbline 86
L21:
	.dbline 86
;   while(!(UCSR1A&0x20)); 
	lds R2,155
	sbrs R2,5
	rjmp L20
	.dbline 87
;   UDR1=cmd;      //写命令  
	sts 156,R20
	.dbline 88
;   mDelaymS( 30 );  /* 延时100毫秒 */
	ldi R16,30
	xcall _mDelaymS
	.dbline 89
; 	delay2us();
	xcall _delay2us
	.dbline -2
L19:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r cmd 20 c
	.dbend
	.dbfunc e CH375_WR_DAT_PORT _CH375_WR_DAT_PORT fV
;            dat -> R20
	.even
_CH375_WR_DAT_PORT::
	xcall push_gset1
	mov R20,R16
	.dbline -1
	.dbline 92
; }
; 
; void CH375_WR_DAT_PORT( unsigned char dat ) {  /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */
	.dbline 94
; 	//CH375_DAT_PORT=dat;
;   UCSR1B &= 0XFE; 
	lds R24,154
	andi R24,254
	sts 154,R24
L24:
	.dbline 95
L25:
	.dbline 95
;   while(!(UCSR1A&0x20));
	lds R2,155
	sbrs R2,5
	rjmp L24
	.dbline 96
;   UDR1= dat;
	sts 156,R20
	.dbline 97
;   mDelaymS( 30 );  /* 延时100毫秒 */
	ldi R16,30
	xcall _mDelaymS
	.dbline 98
; 	delay1us();  /* 因为MCS51单片机较慢所以实际上无需延时 */
	xcall _delay1us
	.dbline -2
L23:
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r dat 20 c
	.dbend
	.dbfunc e CH375_RD_DAT_PORT _CH375_RD_DAT_PORT fc
;         status -> R20
;           resl -> R20
;           resh -> R22
	.even
_CH375_RD_DAT_PORT::
	xcall push_gset2
	.dbline -1
	.dbline 102
; }
; 
; unsigned char CH375_RD_DAT_PORT() 
; {  /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */
	.dbline 105
; unsigned char status, resh;
; unsigned char  resl;
; delay1us();  /* 因为MCS51单片机较慢所以实际上无需延时 */
	xcall _delay1us
	.dbline 108
; //while ( !(UCSR1A & (1<<RXC)) )  // 等待接收数据 
; //while ( !(UCSR1A & 0x80) )  // 等待接收数据 
; status = UCSR1A;// 从缓冲器中获得状态、第9 位及数据
	lds R20,155
	.dbline 109
; resh = UCSR1B;
	lds R22,154
	.dbline 110
; resl = UDR1;
	lds R20,156
	.dbline 115
; 
; //if ( status & (1<<FE)|(1<<DOR)|(1<<UPE) ) //如果出错,返回 -1 
; //return -1;
; /* 过滤第9 位数据,然后返回*/
; resh = (resh >> 1) & 0x01;
	lsr R22
	andi R22,1
	.dbline 116
; return ((resh << 8) | resl);
	mov R17,R22
	mov R16,R20
	xjmp L27
X2:
	.dbline 117
; mDelaymS( 6 );  /* 延时100毫秒 */
	ldi R16,6
	xcall _mDelaymS
	.dbline -2
L27:
	xcall pop_gset2
	.dbline 0 ; func end
	ret
	.dbsym r status 20 c
	.dbsym r resl 20 c
	.dbsym r resh 22 c
	.dbend
	.dbfunc e mWaitInterrupt _mWaitInterrupt fc
	.even
_mWaitInterrupt::
	.dbline -1
	.dbline 123
; 	//return( CH375_DAT_PORT );
; }
; 
; /* 等待CH375中断并获取状态 */
; unsigned char mWaitInterrupt()
;  {  /* 主机端等待操作完成, 返回操作状态 */
	xjmp L30
L29:
	.dbline 125
	.dbline 126
	.dbline 126
	lds R24,101
	andi R24,239
	sts 101,R24
	.dbline 126
	.dbline 126
	.dbline 127
	ldi R16,80
	xcall _mDelaymS
	.dbline 128
	.dbline 128
	lds R24,101
	ori R24,16
	sts 101,R24
	.dbline 128
	.dbline 128
	.dbline 129
	ldi R16,80
	xcall _mDelaymS
	.dbline 130
L30:
	.dbline 124
; 	while( CH375_INT_WIRE )  /* 查询等待CH375操作完成中断(INT#低电平) */
	sbic 0x10,4
	rjmp L29
	.dbline 131
; 	 {
; 	     LED_OUT_ACT( );  /* LED闪烁 */
; 		   mDelaymS( 80 );
; 		   LED_OUT_INACT( );
; 		   mDelaymS( 80 );
;    } 
;   CH375_WR_CMD_PORT( CMD_GET_STATUS );  /* 产生操作完成中断, 获取中断状态 */
	ldi R16,34
	xcall _CH375_WR_CMD_PORT
	.dbline 132
; 	return( CH375_RD_DAT_PORT( ) );
	xcall _CH375_RD_DAT_PORT
	.dbline -2
L28:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e mCH375Init _mCH375Init fc
;              i -> R20
	.even
_mCH375Init::
	xcall push_gset1
	sbiw R28,2
	.dbline -1
	.dbline 140
; /*	c = CH375_RD_DAT_PORT( );   返回中断状态 */
; /*	if ( c == USB_INT_DISCONNECT ) ?;   检测到USB设备断开事件 */
; /*	else if ( c == USB_INT_CONNECT ) ?;   检测到USB设备连接事件 */
; }
; 
; /* 设置CH375为USB主机方式 */
; unsigned char	mCH375Init( )
; {
	.dbline 163
; unsigned char	i;
; #ifdef	TEST_CH375_PORT
; 	unsigned char	c;
; 	CH375_WR_CMD_PORT( CMD_CHECK_EXIST );  /* 测试工作状态 */
; 	CH375_WR_DAT_PORT( 0x55 );  /* 测试数据 */
; 	c = CH375_RD_DAT_PORT( );  /* 返回数据应该是测试数据取反 */
; 	if ( c != 0xaa ) {  /* CH375出错 */
; 		for ( i = 100; i != 0; i -- ) {  /* 强制数据同步 */
; 			CH375_WR_CMD_PORT( CMD_RESET_ALL );  /* CH375执行硬件复位 */
; 			c = CH375_RD_DAT_PORT( );  /* 延时 */
; 			ShowText(10,21,"初始化错误!");
; 	    while ( 1 ) 
; 	     {
; 		     LED_OUT_ACT( );  //LED闪烁 
; 		     mDelaymS( 80 );
; 		     LED_OUT_INACT( );
; 		     mDelaymS( 80 );
; 	     }
; 		}
; 		mDelaymS( 50 );  /* 延时至少30mS */
; 	}
; #endif
; 	CH375_WR_CMD_PORT( CMD_SET_USB_MODE );  /* 设置USB工作模式 */
	ldi R16,21
	xcall _CH375_WR_CMD_PORT
	.dbline 164
; 	CH375_WR_DAT_PORT( 6 );  /* 模式代码,自动检测USB设备连接 */
	ldi R16,6
	xcall _CH375_WR_DAT_PORT
	.dbline 165
; 	for ( i = 0xff; i != 0; i -- )  /* 等待操作成功,通常需要等待10uS-20uS */
	ldi R20,255
	xjmp L36
L33:
	.dbline 166
; 		if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break;  /* 操作成功 */
	xcall _CH375_RD_DAT_PORT
	cpi R16,81
	brne L37
	.dbline 166
	xjmp L35
L37:
L34:
	.dbline 165
	dec R20
L36:
	.dbline 165
	tst R20
	brne L33
L35:
	.dbline 167
; 	if ( i != 0 )
	tst R20
	breq L39
	.dbline 168
; 		{ return( 0 ); } /* 操作成功 */
	.dbline 168
	clr R16
	xjmp L32
L39:
	.dbline 170
; 	else
; 		{
	.dbline 171
; 			ShowText(10,21,"CH375出错!");
	ldi R24,<L41
	ldi R25,>L41
	std y+1,R25
	std y+0,R24
	ldi R18,21
	ldi R19,0
	ldi R16,10
	ldi R17,0
	xcall _ShowText
	xjmp L43
L42:
	.dbline 173
	.dbline 174
	.dbline 174
	lds R24,101
	andi R24,239
	sts 101,R24
	.dbline 174
	.dbline 174
	.dbline 175
	ldi R16,80
	xcall _mDelaymS
	.dbline 176
	.dbline 176
	lds R24,101
	ori R24,16
	sts 101,R24
	.dbline 176
	.dbline 176
	.dbline 177
	ldi R16,80
	xcall _mDelaymS
	.dbline 178
L43:
	.dbline 172
; 	    while ( 1 ) 
	xjmp L42
X3:
	.dbline 179
; 	     {
; 		     LED_OUT_ACT( );  //LED闪烁 
; 		     mDelaymS( 80 );
; 		     LED_OUT_INACT( );
; 		     mDelaymS( 80 );
; 	     }
; 			return( 0xff );
	ldi R16,255
	.dbline -2
L32:
	adiw R28,2
	xcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r i 20 c
	.dbend
	.dbfunc e mInitDisk _mInitDisk fc
;     mIntStatus -> R20
;              i -> R20
	.even
_mInitDisk::
	xcall push_gset1
	sbiw R28,2
	.dbline -1
	.dbline 185
; 	  } /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */
; }
; 
; /* 初始化磁盘 */
; unsigned char	mInitDisk( )
; {
	.dbline 187
; 	unsigned char mIntStatus, i;
; 	CH375_WR_CMD_PORT( CMD_GET_STATUS );  /* 产生操作完成中断, 获取中断状态 */
	ldi R16,34
	xcall _CH375_WR_CMD_PORT
	.dbline 188
; 	mIntStatus = CH375_RD_DAT_PORT( );  //获取中断状态
	xcall _CH375_RD_DAT_PORT
	mov R20,R16
	.dbline 189
; 	if ( mIntStatus == USB_INT_DISCONNECT ) return( mIntStatus );  /* USB设备断开 */
	cpi R16,22
	brne L46
	.dbline 189
	xjmp L45
L46:
	.dbline 190
; 	CH375_WR_CMD_PORT( CMD_DISK_INIT );  /* 初始化USB存储器 */
	ldi R16,81
	xcall _CH375_WR_CMD_PORT
	.dbline 191
; 	mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
	xcall _mWaitInterrupt
	mov R20,R16
	.dbline 192
; 	if ( mIntStatus != USB_INT_SUCCESS ) return( mIntStatus );  /* 出现错误 */
	cpi R16,20
	breq L48
	.dbline 192
	xjmp L45
L48:
	.dbline 193
; 	CH375_WR_CMD_PORT( CMD_DISK_SIZE );  /* 获取USB存储器的容量 */
	ldi R16,83
	xcall _CH375_WR_CMD_PORT
	.dbline 194
; 	mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
	xcall _mWaitInterrupt
	mov R20,R16
	.dbline 195
; 	if ( mIntStatus != USB_INT_SUCCESS ) 
	cpi R16,20
	breq L50
	.dbline 196
; 		{  /* 出错重试 */
	.dbline 197
; 		  mDelaymS( 200 );
	ldi R16,200
	xcall _mDelaymS
	.dbline 198
; 		  CH375_WR_CMD_PORT( CMD_DISK_SIZE );  /* 获取USB存储器的容量 */
	ldi R16,83
	xcall _CH375_WR_CMD_PORT
	.dbline 199
; 		  mIntStatus = mWaitInterrupt( );  /* 等待中断并获取状态 */
	xcall _mWaitInterrupt
	mov R20,R16
	.dbline 200
; 	  }
L50:
	.dbline 201
; 	if ( mIntStatus != USB_INT_SUCCESS ) return( mIntStatus );  /* 出现错误 */
	cpi R20,20
	breq L52
	.dbline 201
	mov R16,R20
	xjmp L45
L52:
	.dbline 204
; 
; /* 可以由CMD_RD_USB_DATA命令将容量数据读出,分析每扇区字节数 */
; 	CH375_WR_CMD_PORT( CMD_RD_USB_DATA );  /* 从CH375缓冲区读取数据块 */
	ldi R16,40
	xcall _CH375_WR_CMD_PORT
	.dbline 205
; 	i = CH375_RD_DAT_PORT( );  /* 后续数据的长度 */
	xcall _CH375_RD_DAT_PORT
	mov R20,R16
	.dbline 206
; 	if ( i != 8 ) return( USB_INT_DISK_ERR );  /* 异常 */
	cpi R16,8
	breq L54
	.dbline 206
	ldi R16,31
	xjmp L45
L54:
	.dbline 207
; 	for ( i = 0; i != 8; i ++ )
	clr R20
	xjmp L59
L56:
	.dbline 208
	.dbline 209
	xcall _CH375_RD_DAT_PORT
	ldi R24,<_DATA_BUFFER
	ldi R25,>_DATA_BUFFER
	mov R30,R20
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R16
	.dbline 210
L57:
	.dbline 207
	inc R20
L59:
	.dbline 207
	cpi R20,8
	brne L56
	.dbline 211
; 	 {  /* 根据长度读取数据 */
; 		  DATA_BUFFER[ i ] = CH375_RD_DAT_PORT( );  /* 读出数据并保存 */
; 	 }
; 	i = DATA_BUFFER[ 6 ];  /* U盘容量数据中的每扇区字节数,大端格式 */
	lds R20,_DATA_BUFFER+6
	.dbline 213
; 

⌨️ 快捷键说明

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