作者deo2000 (800IM)
看板ASM
標題Re: [問題] PC 收 51 傳的0~255,有時會收到奇怪數字
時間Sat Jan 12 15:38:40 2013
現在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; /*
[email protected]*/
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)
1F:→ ksmrt0123:500Hz週期是2mS, 9600bps傳2bytes需要2.08mS 01/13 00:47
那請問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)
2F:→ ksmrt0123:我猜是pc端的問題. pc是多工的環境, timing不準 01/13 14:20
3F:→ ksmrt0123:30Hz的話 33.3mS要做一次, 這個timing對pc應該有困難 01/13 14:21
timing不準沒關係,當初就是有考慮到OS資源分配問題,所以才想用PC送出"Q",
等OS有空才請MCU送資料到SBUF,PC再去抓回來這樣。
4F:→ ksmrt0123:btw, if(RI&&'Q'==SBUF) 是不好的寫法最好別用 01/13 14:22
我知道SBUF的東西看過可能就不見了,在這裡只用一次,並沒有要存下這個字串,
而且也能少宣告一個buf變數、少一次傳值動作。
※ 編輯: deo2000 來自: 140.122.165.222 (01/13 14:30)
5F:→ ksmrt0123:我是說把條件寫成兩個if比較好 01/13 14:40
6F:→ ksmrt0123:邏輯比較清楚, 也不怕compiler optimization造成錯誤 01/13 14:41
7F:→ ksmrt0123:pc端的問題需要再研究, 你是用timer產生event去讀嗎? 01/13 14:45
我用winmm.dll提供的timeGetTime(1)函式
8F:→ ksmrt0123:有示波器的話可量量看pc送'Q'出來的間隔準不準 01/13 14:49
PC送"Q"的間隔不準沒差,我在意的只有,為什麼經常收到空字串?導致雜訊相當多
每一次要收字串前,都會讓PC送"Q"出去,不應該會收到空字串才對
※ 編輯: deo2000 來自: 140.122.165.222 (01/13 15:03)
9F:推 cwl751005:直接以SBUF的資料判斷太危險了('Q'=SBUF) 01/13 21:34
10F:→ cwl751005:試著先把SBUF的資料先丟出來再判斷,中斷部分做資料搬移 01/13 21:35
11F:→ cwl751005:在主程式裡判斷'Q',然後發送,看會不會好點 01/13 21:36