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

📄 avrmain.lst

📁 AVR单片机制作U盘的源码
💻 LST
📖 第 1 页 / 共 2 页
字号:
__start:
__text_start:
    004F E5CF      LDI	R28,0x5F
    0050 E0D4      LDI	R29,4
    0051 BFCD      OUT	0x3D,R28
    0052 BFDE      OUT	0x3E,R29
    0053 51C0      SUBI	R28,0x10
    0054 40D0      SBCI	R29,0
    0055 EA0A      LDI	R16,0xAA
    0056 8308      STD	Y+0,R16
    0057 2400      CLR	R0
    0058 EAEA      LDI	R30,0xAA
    0059 E0F0      LDI	R31,0
    005A E011      LDI	R17,1
    005B 3AEA      CPI	R30,0xAA
    005C 07F1      CPC	R31,R17
    005D F011      BEQ	0x0060
    005E 9201      ST	R0,Z+
    005F CFFB      RJMP	0x005B
    0060 8300      STD	Z+0,R16
    0061 E5E4      LDI	R30,0x54
    0062 E0F0      LDI	R31,0
    0063 E6A0      LDI	R26,0x60
    0064 E0B0      LDI	R27,0
    0065 E010      LDI	R17,0
    0066 39EE      CPI	R30,0x9E
    0067 07F1      CPC	R31,R17
    0068 F021      BEQ	0x006D
    0069 95C8      LPM
    006A 9631      ADIW	R30,1
    006B 920D      ST	R0,X+
    006C CFF9      RJMP	0x0066
    006D 940E0106  CALL	_main
_exit:
    006F CFFF      RJMP	_exit
