初始化問題求助:U盤讀寫,CH375B,單片機11.059M晶振,串口方式

上回發(fā)帖(http://m.findthetime.net/bbs/View.asp?S=101&I=38287) 在大俠指點下?lián)Q了單片機晶振為11.059M,調(diào)試初始化仍然不通,請教。

目標(biāo):U盤讀寫

環(huán)境參數(shù): 51單片機 STC11F32XE:32K flash,1280 on-chip RAM,接11.0592M晶振 CH375B芯片:接12M晶振,交叉串口方式相連,INT#接P3.2; 采用文件級子程序CH375HF5.LIB,F(xiàn)ILELIB5/EXAM7示例程序為原型。

現(xiàn)狀描述: 波特率9600下向CH375發(fā)出更改波特率為57600的命令,MCU端波特率同步修改,下面在等待CH375對波特率修改后的確認(rèn)時卡住。也就執(zhí)行不到后面的CH375LibInit()函數(shù)了。

求指正,求解決方法!

關(guān)鍵程序如下:(省略部分皆依EXAM7示例程序中默認(rèn)設(shè)置)

#include "CommonHead.h" //引腳地址定義,包含了REG51.H, intrins.h 等 #include "ST7920.h" //LCD

#define MAX_BYTE_IO 16

/* 以下定義的詳細(xì)說明請看CH375HF5.H文件 */ #define LIB_CFG_FILE_IO 1 #define LIB_CFG_INT_EN 0 //#define LIB_CFG_UPD_SIZE 1

#define DISK_BASE_BUF_ADDR 0x0000 #define DISK_BASE_BUF_LEN 512

#define CH375_INT_WIRE INT0 // P3.2, INT0

#define NO_DEFAULT_CH375_F_ENUM 1 #define NO_DEFAULT_CH375_F_QUERY 1

#include "CH375HF5.H"

#define UINT8 unsigned char

void mDelay1_2uS( ) /* 至少延時1.2uS,根據(jù)單片機主頻調(diào)整 */ { return; }

// 如果單片機與CH375是串口連接,那么參考下面的子程序 void CH375_PORT_INIT( ) { SCON = 0xD0; //設(shè)置串口為9位數(shù)據(jù) //設(shè)置波特率和其它串口參數(shù) TMOD = 0x20; //timer 1, mode 2, 8-bits reload TH1 = 0xFD; TL1 = 0xFD; PCON = 0x00;

ES = 1; //enable serial interrupt TR1 = 1; //timer1 run,即TCON=TCON|0x40

}

void xWriteCH375Cmd( UINT8 mCmd ) { TB8 = 1; SBUF = mCmd; while ( TI == 0 ); TI = 0;

}

void xWriteCH375Data( UINT8 mData ) {

TB8 = 0; SBUF = mData; while ( TI == 0 ); TI = 0;

}

UINT8 xReadCH375Data( void ) { while ( RI == 0 ); RI = 0; return( SBUF ); } //

// 延時100毫秒,不精確 // void mDelay100mS( ) { uchar i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }

// 將程序空間的字符串復(fù)制到內(nèi)部RAM中,返回字符串長度 UINT8 mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); }

// 檢查操作狀態(tài),如果錯誤則顯示錯誤代碼并停機 // void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; // 操作成功 //printf( "Error: %02X\n", (UINT16)iError ); // 顯示錯誤 while ( 1 ) { RefreshCurChDisp(3,7,99); mDelay100mS( ); } }

//更改波特率 void CH375SetBaudrate( UINT16 baud ) { UINT8 mCoef, mDivConst; UINT8 temp;

switch( baud ) { case 9600: { mCoef = 0x02; mDivConst = 0xB2; temp = 0xF4; }break; case 19200: { mCoef = 0x02; mDivConst = 0xD9; temp = 0xFA; }break; case 57600: { mCoef = 0x03; mDivConst = 0x98; temp = 0xFE; }break; case 115200: { mCoef = 0x03; mDivConst = 0xCC; temp = 0xFF; }break; }

xWriteCH375Cmd( 0x02 ); xWriteCH375Data( mCoef ); xWriteCH375Data( mDivConst );

TR1 = 0; TH1 = temp; //單片機波特率同步更改 TR1 = 1;

RefreshCurChDisp(1,0,1); //LCD顯示調(diào)試信息

mCoef = 5; while( mCoef -- ) if( xReadCH375Data( ) == 0x51 ) break; //等待CH375確認(rèn),卡住!

mDelay100mS( );

}

