📄 udisk.s
字号:
.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 + -