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

📄 usb.c

📁 基于MSP430单片机的U盘读写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 + -