看板 C_and_CPP 關於我們 聯絡資訊
在為您提供問題的解決方向之前,我想先提出幾點我的疑慮, 我不清楚您的這段程式碼,只是個示意貼出來給大家看, 還是您就真的是這麼寫的...,我編譯了一下你的程式, 我想說,恐怕起碼在 C51 V7.5 是根本不能編譯通過的。 所以不知道您是使用了什麼版本... unsigned char ReceiveBuffer[8]; void ReceiveTask(unsigned char XDATA *Data) { Analyze(*Data); ^^^^^^^^^^^^^^^ 這裡會產生編譯錯誤,不曉得您是筆誤,還是真的這樣寫能過...? } void Analyze(unsigned char *Data) { for(int i=0;i<8;i++,Data++) ^^^^^^^^ 具我所知,我目前的 C51 不接受這樣的語法, 每個區段在程式敘述開始之前, 就得要將所要使用到的變數都做好宣告,最好一同賦值。 { ReceiveBuffer[i]=*Data; } } 重點是,您的 Analyze 的參數資料型態是:unsigned char *Data,沒有指定區段, 且好像一般函數的參數將隨設定的記憶體模型不同而使處理有所不同 (有點忘了), 但基本上,為了杜絕後患,一般不會這樣設計承接的參數,我會指明他所指向的區段, 至少也應該必須如 ReceiveTask 的參數一樣指向 XDATA,不太應該這樣空著不寫, 一方面確定兩個參數都指向同一記憶體區段,另一方面防止記憶體模型影響了區段指向。 當然,這也包括了您的 ReceiveBuffer 一樣沒有指明記憶體區段...,這個有點不太好, 另外,常見的週邊 IC 廠商提供存取內部資料的 API 協同開發方式,一般的是: 1、週邊 IC 產生中斷,迫使 51 執行中斷常式 (ISR)。 2、ISR 進行實際的 IC 存取處理,去取回 IC 中的資料最後存於 XDATA 區段記憶體中, 並呼叫 ReceiveTask 函數,將剛剛的 XDATA 區段資料所在的位址傳遞進去。 3、由您自己實作的 ReceiveTask 函數接手處理該資料。 前面 1、2 兩項,按照您貼文來理解,應該是已經由廠商的 API 程式庫實作完成了, 緊接著由您來實作 ReceiveTask 函數中的處理動作, 也就是說,透過 ReceiveTask 傳遞給您的 unsigned char XDATA *Data 中, 存放的就是前述提到的 IC 資料所在位址: Data --> IC 資料數據 您的程式,我做了一點修改,給您參考一下: unsigned char XDATA g_chReceiveBuffer[8]; void ReceiveTask(unsigned char XDATA *Data) { Analyze(Data); } void Analyze(unsigned char XDATA *lpDataBuffer) { /* 考慮到速度與容量,直接使用八位元操作就可以了,並將變數放在 DATA 區段 */ unsigned char DATA i; for(i = 0; i < 8; i ++) { g_chReceiveBuffer[i] = lpDataBuffer[i]; } } 我假設您貼出來的程式在您的編譯器版本確實能過好了, 這也就是表示上述搭配廠商存取動作,我猜想,將可能變成: 1、IC 產生中斷,迫使 51 執行中斷常式 (ISR)。 2、ISR 進行實際的 IC 存取處理,去取回 IC 中的資料儲存於 XDATA 區段記憶體中, 由於資料眾多,不只一道資料在 XDATA 中,所以另外準備一個指標指向這一堆資料, 並呼叫 ReceiveTask 函數,將這個指向一堆 XDATA 資料的指標其所在位址傳遞進去。 3、由您自己實作的 ReceiveTask 函數接手處理該資料。 注意到差別了嗎?傳遞給您的 unsigned char XDATA *Data 將變成: Data --> 指向一堆資料的指標 --> IC 數據 很怪,這樣很怪,我想這樣廠商乾脆 ReceiveTask 直接傳給你一個結構指標不就好了, 為何還要搞成 unsigned char * ...?當然,這也不能說不可能發生, 因為故意這樣去設計的廠商,也不是沒有出現過, 我想,拿以上兩種假設模型去詢問您的廠商,相信就會能解答該傳值或傳址的問題。 還有最後您提到的問題爆點,是在 ReceiveBuffer 中的資料莫名奇妙的被竄改..., 我猜想,您週邊裝置記憶體映射可能有些問題。 您的所設置記憶體模型之下的變數範圍,我假設你設定在 Large Mode, 恐怕在 XDATA 的區段上與 IC 裝置記憶體映射已經產生重疊。 從 XDATA 區段重疊的關係推論,廠商的 API 內部 IC 存取若不受影響, 但卻有很大的機會去打亂了您為在於 XDATA 區段上的 ReceiveBuffer 內容, 這樣一來,即便沒人呼叫 ReceiveTask 甚至於 Analyze, ReceiveBuffer 的內容將無法保證正確性。 一般廠商應該也會告訴您他的 API 應該會用什麼樣的記憶體模型來編譯, 而若設定在錯誤的記憶體模型,也恐怕會發生一些怪異怪異的問題。 最後若真的沒法找到 bug 所在,嘗試降低一點最佳化等級看看吧...。 以上參考看看,若有謬誤,還煩請指正。 ※ 編輯: SeamusBerloz 來自: 183.4.124.87 (09/29 00:14)
damody:推 洗臉的感覺。 09/29 02:19
tuzr:感謝指教,受益良多.問題點其實是我自己搞笑,資料從來沒錯過 09/30 16:21
tuzr:後來發現是我秀出資料的程式有誤,變數i,j演殘看錯了...Orz 09/30 16:21
tuzr:另外實際程式不是這樣,該段code只是示意,沒再次檢查是我不對 09/30 16:23