Re: [問題] PC 收 51 傳的0~255,有時會收到奇怪數字

看板ASM (組合語言)作者 (800IM)時間12年前 (2013/01/12 15:38), 編輯推噓1(1010)
留言11則, 2人參與, 最新討論串2/5 (看更多)
現在51改傳HEX給PC,PC端再解碼為DEC, 所以就不是"000"~"255",現在是"00"~"FF"。 PC端的軟體是VB6寫的,收到訊號後畫出波形 (用特殊Timer可達1000Hz) PC送出字串"Q"給51時,會計算讀到的HEX並送回給PC 所以每當PC送出"Q", MSC.Input 應該就要收到 "DE""F4"等字串 但是當掃描速度快(500Hz)時,有很高機會收到"DEDD""F4F5"等連續傳兩次的字串 請問這個問題該如何解決? 我每次收完 MSC.Input, 都有用 MSC.InBufferCount = 0 清除 卻還是不能避免 #include "AT89X51.h" /* P2 讀取ADC P1,3,0 預留輸出控制 */ unsigned char ucADC0804; char code HEX[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 ,0x41,0x42,0x43,0x44,0x45,0x46}; main() { IE=0x90; /* (中斷Enable)EA=1,(串列中斷)ES=1*/ P2=0xFF; /* P2為讀取Port */ SCON=0x70; /*Serial Port mode1*/ TMOD=0x20; /*Timer mode1(Auto Load)*/ TH1=0xFD; /*9600bps@11.0952MHz*/ TR1=1; /*Timer1 啟動!*/ TI=1; /*發射中斷啟動!*/ while(1) { ucADC0804=P2; } } void serial_INT(void) interrupt 4 { unsigned char swap; ES=0; //暫時阻擋串列中斷 if(RI&&'Q'==SBUF)// 如果收到請求,才發射ADC Value { swap=(ucADC0804>>4);//&0x0F; //取高4bit SBUF=HEX[swap]; //發射高4bit之ASCII while(!TI); //等待發射完畢 TI=0; //這個如果沒加,幾乎都送0出去 swap=ucADC0804&0x0F; //取低4bit SBUF=HEX[swap]; //發射低4bit之ASCII while(!TI); TI=0; //清除發射中斷旗標 } RI=0; ES=1; //恢復串列中斷 } ※ 編輯: deo2000 來自: 140.122.165.222 (01/12 19:19)

01/13 00:47, , 1F
500Hz週期是2mS, 9600bps傳2bytes需要2.08mS
01/13 00:47, 1F
那請問Rx收到的字串'Q'要不要算進去呢? 三個字=30bits,9600/30=上限320Hz 實際上是超過30Hz就會經常收到空字串,空字串出現機率,隨頻率增加而增加, 到500Hz就會很快發生溢位,PC當掉 ※ 編輯: deo2000 來自: 140.122.136.12 (01/13 01:50) Baud rate改19200之後改善很多,不過收到空字串機率還是太大,都要PC端用軟體過濾 這是目前未經PC端軟體濾波的訊號圖 http://imgur.com/XSyNG
有出現正確訊號的輪廓,但常常會收到0(空字串)雜訊 ※ 編輯: deo2000 來自: 140.122.136.12 (01/13 04:45)

01/13 14:20, , 2F
我猜是pc端的問題. pc是多工的環境, timing不準
01/13 14:20, 2F

01/13 14:21, , 3F
30Hz的話 33.3mS要做一次, 這個timing對pc應該有困難
01/13 14:21, 3F
timing不準沒關係,當初就是有考慮到OS資源分配問題,所以才想用PC送出"Q", 等OS有空才請MCU送資料到SBUF,PC再去抓回來這樣。

01/13 14:22, , 4F
btw, if(RI&&'Q'==SBUF) 是不好的寫法最好別用
01/13 14:22, 4F
我知道SBUF的東西看過可能就不見了,在這裡只用一次,並沒有要存下這個字串, 而且也能少宣告一個buf變數、少一次傳值動作。 ※ 編輯: deo2000 來自: 140.122.165.222 (01/13 14:30)

01/13 14:40, , 5F
我是說把條件寫成兩個if比較好
01/13 14:40, 5F

01/13 14:41, , 6F
邏輯比較清楚, 也不怕compiler optimization造成錯誤
01/13 14:41, 6F

01/13 14:45, , 7F
pc端的問題需要再研究, 你是用timer產生event去讀嗎?
01/13 14:45, 7F
我用winmm.dll提供的timeGetTime(1)函式

01/13 14:49, , 8F
有示波器的話可量量看pc送'Q'出來的間隔準不準
01/13 14:49, 8F
PC送"Q"的間隔不準沒差,我在意的只有,為什麼經常收到空字串?導致雜訊相當多 每一次要收字串前,都會讓PC送"Q"出去,不應該會收到空字串才對 ※ 編輯: deo2000 來自: 140.122.165.222 (01/13 15:03)

01/13 21:34, , 9F
直接以SBUF的資料判斷太危險了('Q'=SBUF)
01/13 21:34, 9F

01/13 21:35, , 10F
試著先把SBUF的資料先丟出來再判斷,中斷部分做資料搬移
01/13 21:35, 10F

01/13 21:36, , 11F
在主程式裡判斷'Q',然後發送,看會不會好點
01/13 21:36, 11F
文章代碼(AID): #1GyHC2aU (ASM)
文章代碼(AID): #1GyHC2aU (ASM)