FILE: E:\电子项目\北极熊模块\例程\AVR\main.c
(0001) /*
(0002) name:main.c
(0003) writer:xiaowu
(0004) date:2009/1/6
(0005) ****************************************
(0006) **  Copyright  (C)  fifth  2008-2009   **
(0007) **  Web:  http://www.chinamcu.com  **
(0008) ****************************************
(0009) **  USB Host File Module      @PB375  **
(0010) **  AVR ATMega32             **
(0011) **  深圳第五元素科技有限公司  **
(0012) **  联系方式:0755-29739852
(0013) **  技术email:xiaowuyeah@163.com  **
(0014) discription:
(0015) 
(0016)  U盘文件读写模块, 连接方式: 软件模拟SPI时序+查询 
(0017)  AVR单片机C语言示例程序 
(0018) 
(0019)  以字节为单位进行U盘文件读写,单片机的RAM只需要几十个字节,不需要外部RAM 
(0020) *********************************************
(0021) */
(0022) 
(0023) 
(0024) #include <iom16v.h>
(0025) #include <macros.h>
(0026) 
(0027) 
(0028) #define PB375_VER				0x30	/* 当前模块版本 */
(0029) 
(0030) /* ********************************************************************************************************************* */
(0031) /* 返回的操作状态码 */
(0032) /* 以下是事件通知状态码,检测到当前U盘已经连接或者已经断开,可以作为最终状态码 */
(0033) #define	ERR_USB_CONNECT			0x15	/* 检测到USB设备连接事件,磁盘已经连接 */
(0034) #define ERR_DISK_DISCON			0x82	/* 检测到USB设备连接事件,磁盘已经断开,或者磁盘尚未连接 */
(0035) /* 代码0XH用于USB设备方式的操作状态代码,由PB375返回,是USB设备模式的中断状态 */
(0036) #define	ERR_USB_DAT_DOWN		0x02	/* USB设备模式: 数据下传成功,上位机下传的数据已经在模块中 */
(0037) #define	ERR_USB_DAT_UP			0x0A	/* USB设备模式: 数据上传成功,模块中的上传数据已经被上位机取走 */
(0038) 
(0039) 
(0040) /* 最终状态码 */
(0041) #define ERR_SUCCESS				0x00	/* 操作成功 */
(0042) #define ERR_PB375_ERROR			0x81	/* PB375硬件错误,可能需要复位PB375 */
(0043) #define ERR_STATUS_ERR			0x83	/* 磁盘状态错误,可能正在连接或者断开磁盘 */
(0044) #define ERR_MBR_ERROR			0x91	/* 磁盘的主引导记录无效,可能磁盘尚未分区或者尚未格式化 */
(0045) #define ERR_TYPE_ERROR			0x92	/* 磁盘分区类型不支持,只支持FAT12/FAT16/BigDOS/FAT32,需要由磁盘管理工具重新分区 */
(0046) #define ERR_BPB_ERROR			0xA1	/* 磁盘尚未格式化,或者参数错误,需要由WINDOWS采用默认参数重新格式化 */
(0047) #define ERR_TOO_LARGE			0xA2	/* 磁盘非正常格式化并且容量大于4GB,或者容量大于250GB,需要由WINDOWS采用默认参数重新格式化 */
(0048) #define ERR_FAT_ERROR			0xA3	/* 磁盘的文件系统不支持,只支持FAT12/FAT16/FAT32,需要由WINDOWS采用默认参数重新格式化 */
(0049) #define ERR_DISK_FULL			0xB1	/* 磁盘文件太满,剩余空间太少或者已经没有,需要磁盘整理 */
(0050) #define ERR_FDT_OVER			0xB2	/* 目录内文件太多,没有空闲的目录项,FAT12/FAT16根目录下的文件数应该少于500个,需要磁盘整理 */
(0051) #define ERR_MISS_DIR			0xB3	/* 指定路径的某个子目录没有找到,可能是目录名称错误 */
(0052) #define ERR_FILE_CLOSE			0xB4	/* 文件已经关闭,如果需要使用,应该重新打开文件 */
(0053) #define ERR_OPEN_DIR			0x41	/* 指定路径的目录被打开 */
(0054) #define ERR_MISS_FILE			0x42	/* 指定路径的文件没有找到,可能是文件名称错误 */
(0055) #define ERR_FOUND_NAME			0x43	/* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中,如果需要使用,应该打开该文件 */
(0056) #define	ERR_USB_DISK_ERR		0x1F	/* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */
(0057) /* 其余错误代码未定义,可以发出命令CMD_QueryStatus查询模块状态并分析 */
(0058) 
(0059) /* ********************************************************************************************************************* */
(0060) /* 磁盘及文件状态,适用于CMD_PARAM.Status.mDiskStatus */
(0061) #define DISK_UNKNOWN			0x00	/* 尚未初始化,未知状态 */
(0062) #define DISK_DISCONNECT			0x01	/* 磁盘没有连接或者已经断开 */
(0063) #define DISK_CONNECT			0x02	/* 磁盘已经连接,但是尚未初始化或者无法识别该磁盘 */
(0064) #define DISK_MOUNTED			0x03	/* 磁盘已经初始化成功,但是尚未分析文件系统或者文件系统不支持 */
(0065) #define DISK_READY				0x10	/* 已经分析磁盘的文件系统并且能够支持 */
(0066) #define DISK_OPEN_ROOT			0x12	/* 已经打开根目录,扇区模式,只能以扇区为单位读写目录的内容,使用后必须关闭,注意FAT12/FAT16根目录是固定长度 */
(0067) #define DISK_OPEN_DIR			0x13	/* 已经打开子目录,扇区模式,只能以扇区为单位读写目录的内容 */
(0068) #define DISK_OPEN_FILE			0x14	/* 已经打开文件,扇区模式,可以以扇区为单位进行数据读写 */
(0069) #define DISK_OPEN_FILE_B		0x15	/* 已经打开文件,字节模式,可以以字节为单位进行数据读写 */
(0070) 
(0071) 
(0072) /* 外部命令码 */
(0073) #define	CMD_DiskQuery			0x61	/* 查询磁盘信息 */
(0074) #define	CMD_FileOpen			0x64	/* 打开文件 */
(0075) #define	CMD_FileCreate			0x65	/* 新建文件并打开,如果文件已经存在则先删除后再新建 */
(0076) #define	CMD_FileErase			0x66	/* 删除文件并关闭 */
(0077) #define	CMD_FileClose			0x67	/* 关闭当前文件 */
(0078) #define	CMD_ByteLocate			0x7A	/* 以字节为单位移动当前文件指针 */
(0079) #define	CMD_ByteRead			0x7B	/* 以字节为单位从当前文件读取数据块 */
(0080) #define	CMD_ByteWrite			0x7C	/* 以字节为单位向当前文件写入数据块 */
(0081) #define	CMD_DiskReady			0x71	/* 查询磁盘是否准备好 */
(0082) 
(0083) 
(0084) /*
(0085)   CS------PB0
(0086)   SCK-----PB1
(0087)   SDI-----PB2
(0088)   SDO-----PB3
(0089) */
(0090) 
(0091) #define  PB375_CS_SET   PORTB |= (1<<PB0)
(0092) #define  PB375_CS_CLR   PORTB &= ~(1<<PB0)
(0093) #define  PB375_SCK_SET    PORTB |= (1<<PB1)
(0094) #define  PB375_SCK_CLR    PORTB &= ~(1<<PB1)
(0095) #define  PB375_SDI_SET    PORTB |= (1<<PB2)
(0096) #define  PB375_SDI_CLR    PORTB &= ~(1<<PB2)
(0097) #define  PB375_SDO    (PINB &(1<<PB3))
(0098) 
(0099) #define  MAXBUFLEN   128
(0100) 
(0101) //发送缓冲区
(0102) unsigned char sendBuff[MAXBUFLEN];
(0103) //接收缓冲区
(0104) unsigned char recBuff[MAXBUFLEN];
(0105) 
(0106) 
(0107) 
(0108) //初始化IO口  设置CS  SCK  SDI 为输出   SDO为输入
(0109) void initPort()
(0110) {
(0111)    PORTB |= 0x07;
_initPort:
    0070 B388      IN	R24,0x18
    0071 6087      ORI	R24,7
    0072 BB88      OUT	0x18,R24
(0112)    DDRB |= 0x07;
    0073 B387      IN	R24,0x17
    0074 6087      ORI	R24,7
    0075 BB87      OUT	0x17,R24
(0113)    DDRB &= 0xF7;
    0076 B387      IN	R24,0x17
    0077 7F87      ANDI	R24,0xF7
    0078 BB87      OUT	0x17,R24
    0079 9508      RET
_mDelaymS:
  i                    --> R20
  c                    --> R10
  j                    --> R22
  delay                --> R16
    007A 940E01CF  CALL	push_gset3
(0114) }
(0115) 
(0116) 
(0117) /* 以毫秒为单位延时,适用于24MHz时钟 */
(0118) void	mDelaymS( unsigned char delay )
(0119) {
(0120) 	unsigned char	i, j, c;
(0121) 	for ( i = delay; i != 0; i -- ) {
    007C 2F40      MOV	R20,R16
    007D C011      RJMP	0x008F
(0122) 		for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */
    007E EC68      LDI	R22,0xC8
    007F C004      RJMP	0x0084
    0080 2D8A      MOV	R24,R10
    0081 5F8D      SUBI	R24,0xFD
    0082 2EA8      MOV	R10,R24
    0083 956A      DEC	R22
    0084 2366      TST	R22
    0085 F7D1      BNE	0x0080
(0123) 		for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */
    0086 EC68      LDI	R22,0xC8
    0087 C004      RJMP	0x008C
    0088 2D8A      MOV	R24,R10
    0089 5F8D      SUBI	R24,0xFD
    008A 2EA8      MOV	R10,R24
    008B 956A      DEC	R22
    008C 2366      TST	R22
    008D F7D1      BNE	0x0088
    008E 954A      DEC	R20
    008F 2344      TST	R20
    0090 F769      BNE	0x007E
    0091 940E01C8  CALL	pop_gset3
    0093 9508      RET
_mSpiExchange:
  d                    --> R20
  i                    --> R22
  c                    --> R16
    0094 940E01D1  CALL	push_gset2
(0124) 	}
(0125) }
(0126) 
(0127) /* 发送一个字节数据给PB375模块,同时接收一个字节,以SPI模式0方式(SPI_SCK默认为0) */
(0128) unsigned char	mSpiExchange( unsigned char c )
(0129) {
(0130) 	unsigned char	i, d;
(0131) 	d = 0;
    0096 2744      CLR	R20
(0132) 	PB375_SCK_CLR;
    0097 98C1      CBI	0x18,1
(0133) 	for ( i = 8; i != 0; i -- ) {  /* 8个位 */
    0098 E068      LDI	R22,0x8
    0099 C00D      RJMP	0x00A7
(0134) 		if ( c & 0x80 ) 
    009A FF07      SBRS	R16,7
    009B C002      RJMP	0x009E
(0135) 		   PB375_SDI_SET;  /* 向模块的SDI输入引脚输出数据 */
    009C 9AC2      SBI	0x18,2
    009D C001      RJMP	0x009F
(0136) 		else 
(0137) 		   PB375_SDI_CLR;
    009E 98C2      CBI	0x18,2
(0138) 		d <<= 1;
    009F 0F44      LSL	R20
(0139) 		if ( PB375_SDO ) 
    00A0 9BB3      SBIS	0x16,3
    00A1 C001      RJMP	0x00A3
(0140) 		 d++;  /* 如果模块的SDO输出引脚为高电平则输入位1 PB375_SDO */
    00A2 9543      INC	R20
(0141) 		PB375_SCK_SET;  /* SPI时钟上升沿,模块接收数据并输出数据 */
    00A3 9AC1      SBI	0x18,1
(0142) 		c <<= 1;
    00A4 0F00      LSL	R16
(0143) 		PB375_SCK_CLR;
    00A5 98C1      CBI	0x18,1
    00A6 956A      DEC	R22
    00A7 2366      TST	R22
    00A8 F789      BNE	0x009A
(0144) 	}
(0145) 	return( d );
    00A9 2F04      MOV	R16,R20
    00AA 940E01C5  CALL	pop_gset2
    00AC 9508      RET
_ExecCommand:
  status               --> R20
  i                    --> R22
  j                    --> R10
  len                  --> R10
  cmd                  --> R20
    00AD 940E01CF  CALL	push_gset3
    00AF 2EA2      MOV	R10,R18
    00B0 2F40      MOV	R20,R16
(0146) }
(0147) 
(0148) 
(0149) 
(0150) /* 执行命令 */
(0151) unsigned char	ExecCommand( unsigned char cmd, unsigned char len )
(0152) {
(0153) 	unsigned char		i, j, status;
(0154) 	PB375_CS_CLR;  /* 产生SPI片选 */
    00B1 98C0      CBI	0x18,0
(0155) 	mSpiExchange( cmd );  /* 写入命令码 */
    00B2 2F04      MOV	R16,R20
    00B3 DFE0      RCALL	_mSpiExchange
(0156) 	mSpiExchange( len );  /* 写入后续参数的长度 */
    00B4 2D0A      MOV	R16,R10
    00B5 DFDE      RCALL	_mSpiExchange
(0157) 	if ( len ) {  /* 有参数 */
    00B6 20AA      TST	R10
    00B7 F069      BEQ	0x00C5
(0158) 		for ( i = 0; i != len; i ++ ) mSpiExchange( sendBuff[ i ] );  /* 依次写入参数 */
    00B8 2766      CLR	R22
    00B9 C009      RJMP	0x00C3
    00BA E28A      LDI	R24,0x2A
    00BB E091      LDI	R25,1
    00BC 2FE6      MOV	R30,R22
    00BD 27FF      CLR	R31
    00BE 0FE8      ADD	R30,R24
    00BF 1FF9      ADC	R31,R25
    00C0 8100      LDD	R16,Z+0
    00C1 DFD2      RCALL	_mSpiExchange
    00C2 9563      INC	R22
    00C3 156A      CP	R22,R10
    00C4 F7A9      BNE	0x00BA
(0159) 	}
(0160) 	PB375_CS_SET;  /* 结束SPI片选 */
    00C5 9AC0      SBI	0x18,0
    00C6 C02C      RJMP	0x00F3
(0161) 	while ( 1 ) {  /* 处理数据传输,直到操作完成才退出 */
(0162) 
(0163) 		PB375_CS_CLR;  /* 产生SPI片选 */
    00C7 98C0      CBI	0x18,0
(0164) 		status = mSpiExchange( 0xFF );  /* 写入0xFF作为无效命令码(不应该写其它值),返回模块操作状态 */
    00C8 EF0F      LDI	R16,0xFF
    00C9 DFCA      RCALL	_mSpiExchange
    00CA 2F40      MOV	R20,R16
(0165) 		if ( status == 0xFF ) {  /* 模块操作尚未完成,也就是INT#没有中断产生 */
    00CB 3F0F      CPI	R16,0xFF
    00CC F421      BNE	0x00D1
(0166) 			PB375_CS_SET;  /* 结束SPI片选 */
    00CD 9AC0      SBI	0x18,0
(0167) 			mDelaymS( 1 );
    00CE E001      LDI	R16,1
    00CF DFAA      RCALL	_mDelaymS
(0168) 			continue;  /* 继续等待模块完成操作 */
    00D0 C022      RJMP	0x00F3
(0169) 		}
(0170) 
(0171) 		if ( status == ERR_SUCCESS )  /* 操作成功 */ 
    00D1 2344      TST	R20
    00D2 F4B9      BNE	0x00EA
(0172) 		{  
(0173) 			i = mSpiExchange( 0 );  /* 返回结果数据的长度,写入0没有意义,可以是任何值 */
    00D3 2700      CLR	R16
    00D4 DFBF      RCALL	_mSpiExchange
    00D5 2F60      MOV	R22,R16
(0174) 			if ( i ) {  /* 有结果数据 */
    00D6 2300      TST	R16
    00D7 F081      BEQ	0x00E8
(0175) 				j = 0;
    00D8 24AA      CLR	R10
(0176) 				do {  /* 使用do+while结构是因为其效率高于for */
(0177) 					recBuff[ j ] = mSpiExchange( 0 );  /* 接收结果数据并保存到参数结构中,写入0没有意义 */
    00D9 2700      CLR	R16
    00DA DFB9      RCALL	_mSpiExchange
    00DB EA8A      LDI	R24,0xAA
    00DC E090      LDI	R25,0
    00DD 2DEA      MOV	R30,R10
    00DE 27FF      CLR	R31
    00DF 0FE8      ADD	R30,R24
    00E0 1FF9      ADC	R31,R25
    00E1 8300      STD	Z+0,R16
(0178) 					j ++;
    00E2 94A3      INC	R10
(0179) 				} while ( -- i );
    00E3 2F86      MOV	R24,R22
    00E4 5081      SUBI	R24,1
    00E5 2F68      MOV	R22,R24
    00E6 2388      TST	R24
    00E7 F789      BNE	0x00D9
(0180) 			}
(0181) 			PB375_CS_SET;  /* 结束SPI片选 */
    00E8 9AC0      SBI	0x18,0
(0182) 			break;  /* 操作成功返回 */
    00E9 C00A      RJMP	0x00F4
(0183) 		}
(0184) 		else   /* 操作失败 */ 
(0185) 		{  
(0186) 			PB375_CS_SET;  /* 结束SPI片选 */
    00EA 9AC0      SBI	0x18,0
(0187) 			if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) mDelaymS( 100 );  /* U盘刚刚连接或者断开,应该延时几十毫秒再操作 */
    00EB 3842      CPI	R20,0x82
    00EC F011      BEQ	0x00EF
    00ED 3145      CPI	R20,0x15
    00EE F429      BNE	0x00F4
    00EF E604      LDI	R16,0x64
    00F0 DF89      RCALL	_mDelaymS
(0188) 			break;  /* 操作失败返回 */
    00F1 C002      RJMP	0x00F4
(0189) 		}

⌨️ 快捷键说明

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