hcn你好,CH375LIB.ZIP里沒有AVR的串口模式例程吧
用的是gcc,按照上面的說法在AVR Studio里面的庫里增加了CH375HFB.A,編譯后出現(xiàn)錯誤提示: d:\WinAVR\bin\..\lib\gcc\avr\3.4.6\..\..\..\..\avr\bin\ld.exe: cannot find -lCH375HFB 不知什么原因?
(1)TO wuchuan:參考\CH375LIB\MCS51\FILELIB5\EXAM7修改3個讀寫子程序 (2)TO heibai:你的庫文件選錯了,應是:libCH375HFD.A,參考示例:UploadImages/200810271232182.rar
SCM謝謝了。我試試吧!感謝!
現(xiàn)在更改為庫文件libCH375HFD.A后可以了,謝謝
你好,我用128下載了你們的并口示例程序,想改成串口,按照你們的提示修改了三個讀寫子函數(shù),編譯通過,但試驗過不去,現(xiàn)在我把程序貼上,您給看看是哪里的問題,是不是串口初始化錯誤,應該還要做哪些改動,請幫忙。謝謝。 /* 2004.06.05 **************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB Host File Interface for CH375 ** ** TC2.0@PC, ICCAVR_6.31@AVR ** **************************************** */ /* CH375 主機文件系統(tǒng)接口 */ /* 支持: FAT12/FAT16/FAT32 */
/* AVR單片機C語言的U盤文件讀寫示例程序 */ /* 該程序將U盤中的/C51/CH375HFT.C文件中的前600個字符顯示出來, 如果找不到原文件CH375HFT.C, 那么該程序將顯示C51子目錄下所有以CH375開頭的文件名, 如果找不到C51子目錄, 那么該程序將顯示根目錄下的所有文件名, 最后將程序ROM中的一個字符串寫入寫入新建的文件"NEWFILE.TXT"中 */ /* CH375的INT#引腳采用查詢方式處理, 數(shù)據(jù)復制方式為"內(nèi)部復制", 本程序適用于ATmega128單片機, 串口0輸出監(jiān)控信息,9600bps */ /* 本例以字節(jié)為單位讀寫U盤文件,讀寫速度較扇區(qū)模式慢,但是由于字節(jié)模式讀寫文件不需要文件數(shù)據(jù)緩沖區(qū)FILE_DATA_BUF, 所以總共只需要600字節(jié)的RAM,適用于單片機硬件資源有限、數(shù)據(jù)量小并且讀寫速度要求不高的系統(tǒng) */
/* ICCAVR -v -Wp -I\ICC\INCLUDE -Wf -Mavr_enhanced -Wl -L\ICC\LIB -m -bfunc_lit:0x8C.0x20000 -bdata:0x0100.0x0FFF -dram_end:0x0FFF -dhwstk_size:40 -ucrtatmega.o CH375HFB.C CH375HFB.A */
#include #include #include
/* 以下定義的詳細說明請看CH375HF9.H文件 */ #define LIB_CFG_FILE_IO 1 /* 文件讀寫的數(shù)據(jù)的復制方式,0為"外部子程序",1為"內(nèi)部復制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引腳連接方式,0為"查詢方式",1為"中斷方式" */
/* 單片機的RAM有限,其中CH375子程序用512字節(jié),剩余RAM部分可以用于文件讀寫緩沖 */ #define DISK_BASE_BUF_LEN 2048 /* 默認的磁盤數(shù)據(jù)緩沖區(qū)大小為512字節(jié),建議選擇為2048甚至4096以支持某些大扇區(qū)的U盤,為0則禁止在.H文件中定義緩沖區(qū)并由應用程序在pDISK_BASE_BUF中指定 */ #define FILE_DATA_BUF_LEN 0x0200 /* 外部RAM的文件數(shù)據(jù)緩沖區(qū),緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度 */
#define CH375_INT_WIRE ( PINB & 0x10 ) /* PINB.4, CH375的中斷線INT#引腳,連接CH375的INT#引腳,用于查詢中斷狀態(tài) */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未調(diào)用CH375FileEnumer程序故禁止以節(jié)約代碼 */ #define NO_DEFAULT_CH375_F_QUERY 1 /* 未調(diào)用CH375FileQuery程序故禁止以節(jié)約代碼 */
#include "CH375HFB.H"
/* 有些AVR單片機提供開放系統(tǒng)總線,那么直接將CH375掛在其系統(tǒng)總線上,以8位I/O方式進行讀寫 */ /* 雖然Atmega128提供系統(tǒng)總線,不過本例假定不開放系統(tǒng)總線,所以用I/O引腳模擬產(chǎn)生CH375的并口讀寫時序 */ /* 本例中的硬件連接方式如下(實際應用電路可以參照修改下述3個并口讀寫子程序) */ /* 單片機的引腳 CH375芯片的引腳 PINB.4 INT# PORTB.3 A0 PORTB.2 CS# PORTB.1 WR# PORTB.0 RD# PORTA(8位端口) D7-D0 */
void mDelay1uS( ) /* 至少延時1uS,根據(jù)單片機主頻調(diào)整 */ { UINT8 i; for ( i = 5; i != 0; i -- ); }
void CH375_PORT_INIT( ) /* 由于使用通用I/O模塊并口讀寫時序,所以進行初始化 */ { DDRA = 0x00; /* 設置8位并口為輸入 */ PORTB = 0x07; /* 設置CS,WR,RD默認為高電平 */ DDRB = 0x0F; /* 設置CS,WR,RD,A0為輸出,設置INT#為輸入 */ }
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫命令 */ { while(!(UCSR0A&(1<UCSR0B&=~(1<if(mCmd&0x0100) UCSR0B|=(1<UDR0=mCmd; } void xWriteCH375Data( UINT8 mData ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫數(shù)據(jù) */ { while(!(UCSR0A&(1<UCSR0B&=~(1<if(!(mData&0x0100)) UCSR0B&=~(1<UDR0=mData;
} UINT8 xReadCH375Data( void ) /* 外部定義的被CH375程序庫調(diào)用的子程序,從CH375讀數(shù)據(jù) */ { unsigned char status,resh,resl; while(!(UCSR0A&(1<status=UCSR0A; resh=UCSR0B; resl=UDR0; if(status&(1<return -1; resh=(resh>>1)&0x01; return((resh<<8)|resl);
}
/* 在P0.2連接一個LED用于監(jiān)控演示程序的進度,低電平LED亮 */ #define LED_OUT_INIT( ) { PORTB |= 0x80; DDRB |= 0x80; } /* PORTB.7 高電平為輸出方向 */ #define LED_OUT_ACT( ) { PORTB &= 0x7F; } /* PORTB.7 低電平驅動LED顯示 */ #define LED_OUT_INACT( ) { PORTB |= 0x80; } /* PORTB.7 低電平驅動LED顯示 */
/* 延時指定毫秒時間,根據(jù)單片機主頻調(diào)整,不精確 */ void mDelaymS( UINT8 ms ) { UINT16 i; while ( ms -- ) for ( i = 2600; i != 0; i -- ); }
/* 檢查操作狀態(tài),如果錯誤則顯示錯誤代碼并停機 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 顯示錯誤 */ while ( 1 ) { LED_OUT_ACT( ); /* LED閃爍 */ mDelaymS( 100 ); LED_OUT_INACT( ); mDelaymS( 100 ); } }
/* 為printf和getkey輸入輸出初始化串口 */ extern int _textmode; void mInitSTDIO( ) { UBRR0H = 0; UBRR0L = 103; /* 9600bps@16MHz */ UCSR0B = 0x18; /* BIT(RXEN) | BIT(TXEN); */ UCSR0C = 0x06; /* BIT(UCSZ1) | BIT(UCSZ0); */ _textmode = 1; }
void main( ) { UINT8 i, c; UINT16 TotalCount; UINT8 *pCodeStr; CH375_PORT_INIT( ); LED_OUT_INIT( ); LED_OUT_ACT( ); /* 開機后LED亮一下以示工作 */ mDelaymS( 100 ); /* 延時100毫秒 */ LED_OUT_INACT( ); mInitSTDIO( ); /* 為了讓計算機通過串口監(jiān)控演示過程 */ printf( "Start\n" );
#if DISK_BASE_BUF_LEN == 0 pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定義CH375的專用緩沖區(qū),而是用緩沖區(qū)指針指向其它應用程序的緩沖區(qū)便于合用以節(jié)約RAM */ #endif
i = CH375LibInit( ); /* 初始化CH375程序庫和CH375芯片,操作成功返回0 */ mStopIfError( i ); /* 其它電路初始化 */
while ( 1 ) { printf( "Wait Udisk\n" ); while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 查詢CH375中斷并更新中斷狀態(tài),等待U盤插入 */ LED_OUT_ACT( ); /* LED亮 */ mDelaymS( 200 ); /* 延時,可選操作,有的USB存儲器需要幾十毫秒的延時 */
/* 檢查U盤是否準備好,有些U盤不需要這一步,但是某些U盤必須要執(zhí)行這一步才能工作 */ for ( i = 0; i < 10; i ++ ) { /* 有的U盤總是返回未準備好,不過可以被忽略 */ mDelaymS( 100 ); printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查詢磁盤是否準備好 */ } #if DISK_BASE_BUF_LEN if ( DISK_BASE_BUF_LEN < CH375vSectorSize ) { /* 檢查磁盤數(shù)據(jù)緩沖區(qū)是否足夠大,CH375vSectorSize是U盤的實際扇區(qū)大小 */ printf( "Too large sector size\n" ); while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelaymS( 100 ); continue; } #endif /* 查詢磁盤物理容量 */ /* printf( "DiskSize\n" ); i = CH375DiskSize( ); mStopIfError( i ); printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * (CH375vSectorSize/512) / 2048 ) ); // 顯示為以MB為單位的容量 // 原計算方法 (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * CH375vSectorSize / 1000000 ) 有可能前兩個數(shù)據(jù)相乘后導致溢出, 所以修改成上式 */
/* 讀取原文件 */ printf( "Open\n" ); strcpy( (char *)mCmdParam.Open.mPathName, "/C51/CH375HFT.C" ); /* 文件名,該文件在C51子目錄下 */ i = CH375FileOpen( ); /* 打開文件 */ if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { /* 沒有找到文件 */ /* 列出文件 */ if ( i == ERR_MISS_DIR ) pCodeStr = (UINT8 *)"/*"; /* C51子目錄不存在則列出根目錄下的文件 */ else pCodeStr = (UINT8 *)"/C51/CH375*"; /* CH375HFT.C文件不存在則列出\C51子目錄下的以CH375開頭的文件 */ printf( "List file %s\n", pCodeStr ); for ( c = 0; c < 254; c ++ ) { /* 最多搜索前254個文件 */ strcpy( (char *)mCmdParam.Open.mPathName, (char *)pCodeStr ); /* 搜索文件名,*為通配符,適用于所有文件或者子目錄 */ i = strlen( (char *)mCmdParam.Open.mPathName ); /* 計算文件名長度,以處理文件名結束符 */ mCmdParam.Open.mPathName[ i ] = c; /* 根據(jù)字符串長度將結束符替換為搜索的序號,從0到255 */ i = CH375FileOpen( ); /* 打開文件,如果文件名中含有通配符*,則為搜索文件而不打開 */ if ( i == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已經(jīng)沒有匹配的文件名 */ if ( i == ERR_FOUND_NAME ) { /* 搜索到與通配符相匹配的文件名,文件名及其完整路徑在命令緩沖區(qū)中 */ printf( " match file %03d#: %s\n", (unsigned int)c, mCmdParam.Open.mPathName ); /* 顯示序號和搜索到的匹配文件名或者子目錄名 */ continue; /* 繼續(xù)搜索下
貼的都是下載的示例程序,我只修改了三個讀寫子函數(shù)
(1)試驗過不去?哪步出錯,返回值是多少? 在CH375LibInit之前先做測試命令,詳細流程參看手冊說明 xWriteCH375Cmd( 0x06 ); xWriteCH375dat( 0x55 ); i = xReadCH375dat( ); 如果i = 0xAA,則表示硬件連接和3個讀寫函數(shù)基本沒問題,可以繼續(xù)操作,反之檢查硬件連接和3個讀寫函數(shù) (2)確認單片機串口配置是否正確,能否正確收發(fā)數(shù)據(jù),可以用自發(fā)自收測試
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫命令 */ { while(!(UCSR0A&(1<UCSR0B&=~(1<if(mCmd&0x0100) UCSR0B|=(1<UDR0=mCmd; } void xWriteCH375Data( UINT8 mData ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫數(shù)據(jù) */ { while(!(UCSR0A&(1<UCSR0B&=~(1<if(!(mData&0x0100)) UCSR0B&=~(1<UDR0=mData;
} UINT8 xReadCH375Data( void ) /* 外部定義的被CH375程序庫調(diào)用的子程序,從CH375讀數(shù)據(jù) */ { unsigned char status,resh,resl; while(!(UCSR0A&(1<status=UCSR0A; resh=UCSR0B; resl=UDR0; if(status&(1<return -1; resh=(resh>>1)&0x01; return((resh<<8)|resl);
}
SCM你好,問您幾個問題(我是編程新手,公司給分配的任務,想用貴公司的CH375做U盤的讀寫) 1.咱們的示例程序是并口的,如果想改成串口是不是只需改動以上三個讀寫子函數(shù)就行了,以上是我改的,您給看看有什么問題沒有。 2.串口連接是不是只需連上TXD,RXD,和INT#三根線呢,INT#是連在通用I/O口上嗎,什么時候對他進行操作,該怎樣操作他呢。 3.我的串口初始化操作正確嗎: void mInitSTDIO( ) { UBRR0H = 0; UBRR0L = 103; /* 9600bps@16MHz */ UCSR0B = 0x1C ; /* BIT(RXEN) | BIT(TXEN); */ UCSR0C = 0x06; /* BIT(UCSZ1) | BIT(UCSZ0); */ //_textmode = 1; } 4.另外咱們的示例程序里串口用來做監(jiān)測用了,我想用串口的話是不是把監(jiān)測部分程序直接去掉就可以了,還有那個發(fā)光管的程序,實際中我用不上的話直接去掉就行了嗎。 謝謝了,我真是菜鳥,兩個多月了還是不行啊。
(1)寫命令接口函數(shù)中有無效語句:if(mCmd&0x0100) 所有的命令碼都8位的,向CH375發(fā)送命令碼時要求第9位為1,而這條語句會始終把命令碼當成數(shù)據(jù)發(fā)給CH375 注:與CH375串口通信時,需為9位數(shù)據(jù)方式,第9位為1表示命令,反之表示數(shù)據(jù) (2) void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫命令 */ { while( UCSR0A & ( 1 << UDRE0 ) == 0 ); /* 等待發(fā)送完成 */ UCSR0B |= ( 1 << TXB80 ); /* 置第9位為1 */ UDR0 = mCmd; } void xWriteCH375Data( UINT8 mData ) /* 外部定義的被CH375程序庫調(diào)用的子程序,向CH375寫數(shù)據(jù) */ { while( UCSR0A & ( 1 << UDRE0 ) == 0 ); /* 等待發(fā)送完成 */ UCSR0B &= ( 1 << TXB80 ); /* 置第9位為0 */ UDR0 = mCmd; }
UINT8 xReadCH375Data( void ) /* 外部定義的被CH375程序庫調(diào)用的子程序,從CH375讀數(shù)據(jù) */ { while( UCSR0A & ( 1 << RXC0 ) == 0 ); /* 等待接收完成 */ return ( UDR0 ); } (3)還有GND線,INT#是CH375請求中斷線,可以連接在通用I/O口上,只要像例程中定義CH375_INT_WIRE接口,庫會自動處理CH375的中斷請求 (4)UCSR0B = ( 1 << RXEN ) | ( 1 << TXEN ) | ( 1 << UCSZ2 ) | ( 1 << RXB8 ) | ( 1 << TXB8 ); (5)建議增加USART1的配置,用于監(jiān)視,發(fā)光管代碼可以去掉
SCM謝謝你了,如果我只想用Mega128串口方式實現(xiàn)對U盤的文件讀寫(即實現(xiàn)能讀文件和寫文件)那我應該參考哪個示例子程序呢?我看咱們站上好多例子,看了很長時間了,好多還不理解,如果用我上邊說的例子,還需做哪些修改呢?另外SCM我在實際應用中做好的產(chǎn)品只是給用戶留個USB口讓用戶完成文件的讀寫,所以用于監(jiān)視的代碼和對USART1的配置是否可以省略呢。不好意思太麻煩你了!
(1)\CH375LIB\AVR下的例程都可以參考,只是編譯器及版本不同,主程序基本都是通用的 (2)可以省略,只是監(jiān)視方便調(diào)試程序
CH375EVT CH375HM CH375HMU CH375HST CH375LIB_V30 CH375X86等里面的 示例程序是不是也能用上呢。
(1)CH375HM CH375HMU CH375HST CH375X86不可以 (2)CH375LIB_V30是早期版本的庫,下載最新的CH375LIB.ZIP(V3.6),只要參考\CH375LIB\AVR下的例程就夠了,下載地址:http://wch.cn/download/list.asp?id=41
SCM你好,我按您說的把程序做了如下修改來達到我要的功能(配合我的儀器使用,即把數(shù)據(jù)存入U盤,和從U盤里讀數(shù)據(jù)): 1.修改三個讀寫子函數(shù)。把并口的改為了串口。 2.屏蔽掉了咱們使用串口做的監(jiān)測程序部分(就只把帶printf("")的語句屏蔽掉了,是不是只需這樣呢) 3.把發(fā)光二極管的指示部分屏蔽了。 做了以上修改后能實現(xiàn)我要的功能嗎?另外還有個問題: 4.我存入U盤中的數(shù)據(jù)是以什么格式存在的?是文件嗎?是什么形式的文件?后綴是什么呢?如果把這些數(shù)據(jù)傳到電腦里該用什么工具打開呢?謝謝!