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

📄 udisk.s

📁 AVR单片机平台Atmega32+CH375A芯片读写U盘代码
💻 S
📖 第 1 页 / 共 5 页
字号:
	.module udisk.c
	.area text(rom, con, rel)
	.dbfile E:\xm\jxf\u盘读写模块\code\udisk_test0827/CH375HFB.h
	.dbfunc e CH375FileRead _CH375FileRead fc
	.even
_CH375FileRead::
	.dbline -1
	.dbline 673
; //此版本为测试375自带模块函数设计,
; //测试读取文件,新建文件,写入文件,修改属性
; 
; 
; #include <iom32v.h>
; #include "macros.h"
; #include <string.h>
; #include <stdio.h>
; #include "twi.h"
; #include "UART.h"
; #include "udisk.h"
; 
; 
; #define uchar unsigned char
; #define UINT8 unsigned char
; #define ulong unsigned long
; #define uint  unsigned int
; //端口的定义,用I/O模拟总线方式
; //LED定义
; #define LEDPORT PORTD
; #define ALLLED  0xF0
; #define LEDRD   PD7
; #define LEDWR   PD6
; #define LEDBUSY PD5
; #define LEDERR  PD4
; //按键定义
; #define KEYPORT PIND
; #define S1      PD3
; //模拟总线定义
; #define DATAOUT PORTA                    //D0~D7在PA口
; #define DATAIN  PINA
; 
; #define CTRLBUS PORTC
; #define CTRLWR  PC7                      //WR信号线在PC7
; #define CTRLRD  PC6                      //RD信号线在PC6
; 
; #define ADDRBUS PORTB
; #define A0      PB0                      //A0地址线在PB0
; 
; #define CSPORT PORTB
; #define CS      PB1                      //片选线在PB1
; 
; //一些总线控制宏定义
; #define WRCTRL  CTRLBUS&= ~BIT(CTRLWR)   //写总线置低
; #define RDCTRL  CTRLBUS&= ~BIT(CTRLRD)   //读总线置低
; #define CLRCTRL CTRLBUS|= (BIT(CTRLWR)|BIT(CTRLRD))  //读写总线均置高
; #define MCMD  ADDRBUS|= BIT(A0)                       //指令的读写模式,A0置高
; #define MDATA  ADDRBUS&= ~BIT(A0)                       //数据的读写模式,A0置低
; #define CSEN    ADDRBUS&= ~BIT(CS)                   //CS使能置低
; #define CSDIS   ADDRBUS|= BIT(CS)                    //CS不使能置高
; #define DATADIRI      DDRA=0                               //数据输入方式把DDRA置0
; #define DATADIRO     DDRA=0xff                            //数据输出方式把DDAR置0xff
; 
; 
; 
; //点灯的宏定义
; 
; #define LIGHT_WR    LEDPORT&= ~BIT(LEDWR)
; #define OFF_WR      LEDPORT|= BIT(LEDWR)
; #define LIGHT_RD    LEDPORT&= ~BIT(LEDRD)
; #define OFF_RD      LEDPORT|= BIT(LEDRD)
; #define LIGHT_BUSY  LEDPORT&= ~BIT(LEDBUSY)
; #define OFF_BUSY    LEDPORT|= BIT(LEDBUSY)
; #define LIGHT_ERR   LEDPORT&= ~BIT(LEDERR)
; #define OFF_ERR     LEDPORT|= BIT(LEDERR)
; 
; #define LIGHT_ALL   LEDPORT&= ~ALLLED
; #define OFF_ALL LEDPORT|= ALLLED
; 
; #define I2C_SEND_READY DataPrepared = 0xff
; #define CLR_COMFLAGE I2cComStatus = 0
; 
; #define FILE_ATTRI_BYTES 9
; 
; 
; 
; #define RETURN_SUCCESS nComBuff.AckData.Ack = A_SUCCESS
; 
; //决定是否使能应答
; #define OPEN_ACK TWCR|= 1<<TWEA
; #define CLOSE_ACK  TWCR&= ~(1<<TWEA)
; 
; 
; 
; /* 以下定义的详细说明请看CH375HF9.H文件 */
; #define LIB_CFG_FILE_IO			1		/* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */
; #define LIB_CFG_INT_EN			0		/* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */
; 
; /* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */
; #define FILE_DATA_BUF_LEN		512	/* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */
; 
; #define CH375_INT_WIRE			( PIND & 0x04 )	/* PIND.2, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
; 
; #define NO_DEFAULT_CH375_F_ENUM		1		/* 未调用CH375FileEnumer程序故禁止以节约代码 */
; //#define NO_DEFAULT_CH375_F_QUERY	1		/* 未调用CH375FileQuery程序故禁止以节约代码 */
; #define LIB_CFG_FILE_IO_DEFAULT
; #define NO_DEFAULT_DELAY_100US                 //用自己定义的延时100us函数实现延时
; #define NO_DEFAULT_DELAY_WRITE                 //用自己定义的延时函数实现写入后的延时
; #include "CH375HFB.h"
; 
; 
; 
; void init_devices(void );
; void mDelaymS( UINT8 ms );
; void xDelay100uS( void );
; void xDelayAfterWrite( void );
; 
; void twi_process(void);
; void transmit_process(void);
; void receive_process(void);
; void twisentbyte(unsigned char SentData);
; void delay_us(void);
; void xWriteCH375Cmd( UINT8 mCmd );
; void xWriteCH375Data( UINT8 mData );
; UINT8 xReadCH375Data( void );
; void timer0_ovf_isr(void);
; void timer0_init(void);
; void twi_isr(void);
; void variable(void);
; void RecieveFrameProcess( void );
; void ModuleSetOffset(uchar ModeLocate);
; 
; COM_BUFF nComBuff;
; uchar  ys20ms;
; 
; uchar B_status;    //模块大状态变量
; uchar temp[10];
; 
; uchar OperReturn;
; uchar DataPrepared;       //数据是否准备好变量
; uchar rdcount;
; 
; extern uint *SlaveSendLength;
; extern uchar I2cComStatus;     //通信状态变量
; 
; /*Bit7        Bit6        Bit5    Bit4 Bit3 Bit2 Bit1 Bit0
;   I2CRecCom   I2C_sendCom  
;   I2C_RecCom--Recieve complete
;   I2C_SendCom--Transmmit complete
;  **********************************************************/
; extern unsigned char *I2cReceiveData;    //I2c数据接收缓冲地址 
; extern unsigned char *I2cSendData;      //I2c数据发送缓冲地址
; 			
; extern unsigned char *UartRx;          //存放接收数据的指针
; extern unsigned int *RxLength;         //数据接收长度地址指针
; extern unsigned char UartState; 	  //UART状态变量		
; 			
; 				
; 			
; 
; void main(void)
; {
; 	UINT8 i;
; 	uint j=200;
; begin: variable( );              //变量的初始化
;     i2cSetBitrate(100);
;     i2cInit();
;     i2cSetLocalDeviceAddr(0x60,1);
; 	init_USART(0);
;     init_devices( );
;     /*测试延时时间是否充足*/
; 	xDelay100uS( );
; 	delay_us( );
;     put_s("Start\n");
;     for(i=0;i<3;i++)           //闪烁三次
; 	{
; 		LIGHT_ALL;
;         ys20ms=20;
; 		while(ys20ms);
; 		OFF_ALL;
; 		ys20ms=20;
; 		while(ys20ms);
; 		
; 	}
; 
; 	OperReturn = CH375LibInit( );  // 初始化CH375程序库和CH375芯片,操作成功返回0 
; 	if(OperReturn)
; 	{
; 		goto begin;                 //重新启动程序
; 	}
; 
; 	while( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( );  // 查询CH375中断并更新中断状态,等待U盘插入 
; 	
; 	mDelaymS( 200 );  //延时,可选操作,有的USB存储器需要几十毫秒的延时 
; 
; /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */
; 	for ( i = 0; i < 10; i ++ ) 
; 	{                                       /* 有的U盘总是返回未准备好,不过可以被忽略 */
; 		mDelaymS( 100 );
; 		if ( CH375DiskReady( ) == ERR_SUCCESS ) 
;         {
;             B_status = S_READY;
;             break;  /* 查询磁盘是否准备好 */
;         }
;         else
;         {
;             B_status = S_NOTREADY;
;         }
; 	}
;     put_s("Prepared\n");
; 
; 	while(1)
; 	{
; 
; 		if(I2cComStatus & BIT(I2C_RECCOM))
; 		{
;             CLOSE_ACK;                //停止应答
;             LIGHT_BUSY;
;             puts("Command received\n");
;             put_bytes(&nComBuff.ReqData.Com,1);
; 			I2cComStatus&= ~BIT(I2C_RECCOM);
;             if(nComBuff.ReqData.Com == R_RESET)
;             {
;                 nComBuff.ReqData.Com = 0;
;                 goto begin;
;             }
; 			RecieveFrameProcess( );
;             DataPrepared = 0xff;
; 		}
; 		if(DataPrepared)
; 		{
;             DataPrepared = 0;
;             put_bytes((char* )&nComBuff,MAX_BYTE_TRANS+5);
;             OPEN_ACK;                 //进行应答
;             OFF_BUSY;
; 		}
;         
; 	}
;      	
; }
; 	
; 
; 
; /* 延时指定毫秒时间,根据单片机主频调整,不精确 */
; void	mDelaymS( UINT8 ms )
; {
; 	UINT16	i;
; 	while ( ms -- ) for ( i = 1325; i != 0; i -- );
; }
; 
; 
; /******************************************************************************
; 延时1uS
; *******************************************************************************/
; 	
; void delay_us(void)
;     {
; 	   uchar j;
; 	   j++;
; 	}
; /*****************************************************************************
; /函数库要调用的100us延时
; *****************************************************************************/
; void xDelay100uS( void )				/* 延时100uS */
; {
; 	UINT16	count;
; 	for ( count = 150; count != 0; count -- ); 
; }
; /****************************************************************************
; /函数库要调用的写入后延时
; ****************************************************************************/
; void xDelayAfterWrite( void )			/* 写操作后延时 */
; {
; 	UINT16	count;
; 	for ( count = 300; count != 0; count -- );  /* 延时200uS左右 */
; }
; /**************************************************************************
; 外部定义的被CH375程序库调用的子程序,向CH375写命令,最小周期为4uS,
; 否则之前之后各延时2uS 
; ***************************************************************************/
; void xWriteCH375Cmd( UINT8 mCmd )	
; {
; 	delay_us();
; 	delay_us();
; 	MCMD;                               //A0置高
; 	DATADIRO;                            //数据方向为输出
; 	DATAOUT=mCmd;                        //数据输出
; 	CSEN;                                //使能
; 	WRCTRL;                              //写信号
; 	WRCTRL;                              //延时
; 	CLRCTRL;                            //关写信号
; 	CSDIS;                              //使能禁止
; 	delay_us();
; 	delay_us();
; }
; 
; /**************************************************************************
; 外部定义的被CH375程序库调用的子程序,向CH375写数据,最小周期为1.5uS,
; 否则之后延时1.5uS
; ***************************************************************************/
; void xWriteCH375Data( UINT8 mData )
; {
; 	MDATA;                               //A0置高
; 	DATADIRO;                            //数据方向为输出
; 	DATAOUT=mData;                        //数据输出
; 	CSEN;                                //使能
; 	WRCTRL;                              //写信号
; 	WRCTRL;                               //延时
; 	CLRCTRL;                            //关写信号
; 	CSDIS;                              //使能禁止
; 	delay_us();
; 	delay_us();	 
; 
; }
; /**************************************************************************
; 外部定义的被CH375程序库调用的子程序,从CH375读数据,最小周期为1.5uS,
; 否则之前延时1.5uS
; ***************************************************************************/
; UINT8 xReadCH375Data( void )
; {
; 	UINT8 inData;
; 	delay_us();
; 	MDATA;
; 	DATADIRI;
; 	CSEN;
; 	RDCTRL;
; 	RDCTRL;
; 	inData=DATAIN;
; 	CLRCTRL;
; 	CSDIS;
; 	return(inData);
; }
; 
; /****************************************************************************
; /动作执行完,返回结果,OperReturn为0则返回A_SUCCESS,非零则返回OperReturn值
; ****************************************************************************/
; void ReturnProResult( void )
; {
; 	if(OperReturn)
; 	{
; 		nComBuff.AckData.Ack = OperReturn;
; 	}
; 	else
; 	{
; 		nComBuff.AckData.Ack = A_SUCCESS;
; 	}
; }
; 
; /************************************************************************/
; /* 发送错误码。自动组帧。
; 入口参数:ErrorCode                                                     */
; /************************************************************************/
; void ReturnErrorCode(uchar ErrorCode)
; {
; 	I2C_SEND_READY;
;     nComBuff.AckData.Ack = ErrorCode;
; 	nComBuff.AckData.FrameLen = 3;
; }
; /************************************************************************/
; /* 复制数据
; 入口参数:
; uchar destination *:目的地址
; uchar source *:源地址
; uint number:  字节数                                                     */
; /************************************************************************/
; void CopyBytes(uchar* destination,uchar* source,uint number)
; {
; 	uint i;
; 	for(i=0;i<number;i++)
; 	{
; 		*(destination+i) = *(source+i);
; 	}
; }
; 
; /************************************************************************/
; /* 新建文件(文件夹)函数
; 入口参数:directory,0=新建文件,!0=新建文件夹                          */
; /************************************************************************/
; void ModuleNewFile(uchar directory)
; {
; 	nComBuff.ReqData.VeryData.FileName[MAX_PATH_LEN-1]=0;  //确保最后一个是“0”,作为字符串的尾部
; 	strcpy((char *)mCmdParam.Create.mPathName,(char *)nComBuff.ReqData.VeryData.FileName);
; 	OperReturn = CH375FileCreate( );    //新建文件
; 	
; 	if(OperReturn)
; 	{
; 		ReturnErrorCode(OperReturn);
; 		B_status = S_READY;
; 	}
; 	else if(directory)
; 	{
; 		mCmdParam.Modify.mFileAttr = ATTR_DIRECTORY;
; 		mCmdParam.Modify.mFileDate = 0xffff;
; 		mCmdParam.Modify.mFileSize = 0xffffffff;
; 		mCmdParam.Modify.mFileTime = 0xffff;
; 		OperReturn = CH375FileModify();
; 		directory = 0;                         //把此值清零防止再进入此分支
; 		if(OperReturn)
; 		{
; 			ReturnErrorCode(OperReturn);
; 			B_status = S_READY;
; 		}
; 		else
; 		{
; 			mCmdParam.Close.mUpdateLen = 1;                    //自动更新文件长度
; 			OperReturn = CH375FileClose( );
; 			if(OperReturn)
; 			{
; 				ReturnErrorCode(OperReturn);
;                 B_status = S_READY;
; 			}
; 			else
; 			{
; 				ReturnErrorCode(A_SUCCESS);
; 				B_status = S_READY;
; 			}
; 					
; 		}
; 	}
; 	else
; 	{
; 
; 		ReturnErrorCode(A_SUCCESS);
; 		B_status=S_OPEN;
; 	}
; 
; }
; 
; /************************************************************************/
; /* 如果优盘的状态是准备好,但未读写,进入的分支                         */
; /************************************************************************/
; void StatusReady(void)
; {
; 	switch(nComBuff.ReqData.Com)
; 	{
; 		case R_OPEN_FILE:
; 			nComBuff.ReqData.VeryData.FileName[MAX_PATH_LEN-1]=0;  //确保最后一个是“0”,作为字符串的尾部
; 			strcpy((char *)mCmdParam.Open.mPathName,(char *)nComBuff.ReqData.VeryData.FileName);
; 			OperReturn = CH375FileOpen( );
; 			if(OperReturn)
; 			{
; 				ReturnErrorCode(OperReturn);
; 				B_status = S_READY;				  
; 			}
; 			else
; 			{
; 				ReturnErrorCode(A_SUCCESS);
; 				B_status=S_OPEN;
; 			}					
; 
; 			break;
; 		case R_NEW_FILE:
; 			ModuleNewFile(0);                          //新建文件
; 			break;
; 		case R_DEL_FILE:
; 			nComBuff.ReqData.VeryData.FileName[MAX_PATH_LEN-1]=0;  //确保最后一个是“0”,作为字符串的尾部
; 			strcpy((char *)mCmdParam.Create.mPathName,(char *)nComBuff.ReqData.VeryData.FileName);
; 			OperReturn = CH375FileErase( );  //删除文件并关闭
; 			ReturnErrorCode(OperReturn);
; 			B_status = S_READY;
; 			break;
; 		case R_NEW_DIR:
; 			ModuleNewFile(0xff);                      //新建文件夹
; 			break;			
; 		default:
; 			ReturnErrorCode(A_NOTOPEN);
; 			B_status = S_READY;
; 			break;
;       }
; }
; 
; /************************************************************************/
; /* 模块按字节读取文件
; 需要准备的有: nComBuff.ReqData.VeryData.ReadBytes,字节数
; 出口数据: nComBuff.AckData.VeryData.ReadDataVer.ReadBytes,读出的实际字节数
;                                                                         */
; /************************************************************************/
; void ModuleByteRead(void)
; {
;     rdcount=nComBuff.ReqData.VeryData.ReadBytes;
;     if(rdcount)
;     {
; 		if(rdcount>MAX_BYTE_IO)
;       	{
; 			mCmdParam.ByteRead.mByteCount = MAX_BYTE_IO;    //读的字节数就是最大值
; 			goto readbyte1;
; 		}
; 		else
; 		{
; 			mCmdParam.ByteRead.mByteCount = rdcount;
; readbyte1:			LIGHT_RD;                                        //读指示灯打开
; 			OperReturn = CH375ByteRead();
; 			OFF_RD;                                          //读指示灯熄灭
; 			if(OperReturn)
; 			{
; 				ReturnErrorCode(OperReturn);
; 			}
; 			else
; 			{
; 			    RETURN_SUCCESS;                             //返回成功
; 				CopyBytes(nComBuff.AckData.VeryData.ReadDataVer.DataBuff,  //目的地址
; 					mCmdParam.ByteRead.mByteBuffer,       //源地址
; 					mCmdParam.ByteRead.mByteCount);    //实际读出的字节数
;                 nComBuff.AckData.VeryData.ReadDataVer.ReadBytes = mCmdParam.ByteRead.mByteCount;
;                 nComBuff.AckData.FrameLen = nComBuff.AckData.VeryData.ReadDataVer.ReadBytes+5;  //整个帧的长度
; 				I2C_SEND_READY;                            //准备发送
; 			}
; 
; 		}
; 	}
; 	B_status = S_OPEN;
; }
; 
; /************************************************************************/
; /* 模块对文件属性的读取                                                 */
; /************************************************************************/
; void ModuleAttrRead(void)
; {
; 	LIGHT_RD;                                           //亮灯
; 	OperReturn = CH375FileQuery( );
; 	OFF_RD;                                             //灭灯
; 	if(OperReturn)
; 	{
; 		ReturnErrorCode(OperReturn);
; 	}
; 	else
; 	{
; 		nComBuff.AckData.FrameLen = FILE_ATTRI_BYTES+3;
; 		RETURN_SUCCESS;
; 		CopyBytes((uchar *) &nComBuff.AckData.VeryData.ReadFileAttrVer,
; 			(uchar *) &mCmdParam.Modify,
; 			FILE_ATTRI_BYTES);
; 		I2C_SEND_READY;
; 	}
; 	B_status = S_OPEN;
; }
; 
; /************************************************************************/
; /* 模块对文件按字节方式写入                                             */
; /************************************************************************/
; void ModuleByteWrite(void)
; {
; 	rdcount = nComBuff.ReqData.VeryData.WriteDataVer.Bytes;
; 	if(rdcount)
; 	{
; 		if(rdcount>MAX_BYTE_IO)
; 		{
; 			mCmdParam.ByteWrite.mByteCount = MAX_BYTE_IO;
; 			goto writebyte1;
; 		}
; 		else
; 		{
; 			mCmdParam.ByteWrite.mByteCount = rdcount;
; writebyte1:			LIGHT_WR;
; 			CopyBytes(mCmdParam.ByteWrite.mByteBuffer,                //将请求帧的数据内容拷贝到读写结构体当中
; 				nComBuff.ReqData.VeryData.WriteDataVer.DataBuff,
; 				mCmdParam.ByteWrite.mByteCount);
; 			OperReturn = CH375ByteWrite( );
; 			OFF_WR;
; 			if(OperReturn)
; 			{
; 				ReturnErrorCode(OperReturn);
; 			}
; 			else
; 			{
;                 nComBuff.AckData.VeryData.RealWriteByte = mCmdParam.ByteWrite.mByteCount;
; 			    RETURN_SUCCESS;
;                 nComBuff.AckData.FrameLen = nComBuff.AckData.VeryData.RealWriteByte + 5;  //整个帧的长度
; 			}
; 		}
; 	}
; 	B_status = S_OPEN;
; }
; 
; /************************************************************************/
; /* 模块的扇区读取函数
; 在mCmdParam.ReadX.mSectorCount中放入读取的扇区数目
; 在mCmdParam.ReadX.mDataBuffer中                                                                     */
; /************************************************************************/
; void ModuleSectorRead(void)
; {
;     if(CH375DiskStatus == DISK_OPEN_FILE)
;     {
;         mCmdParam.ReadX.mSectorCount = 1;
;         LIGHT_RD;
;         OperReturn = CH375FileRead();
;         OFF_RD;
;         if(OperReturn)
;         {
;             ReturnErrorCode(OperReturn);
;         }

⌨️ 快捷键说明

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