📄 usb.c
字号:
#include "usb.h"
#include "Timer.h"
#include "Serial.h"
#include "String.h"
/*
U盘文件读写模块, 连接方式: 3线制串口+查询
因为使用U盘文件读写模块而不是使用U盘文件级子程序库,
所以占用较少的单片机资源
电路连接方式,只需要连接3根线,使用串口同步码启动操作
单片机 模块
TXD = SIN
RXD = SOUT
STA# 悬空或接高电平
INT# 接地或接低电平
GND = GND
*/
// 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H,
// CH375模块支持的最大值是62,最小值是13
// 为了处理文件目录项,MAX_PATH_LEN至少为36,sizeof( mCmdParam.FileDirInfo )
// 默认情况下该结构将占用60字节的RAM,
// 可以修改MAX_PATH_LEN常量,当修改为32时,只占用32字节的RAM
char mUsbCmd[4];
CMD_PARAM mCmdParam;
//UPAN准备好标志
uchar UsbReady = FALSE;
//超时标志
uchar UsbWaitTimeOut = FALSE;
uchar CmdWaitTimeOut = FALSE;
void Usb_TimeOut()
{
UsbWaitTimeOut = TRUE;
}
void Cmd_TimeOut()
{
CmdWaitTimeOut = TRUE;
}
//执行命令
//输入命令码、参数长度和超时时间
//返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中
uchar ExecCommand( uchar cmd, uchar len)
{
uchar count,status;
UARTReset(UART_USB);
//发送串口同步码通知模块,说明命令码开始发送,请求开始执行命令
//UARTSendChar(UART_USB, SER_SYNC_CODE1 );
//UARTSendChar(UART_USB, SER_SYNC_CODE2 );
//UARTSendChar(UART_USB, cmd ); /* 写入命令码 */
//UARTSendChar(UART_USB, len ); /* 写入后续参数的长度 */
mUsbCmd[0]=SER_SYNC_CODE1;
mUsbCmd[1]=SER_SYNC_CODE2;
mUsbCmd[2]=cmd;
mUsbCmd[3]=len;
UARTnSend(UART_USB, mUsbCmd,4);
if ( len )
{
//发送参数
UARTnSend(UART_USB, (char*)mCmdParam.Other.mBuffer,len );
}
CmdWaitTimeOut = FALSE;
SetTimer(CMD_TIMER,200,Cmd_TimeOut);
// 处理数据传输后,等待模块返回,至少包括返回结果和参数长度
while (CmdWaitTimeOut == FALSE)
{
WATCHDOG_CLEAR; //清除看门狗
if (UARTGetCount(UART_USB) >= 2) break;
}
if ( CmdWaitTimeOut == FALSE)
{ //结果
status = UARTReadChar( UART_USB );
if ( status == ERR_SUCCESS )
{
//返回结果数据的长度
count = UARTReadChar( UART_USB );
//等待结果数据
if (count>0)
{
while (CmdWaitTimeOut == FALSE && UARTGetCount(UART_USB)<count)
{
WATCHDOG_CLEAR; //清除看门狗
Delay(500);//msDelay( 1 );
}
// 有结果数据
if ( CmdWaitTimeOut == FALSE)
UARTnReadChar( UART_USB, mCmdParam.Other.mBuffer, count);
}
}
else if ( status == USB_INT_DISK_READ ||
status == USB_INT_DISK_WRITE ||
status == USB_INT_DISK_RETRY )
{
//正在从U盘读数据块,请求数据读出,正在向U盘写数据块,
//请求数据写入,读写数据块失败重试
//本程序只使用以字节为单位的文件读写子程序,所以正常
//情况下不会收到该状态码,操作失败返回
;
}
else if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT)
{
//U盘刚刚连接或者断开,应该为以后操作延时几十毫秒
WATCHDOG_CLEAR; //清除看门狗
msDelay( 60 );
}
}
KillTimer(CMD_TIMER);
if (CmdWaitTimeOut == TRUE)
{
status = ERR_CMD_TIMEOUT;
}
return( status );
}
void ResetUsb()
{
ExecCommand( CMD_ResetInit, 0 ); /* 复位模块*/
}
uchar Usb_Device()
{
uchar i;
uchar Usb=FALSE;
UsbWaitTimeOut = FALSE;
SetTimer(USB_TIMER,1000,Usb_TimeOut);
while ( UsbWaitTimeOut == FALSE )
{
WATCHDOG_CLEAR; //清除看门狗
//查询当前模块的状态
if ( ExecCommand( CMD_QueryStatus, 0 ) == ERR_SUCCESS);
{
Usb=TRUE;
KillTimer(USB_TIMER);
break; /* U盘已经连接 */
}
}
return Usb;
}
//最大执行10秒
uchar IsUsbReady()
{
uchar usbready = FALSE;
UsbWaitTimeOut = FALSE;
SetTimer(USB_TIMER,500,Usb_TimeOut);
while ( UsbWaitTimeOut == FALSE )
{
WATCHDOG_CLEAR; //清除看门狗
//查询当前模块的状态
if ( ExecCommand( CMD_QueryStatus, 0 ) == ERR_SUCCESS);
{
//看U盘是否连接
if ( mCmdParam.Status.mDiskStatus >= DISK_CONNECT )
{
break; /* U盘已经连接 */
}
WATCHDOG_CLEAR; //清除看门狗
msDelay( 100 ); //200
}
}
// 检查U盘是否准备好,某些U盘必须要执行这一步才能工作
while (UsbWaitTimeOut == FALSE)
{
WATCHDOG_CLEAR; //清除看门狗
msDelay( 100 ); //延时,可选操作,有的USB存储器需要几十毫秒的延时
if ( ExecCommand( CMD_DiskReady, 0 ) == ERR_SUCCESS )
{
usbready = TRUE;
break;
}
}
KillTimer(USB_TIMER);
if (usbready == FALSE)
{ WATCHDOG_CLEAR; //清除看门狗
ExecCommand( CMD_ResetInit, 0 ); /* 复位模块*/
}
return (usbready);
}
/* 大端与小端格式的数据处理 */
ushort SwapUINT16( ushort d )
{
return( ( d << 8 ) & 0xFF00 | ( d >> 8 ) & 0xFF );
}
uchar CreateFile(uchar *fname,uint date, uint time)
{
uchar len;
if (!IsUsbReady()) return FALSE;
// 新文件名,在根目录下
len = strlen((char*)fname) + 1;
memcpy( mCmdParam.Create.mPathName, fname,len);
//新建文件并打开,如果文件已经存在则先删除后再新建
memcpy( mCmdParam.Create.mPathName, fname,len);
ExecCommand( CMD_FileErase, len+1 );
memcpy( mCmdParam.Create.mPathName, fname,len);
len = ExecCommand( CMD_FileCreate, len+1 );
WATCHDOG_CLEAR; //清除看门狗
if (len == ERR_SUCCESS)
{ //修改文件信息
mCmdParam.FileDirInfo.mAccessMode = 0; // 读取文件目录信息
mCmdParam.FileDirInfo.mReserved[0] = 0;
mCmdParam.FileDirInfo.mReserved[1] = 0;
mCmdParam.FileDirInfo.mReserved[2] = 0; // 保留单元
len = ExecCommand( CMD_FileDirInfo, 4 );
WATCHDOG_CLEAR; //清除看门狗
if (len == ERR_SUCCESS)
{ // 存取当前已打开文件的目录信息
// 以下修改文件目录信息中的文件创建时间,
// DIR_CrtTime是创建时间,DIR_WrtTime是修改时间
mCmdParam.FileDirInfo.mDir.DIR_CrtTime = time;
mCmdParam.FileDirInfo.mDir.DIR_CrtDate = date;
mCmdParam.FileDirInfo.mDir.DIR_WrtTime = time;
mCmdParam.FileDirInfo.mDir.DIR_WrtDate = date;
mCmdParam.FileDirInfo.mDir.DIR_LstAccDate = date;
mCmdParam.FileDirInfo.mAccessMode = 0xF0; // 写入/更新文件目录信息
len = ExecCommand( CMD_FileDirInfo, sizeof( mCmdParam.FileDirInfo ));
WATCHDOG_CLEAR; //清除看门狗
}
if (len != ERR_SUCCESS)
{ //成功创建文件后,其他操作不成功,要关闭文件
mCmdParam.Close.mUpdateLen = 0;
ExecCommand( CMD_FileClose, 1 );
WATCHDOG_CLEAR; //清除看门狗
}
}
if (len == ERR_SUCCESS) return TRUE;
ExecCommand( CMD_ResetInit, 0); // 复位模块
return FALSE;
}
uchar OpenFile(uchar *fname)
{
uchar len;
if (!IsUsbReady()) return FALSE;
// 文件名,在根目录下
len = strlen((char*)fname)+1;
WATCHDOG_CLEAR; //清除看门狗
memcpy( mCmdParam.Create.mPathName, fname,len);
//文件并打开,
len = ExecCommand( CMD_FileOpen, len );
if (len == ERR_SUCCESS) return TRUE;
WATCHDOG_CLEAR; //清除看门狗
ExecCommand( CMD_ResetInit, 0 ); /* 复位模块*/
WATCHDOG_CLEAR; //清除看门狗
return FALSE;
}
void CloseFile()
{
UsbWaitTimeOut = FALSE;
SetTimer(USB_TIMER,1000,Usb_TimeOut);
mCmdParam.Close.mUpdateLen = 1;
ExecCommand( CMD_FileClose, 1 );
WATCHDOG_CLEAR; //清除看门狗
while ( UsbWaitTimeOut == FALSE )
{
WATCHDOG_CLEAR; //清除看门狗
if (ExecCommand( CMD_QueryStatus, 0 ) == ERR_SUCCESS )
{
if ( mCmdParam.Status.mDiskStatus <= DISK_READY )
{
WATCHDOG_CLEAR; //清除看门狗
/* U盘已经断开 */
break;
}
}
msDelay( 60 );
}
KillTimer(USB_TIMER);
ExecCommand( CMD_ResetInit, 0 ); /* 复位模块*/
}
uchar WriteFile(uchar *buff,uchar cnt)
{
if (cnt <= sizeof( mCmdParam.ByteWrite.mByteBuffer ))
{
WATCHDOG_CLEAR; //清除看门狗
if (buff!=mCmdParam.ByteWrite.mByteBuffer)
{
memcpy( mCmdParam.ByteWrite.mByteBuffer, buff, cnt );
}
/* 指定本次写入的字节数 */
mCmdParam.ByteWrite.mByteCount = cnt;
/* 以字节为单位向文件写入数据 */
if (ExecCommand( CMD_ByteWrite, 1+cnt )== ERR_SUCCESS )
return TRUE;
else
return FALSE;
}
return FALSE;
}
uchar ReadFile(uchar *buff,uchar cnt)
{
if (cnt <= sizeof( mCmdParam.ByteRead.mByteBuffer ))
{
mCmdParam.ByteRead.mByteCount = cnt;
if (ExecCommand( CMD_ByteRead, 1 )== ERR_SUCCESS )
{ WATCHDOG_CLEAR; //清除看门狗
if (buff!=mCmdParam.ByteRead.mByteBuffer)
{
memcpy(buff, mCmdParam.ByteRead.mByteBuffer, cnt );
}
return TRUE;
}else
return FALSE;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -