0 引言
USB(通用串行總線),是近年來逐步在PC領域廣為應用的新型接口技術,廣泛地應用于PC機以及嵌入式系統上。目前市場上的USB設備, 除計算機是主機接口外,其他多數為從機接口, 如打印機、U 盤等,然而USB 的拓撲結構中居于核心地位的是Host (也稱為主機) , 任何一次USB的數據傳輸都必須由主機來發起和控制,DEVICE (從機或設備) 只能響應主機的請求,任何2個外設之間或是2個主機之間無法直接通信。隨著USB應用領域的逐漸擴大,人們對于USB的期望也越來越高,希望USB能應用在沒有PC的領域中,基于USB HOST的開發應用也越來越廣泛。筆者考慮到傳統的環境監測儀多利用RS485實現與PC主機的有線遠程數據傳輸,使得監測儀的工作場合和便攜性受到相當大的限制,在本文中提出一種新型環境參數監測儀,它配置兩路音頻和溫度傳感器,以USB HOST系統為核心,以U盤為數據存儲媒介,不受場合限制隨時隨地實現環境參數(環境噪音響度,溫度)的采集、處理、存儲和通信等功能;更有助于準確地建立環境參數的演變數據庫,為環境的監控和整改提供客觀依據;便于攜帶,成本低廉,有較強的市場前景。
1 環境監測儀的設計
1.1 系統概述
環境監測儀對環境參數的處理可分為信號采集和數據處理兩部分,與此相對應,環境監測儀主要由環境參數采集電路和USB主機兩個部分組成。整體結構框圖見圖1:
圖 1 整體結構框圖
1.2 環境參數采集電路設計
以DS18B20單線數字溫度傳感器,MCA-BTA聲音傳感器加上高速A/D構成了系統的環境參數采集電路。
DS18B20數字溫度計是DALLAS公司生產的1-Wire,即單總線器件,線路簡單(三個引腳GND,DQ:數字信號輸入輸出端,VDD),體積小;只要求一個端口即可實現通信;不需要外部任何元器件即可實現測溫,范圍在-55℃到+125℃之間;可以通過寄生電源或者外部電源兩種供電方式工作。因此完全符合便利地對現場溫度測量的要求。需要注意的是,在寄生電源接線模式下,必須確保電源電壓汲取能量充足,否則會導致測量溫度偏高,誤差量較大。
MCA-MTA聲音傳感器由美國Vernier公司生產,使用的是與人類耳朵相似具有頻率反應的電麥克風。它的工作原理為:聲壓訊號→傳感器→電壓訊號→放大器→計權網絡dB值。
為增加檢測信息的實用性,USB主機系統設計中加了一個日歷時鐘模塊:DS 12C887。DS 12C887 能夠自動產生世紀、年、月、日、時、分、秒等時間信息; 具有標準的并行總線口, 可以方便與單片機連接。
1.3 嵌入式USB主機硬件結構設計
1.3.1 硬件要求
USB主機是本監測儀開發中的重點和核心。設計嵌入式USB主機電路要遵循USB主機的協議規范,具體在硬件設計上要選擇USB主機的接口芯片,并且要選用合適的MCU(單片機或微控制器)或MPU(微處理器)來控制。因為整個USB協議框架非常復雜,所以就需要MCU具有較大的內部RAM,用以處理大量的數據緩沖區,變量,數據存儲等等;其次系統要有大量的程序存儲區,一般FLASH的需求大概是在10K至60K。
1.3.2 CH375簡介
CH375是一個USB總線的通用接口芯片,支持HOST主機方式和SLAVE 設備方式。CH375的USB主機方式支持各種常用的USB全速設備,外部單片機/DSP/MCU可以通過CH375按照相應的USB 協議與USB 設備通訊。CH375還內置了處理Mass Storage海量存儲設備的專用通訊協議的固件,外部單片機/DSP/MCU可以直接以扇區為基本單位讀寫常用的USB 存儲設備(包括USB硬盤/USB閃存盤/U盤)。
CH375芯片內部集成了PLL倍頻器、主從USB接口SIE、數據緩沖區、被動并行接口、異步串行接口、命令解釋器、控制傳輸的協議處理器、通用的固件程序等。對于USB存儲設備的應用,CH375直接提供了數據塊的讀寫接口,以512b的物理扇區為基本讀寫單位,從而將USB存儲設備簡化為一種外部數據存儲器,單片機可以自由讀寫USB存儲設備中的數據,也可以自由定義其數據結構。
1.3.3 CPU的選擇
CH375的文件級子程序庫(實現FAT文件系統層,詳細請見軟件設計)需要大約600字節的隨機存儲器RAM作為緩沖區。鑒于采用MCS51內核, 且與AT89C52兼容的SM 5964單片機內部嵌有64KB的flash和1KB的SRAM,為USB主機協議的實現提供了足夠的代碼空間和數據存儲區,無須擴展外部RAM,簡化了硬件層面的設計,而且抗干擾能力較強,溫度范圍寬,在目前市場上性價比較高,嵌入式USB主機CPU采用SM 5964。
1.3.4 連接電路
CH375工作于主機模式時,分為串行方式與并行方式兩種。我們這里采用串行方式,這種的連線相對比較簡單。如果CH375芯片的TXD引腳懸空(待接單片機)或者沒有通過下拉電阻接地,那么CH375工作于串口方式。在串口方式下,CH375只需要與單片機/DSP/MCU連接3個信號線,TXD引腳、RXD引腳以及INT#引腳,其它引腳都可以懸空,就可以進行較遠距離的點對點連接。CH375芯片的RXD 和TXD分別連接到單片機的串行數據輸出引腳和串行數據輸入引腳。INT#輸出的中斷請求是低電平有效,用于通知單片機(見圖2)。
CH375 的串行數據格式是1個起始位、9個數據位、1個停止位,其中前8個數據位是一個字節數據,最后1個數據位是命令標志位。第9位為0時,前8位的數據被寫入CH375芯片中,第9位為1時,前8位被作為命令碼寫入CH375芯片中。CH375的串行通訊波特率默認是 9600 bps,單片機可以隨時通過SET_BAUDRATE 命令選擇合適的通訊波特率。
圖 2 串口方式下CH375與單片機連接示意圖
1.4 嵌入式USB主機的軟件設計
嵌入式USB主機主要實現USB設備的熱插拔檢測、設備重啟、讀取設備的各種描述符等USB1.1協議規范, 并實現USB Mass Storage 類。Mass Storage 類主要用于為軟磁盤接口、ATA接口、硬盤接口及FLASH存儲器等設備建立的USB接口。
在USB主機方式下,CH375支持各種常用的USB全速設備,以中斷方式通知外部單片機(SM5964)進行處理,中斷邏輯圖如圖3。單片機需要編寫固件程序按照相應的USB協議與USB設備通訊。
圖 3 主機方式下CH375中斷邏輯圖
單片機處理USB存儲設備的文件系統需要實現圖3左邊的4個層次,右邊是USB存儲設備的內部結構層次。CH375不僅是一個通用的USB-HOST硬件接口芯片,還內置了相關的固件程序,包含了圖4左邊的3個層次(深色),所以實際的單片機程序主要處理FAT文件系統層。
圖 4 處理USB存儲設備文件系統示意圖
在上圖中的SCSI,UFI,RBC都是Mass Storage類的子類,都有自己的協議,應用于不盡相同的設備。他們通過命令的形式實現各種功能,而這些命令都是各子類所特有的。在USB進行數據傳輸的時候,這些命令都被打包成一系列的命令包進行傳輸。真正與Mass Storage的傳輸方式相關的是其傳輸協議,在這里為BULK-ONLY傳輸協議。有關Mass Storage類的標準描述符在傳輸協議中實現。
FAT文件系統層可以由CH375的U盤文件級子程序庫實現。該子程序庫提供了USB存儲設備的文件級接口,這些應用層接口API包含了常用的文件級操作,可以移植并嵌入到SM5964單片機程序中。CH375的U盤文件級子程序庫具有以下特性:支持常用的FAT16和FAT32文件系統,磁盤容量可達100GB以上,支持多級子目錄,支持8.3格式的大寫字母文件名,支持文件打開、新建、刪除、讀寫以及搜索等。
綜上所述,分層次程序段示例如下:
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned long
#define UINT8X unsigned char xdata
#define UINT8VX unsigned char volatile xdata
UINT8VX CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
UINT8VX CH375_DAT_PORT _at_ 0xBCF0; /* CH375數據端口的I/O地址 */
#define CH375_INT_WIRE INT0 /* P3.2, 連接CH375的INT#引腳,用于查詢中斷狀態 */
UINT8X DISK_BUFFER[512*32] _at_ 0x0000; /* 外部RAM數據緩沖區的起始地址 */
UINT32 DiskStart; /* 邏輯盤的起始絕對扇區號LBA */
UINT8 SecPerClus; /* 邏輯盤的每簇扇區數 */
UINT8 RsvdSecCnt; /* 邏輯盤的保留扇區數 */
UINT16 FATSz16; /* FAT16邏輯盤的FAT表占用的扇區數 */
/* ********** 硬件USB接口層*/
void mDelaymS( UINT8 delay ) {
UINT8 i, j, c;
for ( i = delay; i != 0; i -- ) {
for ( j = 200; j != 0; j -- ) c + = 3;
for ( j = 200; j != 0; j -- ) c + = 3;
}
}
void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口寫入命令 */
CH375_CMD_PORT=cmd;
for ( cmd = 2; cmd != 0; cmd -- ); /* 發出命令碼前后應該各延時2uS */
}
void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的數據端口寫入數據 */
CH375_DAT_PORT=dat; /* 因為單片機較慢所以實際上無需延時 */
}
UINT8 CH375_RD_DAT_PORT( void ) { /* 從CH375的數據端口讀出數據 */
return( CH375_DAT_PORT ); /* 因為單片機較慢所以實際上無需延時 */
}
UINT8 mWaitInterrupt( void ) { /* 等待CH375中斷并獲取狀態,返回操作狀態 */
while( CH375_INT_WIRE ); /* 查詢等待CH375操作完成中斷(INT#低電平) */
CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產生操作完成中斷,獲取中斷狀態 */
return( CH375_RD_DAT_PORT( ) );
}
/* ********** BulkOnly傳輸協議層,被CH375內置了,無需編寫單片機程序 */
/* ********** RBC/SCSI命令層,雖然被CH375內置了,但是要寫程序發出命令及收發數據 */
UINT8 mInitDisk( void ) { /* 初始化 */
UINT8 Status;
CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 產生操作完成中斷, 獲取中斷狀態 */
Status = CH375_RD_DAT_PORT( );
if ( Status == USB_INT_DISCONNECT ) return( Status ); /* USB設備斷開 */
CH375_WR_CMD_PORT( CMD_DISK_INIT ); /* 初始化USB存儲器 */
Status = mWaitInterrupt( ); /* 等待中斷并獲取狀態 */
if ( Status != USB_INT_SUCCESS ) return( Status ); /* 出現錯誤 */
CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 獲取USB存儲器的容量 */
Status = mWaitInterrupt( ); /* 等待中斷并獲取狀態 */
if ( Status != USB_INT_SUCCESS ) { /* 出錯重試 */
mDelaymS( 250 );
CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 獲取USB存儲器的容量 */
Status = mWaitInterrupt( ); /* 等待中斷并獲取狀態 */
}
if ( Status != USB_INT_SUCCESS ) return( Status ); /* 出現錯誤 */
return( 0 ); /* U盤已經成功初始化 */
}
UINT8 mReadSector( UINT32 iLbaStart, UINT8 iSectorCount, UINT8X *oDataBuffer )
{
UINT16 mBlockCount;
UINT8 c;
CH375_WR_CMD_PORT( CMD_DISK_READ ); /* 從USB存儲器讀數據塊 */
CH375_WR_DAT_PORT( (UINT8)iLbaStart ); /* LBA的最低8位 */
CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 8 ) );
CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 16 ) );
CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */
CH375_WR_DAT_PORT( iSectorCount ); /* 扇區數 */
for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) {
c = mWaitInterrupt( ); /* 等待中斷并獲取狀態 */
if ( c == USB_INT_DISK_READ ) { /* 等待中斷并獲取狀態,請求數據讀出 */
CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 從CH375緩沖區讀取數據塊 */
c = CH375_RD_DAT_PORT( ); /* 后續數據的長度 */
while ( c -- ) *oDataBuffer++ = CH375_RD_DAT_PORT( );
CH375_WR_CMD_PORT( CMD_DISK_RD_GO ); /* 繼續執行USB存儲器的讀操作 */
}
else break; /* 返回錯誤狀態 */
}
if ( mBlockCount == 0 ) {
c = mWaitInterrupt( ); /* 等待中斷并獲取狀態 */
if ( c== USB_INT_SUCCESS ) return( 0 ); /* 操作成功 */
}
return( c ); /* 操作失敗 */
}
FAT文件系統層的程序量較大,主要包括下列函數: mIdenDisk,識別分析當前邏輯盤;mLinkCluster,獲得指定簇號的鏈接簇,輸入:當前簇號, 返回:原鏈接簇號, 如果為0則說明錯誤;mStopIfError,若錯誤則停止運行并顯示錯誤狀態,等等,在此不予詳述。
2 工作流程
基于嵌入式USB主機的交通監測儀的工作流程見圖5:
圖 5 工作流程圖
在實際測試中,將采集到的環境參數以“.txt”方式存儲,目標盤為64M和128M的U盤,成功存入自定的文件“Data.txt”,支持文件續寫和重定義文件名,并可在PC中打開該文件,也可以直接用上層測控軟件進行進一步的處理。
3 結束語
本系統設計充分體現了便攜,可靠,實用的優點,可為城市環境規劃提供充分的數據參考。隨著進一步的實際應用,仍然有改進的余地,如可以擴展多路傳感器,測量如包括氣壓、二氧化碳濃度等其他環境參數;相應地,提高存儲容量;還可以考慮構建區域服務器以增加效率等等。
參考文獻:
[1] 馬偉 計算機USB系統原理及其主從機設計 北京:北京航空航天大學出版社,2004,94~98
[2] 張慧 USB ON-THE-GO技術及應用 工業控制計算機學報,2005,18,10
[3] 嵌入式USB-HOST解決方案[DB/OL] http://www.broadmaking.com,2002,6