main( ) {

uchar tmp,i;

P3_2 = 1; //外部中斷口電平初始化 AUXR1 = 0x00; //p30 p31 正常串口

IT0 = 0; //外部中斷低電平有效 EX0 = 0; CH375_PORT_INIT( ); EA = 1;

SP = 0x5f; //LCD初始化 P4SW = 0x70; //LCD初始化 init_lcd(); //LCD初始化 RefreshCurChDisp(1,2,9); //LCD顯示調(diào)試信息

EX0 = 1; //預(yù)先開一次中斷,以清除歷史殘余 for(tmp = 0;tmp < 20;tmp++) ; EX0 = 0; for(tmp = 0;tmp < 20;tmp++) ; EX0 = 1;

RefreshCurChDisp(0,0,1); //LCD顯示調(diào)試信息 AUXR1 = 0x80; //p16 p17 STC11Fxx的串口復(fù)用,測試通過 mDelay100mS( );

CH375SetBaudrate( 57600 ); //更改波特率,以便CH375在12M晶振下避開9600波特率下的高串口誤差

RefreshCurChDisp(0,1,2); //LCD顯示調(diào)試信息

i = CH375LibInit( ); //初始化CH375程序庫和CH375芯片,操作成功返回0 RefreshCurChDisp(0,2,3); mStopIfError( i ); RefreshCurChDisp(0,3,4); while(1) { mDelay100mS( ); } } [Emot]20[/Emot]

采用主機模式、字節(jié)讀寫方式,又~忘了提到。 看了大家的帖,似乎初始化ch375這塊都直接過,覺得自己挺失敗。。不過頭一次上手ch375,挫折難免的。 多向大俠們學(xué)習(xí)!致敬!


(1)為驗證單片機串口配置是否正確,可以先與PC通訊測試一下 (2)CH375在57600下的誤差與9600是一樣的,可以不用修改波特率,直接用默認(rèn)的9600測試 (3)修改波特率約在1mS內(nèi)完成,程序中修改波特率后,while( mCoef -- )有點短了


SCM 你好,關(guān)于你的建議回應(yīng) 1、目前的串口我已與PC通信測試過,正確;同時,原來我單片機用12M晶振時,9600波特率下與PC通信是差錯不能容忍的,那時只能采用2400*2=4800的波特率才無誤,我看書上以及自己計算,12M晶振下9600波特率的通信誤差都是 >7% 的!這次單片機換用11.0592M晶振目的本就是在9600下保證通信正確,但是ch375的12M晶振是不能更換的,它的誤差能保證如說明書上所言的0.16%嗎?(我理解是只有2400*4=9600這一種辦法)

2、剛剛注釋掉了修改波特率的函數(shù),程序在CH375LibInit()卡住,我理解是CH375Init()函數(shù)中通信無應(yīng)答的原因。

3、修改波特率在1ms內(nèi)完成,也就是說我必須等>1ms的時間,那么等10ms再讀CH375的串口回應(yīng)可以么?

又及,我采用的STC11F系列單片機在指令執(zhí)行速度上有4~8倍的提升,子程序庫庫中如果有類似軟件延時,而且時序要求延時較準(zhǔn)確的地方,那我的單片機跑起來不是“超速”了么? 工程師們了解么


(1)CH375的波特率誤差即如手冊中描述 (2)可以等10mS,但意義不大,只要大與1mS就可以了 (3)子程序庫涉及到的延時均是在庫頭文件中調(diào)整,通常不需要調(diào)整,并且目前調(diào)試與延時無關(guān) (4)CH375上電復(fù)位需要40mS,即程序中mDelay100mS要充足,否則CH375復(fù)位不好 (5)程序中使能了串口中斷,但沒看到中斷服務(wù)程序,不知道有沒有該程序及程序中做了哪些處理,并且與CH375通訊接口程序中均是查詢方式處理串口,二者之間存在矛盾。


(1)波特率誤差的問題且放下,只當(dāng)9600下是沒問題的; (2)(3)明白了; (4)我改程序,使上電先刻意延時超過40ms吧; (5)那意思是從頭到尾不需要開串口中斷,讓ES=0? 請指教


開中斷的意義是什么呢?至少與CH375通訊是不需要的,因為接口程序里面采用查詢方式處理了,使能中斷反而會出現(xiàn)問題,如:中斷程序中清除RI或TI,那么接口程序中會一直死等。


保證9600波特率通信正常的情況下,我增加了上電后延時100ms,并至始至終關(guān)閉串口中斷和外部中斷,終于初始化通過了,感謝SCM關(guān)于中斷和查詢方式的指點,讓我不混淆了。

馬不停蹄測試“發(fā)現(xiàn)U盤”“打開/新建文件”“關(guān)閉文件”和“拔出U盤”,程序上都過了,但是PC上看U盤內(nèi)容的時候(U盤原來是剛格式化完畢的),發(fā)現(xiàn)新建的文件文件名擴展名亂碼(叫r""r."T),且刪除時提示“無法刪除文件:無法讀取源文件或磁盤”。

這和U盤文件系統(tǒng)有關(guān)吧,ch375是自動識別U盤文件系統(tǒng)的么?我的U盤老式的16M朗科,識別為本地磁盤14.3M(其余的被自動劃為軟盤區(qū)),文件系統(tǒng)就叫FAT,也不知是FAT多少。。


(1)文件必須符合8+3格式:8字節(jié)主文件名,3字節(jié)后綴名,且必須大寫 (2)基本上每個函數(shù)有返回值,每步是否成功必須通過返回值判斷,建議先做讀文件測試,成功后再測試寫文件。 另,讀寫U盤的步驟必須按照例程去做:LibInit、DiskConnect、DiskReady,文件操作 (3)文件系統(tǒng)由庫自動識別,可以換個U盤測試


我的測試程序是按照例程的代碼走的,只加入了LCD顯示調(diào)試信息 文件名:ABC.TXT 放在U盤根目錄下。程序在經(jīng)初始化、DiskConnect、DiskReady,后開始打開已存在文件操作,若文件不存在就新建,之后就關(guān)閉文件,拔U盤了。 下面是這段代碼,已存在文件打開時不能發(fā)現(xiàn),新建的文件是亂碼。

i = CH375LibInit( ); // 初始化CH375程序庫和CH375芯片,操作成功返回0 RefreshCurChDisp(0,2,3); //LCD顯示調(diào)試信息 mStopIfError( i ); RefreshCurChDisp(0,3,4); //LCD顯示調(diào)試信息 //printf( "Wait Udisk\n" ); while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); while ( CH375DiskStatus < DISK_CONNECT ) { if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; mDelay100mS( ); } RefreshCurChDisp(0,4,5); //LCD顯示調(diào)試信息 for ( i = 0; i < 5; i ++ ) { // 有的U盤總是返回未準(zhǔn)備好,不過可以被忽略 / mDelay100mS( ); //printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; // 查詢磁盤是否準(zhǔn)備好 / } #if DISK_BASE_BUF_LEN if ( DISK_BASE_BUF_LEN < CH375vSectorSize ) { RefreshCurChDisp(3,6,44); //LCD顯示調(diào)試信息 while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelay100mS( ); } #endif // 查詢磁盤物理容量 / RefreshCurChDisp(0,5,6); //LCD顯示調(diào)試信息

// 開始操作U盤 /

// 如果MY_ADC.TXT文件已經(jīng)存在則添加數(shù)據(jù)到尾部,如果不存在則新建文件 // mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "\\ABC.TXT" ); // 文件名,該文件在根目錄下 / i = CH375FileOpen( ); // 打開文件 / RefreshCurChDisp(0,6,7); //LCD顯示調(diào)試信息 if ( i == ERR_SUCCESS ) { mCmdParam.ByteLocate.mByteOffset = 0xffffffff; // 移到文件的尾部 / i = CH375ByteLocate( ); RefreshCurChDisp(0,7,18); //LCD顯示調(diào)試信息 mStopIfError( i ); } else if ( i == ERR_MISS_FILE ) { // 沒有找到文件,必須新建文件 / // 寫操作 / mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "\\ABC.TXT" ); // 文件名,該文件在根目錄下 i = CH375FileCreate( ); RefreshCurChDisp(0,7,8); //LCD顯示調(diào)試信息 mStopIfError( i ); } else mStopIfError( i ); //打開文件時出錯 /

//printf( "Close\n" ); mCmdParam.Close.mUpdateLen = 1; i = CH375FileClose( ); // 關(guān)閉文件 / RefreshCurChDisp(1,2,11); //LCD顯示調(diào)試信息 mStopIfError( i );

//printf( "Take out\n" ); while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); // 等待U盤拔出 // RefreshCurChDisp(1,3,12); //LCD顯示調(diào)試信息

文件系統(tǒng)為"FAT"到底是哪種?FAT16?FAT12?

實在不行才換U盤。 先請教了。


(1)應(yīng)該是FAT16,在DiskReady后,可以查看CH375vDiskFat,頭文件中有說明 (2)文件名應(yīng)該這樣:"\\ABC.TXT"


上面程序里文件名我用"ABC.TXT","/ABC.TXT","\\ABC.TXT"都試過了,前兩種本身就是不對的(我亂試呢),但最后這種像文檔所說的,依然是亂碼。。??磥肀仨殦Q個U盤了。


你先不換盤,你把這個數(shù)據(jù)復(fù)制到mCmdParam.Create.mPathName緩沖區(qū)里面,然后你在通過其他的監(jiān)測方法把mCmdParam.Create.mPathName緩沖區(qū)里面的數(shù)據(jù)發(fā)出來看下是不是你寫進(jìn)去的數(shù)據(jù)。


忘記了,結(jié)貼。 換過U盤后確實好了(FAT32的文件系統(tǒng)),原來那個確實是中國的第一代U盤了,太老。。。。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频