?? ch375hft.c
字號:
/* 2004.06.05
****************************************
** Copyright (C) W.ch 1999-2004 **
** Web: http://www.winchiphead.com **
****************************************
** USB Host File Interface for CH375 **
** TC2.0@PC, KC7.0@MCS51 **
****************************************
*/
/* CH375 主機文件系統接口 */
/* 支持: FAT12/FAT16/FAT32 */
/* MCS-51單片機C語言的U盤文件讀寫示例程序, 適用于89C52或者更大程序空間的單片機 */
/* 本程序用于演示檢查U盤是否寫保護,演示模擬計算機端的安全移除,也可以參考用于自行處理其它命令 */
/* CH375的INT#引腳采用查詢方式處理, 適用于所有MCS51單片機, 本例適用于V2.4及以上版本的CH375子程序庫, 適用于CH375A芯片 */
/* C51 CH375HFT.C */
/* LX51 CH375HFT.OBJ , CH375HF4.LIB 如果將CH375HF4換成CH375HF6就可以支持FAT32 */
/* OHX51 CH375HFT */
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include <intrins.h>
/* 以下定義的詳細說明請看CH375HF6.H文件 */
#define MAX_BYTE_IO 48 /* 以字節為單位單次讀寫文件時的最大長度,默認值是29,值大則占用內存多,值小則超過該長度必須分多次讀寫 */
#define LIB_CFG_DISK_IO 1 /* 磁盤讀寫的數據的復制方式,1為"單DPTR復制",2為"雙DPTR復制",3為"單DPTR和P2+R0復制" */
#define LIB_CFG_FILE_IO 1 /* 文件讀寫的數據的復制方式,0為"外部子程序",1為"單DPTR復制",2為"雙DPTR復制",3為"單DPTR和P2+R0復制" */
#define LIB_CFG_INT_EN 0 /* CH375的INT#引腳連接方式,0為"查詢方式",1為"中斷方式" */
/*#define LIB_CFG_FILE_IO_DEFAULT 1*/ /* 使用CH375HF6.H提供的默認"外部子程序" */
/*#define LIB_CFG_UPD_SIZE 1*/ /* 在添加數據后是否自動更新文件長度: 0為"不更新",1為"自動更新" */
/* 默認情況下,如果扇區數/字節數不為0那么CH375FileWrite/CH375ByteWrite只負責寫入數據而不修改文件長度,
如果需要每次寫完數據后會自動修改/更新文件長度,那么可以使全局變量CH375LibConfig的位4為1,
如果長時間不寫入數據則應該更新文件長度,防止突然斷電后前面寫入的數據與文件長度不相符,
如果確定不會突然斷電或者后面很快有數據不斷寫入則不必更新文件長度,可以提高速度并減少U盤損耗(U盤內部的內存壽命有限,不宜頻繁改寫) */
#define CH375_CMD_PORT_ADDR 0xBDF1 /* CH375命令端口的I/O地址 */
#define CH375_DAT_PORT_ADDR 0xBCF0 /* CH375數據端口的I/O地址 */
/* 62256提供的32KB的RAM分為兩部分: 0000H-01FFH為磁盤讀寫緩沖區, 0200H-7FFFH為文件數據緩沖區 */
#define DISK_BASE_BUF_ADDR 0x0000 /* 外部RAM的磁盤數據緩沖區的起始地址,從該單元開始的緩沖區長度為SECTOR_SIZE */
#define DISK_BASE_BUF_LEN 4096 /* 默認的磁盤數據緩沖區大小為512字節,建議選擇為2048甚至4096以支持某些大扇區的U盤,為0則禁止在.H文件中定義緩沖區并由應用程序在pDISK_BASE_BUF中指定 */
#define CH375_INT_WIRE INT0 /* P3.2, INT0, CH375的中斷線INT#引腳,連接CH375的INT#引腳,用于查詢中斷狀態 */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未調用CH375FileEnumer程序故禁止以節約代碼 */
#define NO_DEFAULT_CH375_F_QUERY 1 /* 未調用CH375FileQuery程序故禁止以節約代碼 */
#include "..\CH375HF6.H" /* 如果不需要支持FAT32,那么請選用CH375HF4.H */
/* 在P1.4連接一個LED用于監控演示程序的進度,低電平LED亮,當U盤插入后亮 */
sbit P1_4 = P1^4;
#define LED_OUT_INIT( ) { P1_4 = 1; } /* P1.4 高電平 */
#define LED_OUT_ACT( ) { P1_4 = 0; } /* P1.4 低電平驅動LED顯示 */
#define LED_OUT_INACT( ) { P1_4 = 1; } /* P1.4 低電平驅動LED顯示 */
sbit P1_5 = P1^5;
/* 在P1.5連接一個LED用于監控演示程序的進度,低電平LED亮,當對U盤操作時亮 */
#define LED_RUN_ACT( ) { P1_5 = 0; } /* P1.5 低電平驅動LED顯示 */
#define LED_RUN_INACT( ) { P1_5 = 1; } /* P1.5 低電平驅動LED顯示 */
sbit P1_6 = P1^6;
/* 在P1.6連接一個LED用于監控演示程序的進度,低電平LED亮,當對U盤寫操作時亮 */
#define LED_WR_ACT( ) { P1_6 = 0; } /* P1.6 低電平驅動LED顯示 */
#define LED_WR_INACT( ) { P1_6 = 1; } /* P1.6 低電平驅動LED顯示 */
/* 以毫秒為單位延時,不精確,適用于24MHz時鐘 */
void mDelaymS( unsigned char delay )
{
unsigned char i, j, c;
for ( i = delay; i != 0; i -- ) {
for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz時鐘下延時500uS */
for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz時鐘下延時500uS */
}
}
/* 將程序空間的字符串復制到內部RAM中,返回字符串長度 */
UINT8 mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource )
{
UINT8 i = 0;
while ( *iDestination = *iSource ) {
iDestination ++;
iSource ++;
i ++;
}
return( i );
}
/* 檢查操作狀態,如果錯誤則顯示錯誤代碼并停機,應該替換為實際的處理措施 */
void mStopIfError( UINT8 iError )
{
if ( iError == ERR_SUCCESS ) return; /* 操作成功 */
printf( "Error: %02X\n", (UINT16)iError ); /* 顯示錯誤 */
while ( 1 ) {
LED_OUT_ACT( ); /* LED閃爍 */
mDelaymS( 200 );
LED_OUT_INACT( );
mDelaymS( 200 );
}
}
/* 為printf和getkey輸入輸出初始化串口 */
void mInitSTDIO( )
{
SCON = 0x50;
PCON = 0x80;
TMOD = 0x21;
TH1 = 0xf3; /* 24MHz晶振, 9600bps */
TR1 = 1;
TI = 1;
}
/* 以下為CH375硬件接口子程序 */
#ifdef __C51__ // MCS51并口
#define xWriteCH375Cmd( c ) { CH375_CMD_PORT = ( c ); _nop_( ); _nop_( ); _nop_( ); _nop_( ); } /* 寫命令并延時2uS */
#define xWriteCH375Data( c ) { CH375_DAT_PORT = ( c ); _nop_( ); } /* 寫數據并延時1uS */
#define xReadCH375Data( ) ( CH375_DAT_PORT ) /* 連續讀數據,最小周期為1uS,否則延時 */
#else // MCS51或者其它單片機的模擬并口
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定義的被CH375程序庫調用的子程序,向CH375寫命令 */
{
mDelay1uS( ); mDelay1uS( ); /* 至少延時1uS */
P0 = mCmd; /* 向CH375的并口輸出數據 */
CH375_A0 = 1;
CH375_CS = 0;
CH375_WR = 0; /* 輸出有效寫控制信號, 寫CH375芯片的命令端口 */
CH375_CS = 0; /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度大于50nS */
CH375_WR = 1; /* 輸出無效的控制信號, 完成操作CH375芯片 */
CH375_CS = 1;
CH375_A0 = 0;
P0 = 0xFF; /* 禁止數據輸出 */
mDelay1uS( ); mDelay1uS( ); /* 至少延時2uS */
}
void xWriteCH375Data( UINT8 mData ) /* 外部定義的被CH375程序庫調用的子程序,向CH375寫數據 */
{
P0 = mData; /* 向CH375的并口輸出數據 */
CH375_A0 = 0;
CH375_CS = 0;
CH375_WR = 0; /* 輸出有效寫控制信號, 寫CH375芯片的數據端口 */
CH375_CS = 0; /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度大于50nS */
CH375_WR = 1; /* 輸出無效的控制信號, 完成操作CH375芯片 */
CH375_CS = 1;
P0 = 0xFF; /* 禁止數據輸出 */
mDelay1uS( ); /* 至少延時1uS */
}
UINT8 xReadCH375Data( void ) /* 外部定義的被CH375程序庫調用的子程序,從CH375讀數據 */
{
UINT8 mData;
mDelay1uS( ); /* 至少延時1uS */
P0 = 0xFF; /* 輸入 */
CH375_A0 = 0;
CH375_CS = 0;
CH375_RD = 0; /* 輸出有效寫控制信號, 讀CH375芯片的數據端口 */
CH375_CS = 0; /* 該操作無意義,僅作延時,CH375要求讀寫脈沖寬度大于50nS */
mData = P0; /* 從CH375的并口輸入數據 */
CH375_RD = 1; /* 輸出無效的控制信號, 完成操作CH375芯片 */
CH375_CS = 1;
return( mData );
}
#endif
/* 從CH375主機端點的接收緩沖區讀取數據塊,返回讀取的數據總長度 */
UINT8 ReadUsbData( UINT8 *iBuffer )
{
UINT8 mCount, mLength;
xWriteCH375Cmd( CMD_RD_USB_DATA0 ); /* 從當前USB中斷的端點緩沖區讀取數據塊 */
mLength = xReadCH375Data( ); /* 后續數據的長度 */
for ( mCount = mLength; mCount != 0; mCount -- ) { /* 根據長度讀取數據 */
*iBuffer = xReadCH375Data( ); /* 讀出數據并保存 */
iBuffer ++;
}
return( mLength );
}
/* 向CH375主機端點的發送緩沖區寫入數據塊 */
void WriteUsbData( UINT8 *iBuffer, UINT8 iCount )
{
xWriteCH375Cmd( CMD_WR_USB_DATA7 ); /* 向USB主機端點的發送緩沖區寫入數據塊 */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -