使用RS232 接收GPS 資料 |
答題得分者是:mephise
|
good3125
一般會員 發表:2 回覆:2 積分:0 註冊:2008-05-16 發送簡訊給我 |
各位大大好 我是剛加入的板友 最近寫出一個可以透過RS232接收GPS資料的程式 但是,是寫在用BC6開發在C下 所以只會有黑框框,不過為了讓人使用,所以打算寫出介面 就把C的程式放進介面中,編譯也會通過... 但是每當按下做好的開始鈕,程式就會卡住 有人跟我說是因為我是同步接收的,所以等不到資料就不會開始 但在C的黑框框下,卻都跑的好好的,分明一樣的核心程式碼(只改了一點些為了銜接介面) 為什麼放進介面中卻無法使用呢? 以下是程式碼 [code cpp] #include #include #include #define CarNo "JZ-3938" //CAR Number #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; struct GGA //struct of GGA { char strUttcTime [20]; char varLatitude [20]; char strNSIndicator [20]; char varLongitude [20]; char strEWIndicator [20]; char strPositionFix [20]; char strSatsUsed [20]; char strIIDOP [20]; char strAltitude [20]; char strAltUnits [20]; char strGeoid [20]; char strSepUnits [20]; char strDgpsAge [20]; char strDgpsid [20]; char strchecksum [20]; char strTerminator [20]; }GGA_info; //------------------------------------------------------------------------------ void __fastcall TForm1::Button1Click(TObject *Sender) { HANDLE hPort; LPCTSTR lpszPortName; DWORD dwError, dwThreadID; DCB PortDCB; COMMTIMEOUTS CommTimeouts; BYTE Byte; DWORD dwCommModemStatus, dwBytesTransferred, READBUFLEN, WRITEBUFLEN; String s; s="COM" String(Edit8->Text); hPort = CreateFile(s.c_str(),GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,0); // Handle to port with attribute to copy // Specify a set of events to be monitored for the port. SetCommMask (hPort, EV_RXCHAR); SetupComm(hPort, READBUFLEN, WRITEBUFLEN); PurgeComm(hPort, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); CommTimeouts.ReadIntervalTimeout = MAXDWORD; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.ReadTotalTimeoutConstant = 0; CommTimeouts.WriteTotalTimeoutMultiplier = 10; CommTimeouts.WriteTotalTimeoutConstant = 1000; SetCommTimeouts(hPort, &CommTimeouts); // If it fails to open the port, return FALSE. PortDCB.DCBlength = sizeof (DCB); // Get the default port setting information. GetCommState (hPort, &PortDCB); // Change the DCB structure settings. PortDCB.BaudRate = 4800; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking. PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement. PortDCB.fNull = FALSE; // Disable null stripping. PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error. PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8 PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 SetCommState (hPort, &PortDCB); // Retrieve the time-out parameters for all read and write operations on the port. GetCommTimeouts (hPort, &CommTimeouts); // Change the COMMTIMEOUTS structure settings. char linebuf[1024], *p, *q, *pField; p = linebuf; while (hPort != INVALID_HANDLE_VALUE) { // Wait for an event to occur for the port. WaitCommEvent (hPort, &dwCommModemStatus, 0); // Re-specify the set of events to be monitored for the port. if (dwCommModemStatus & EV_RXCHAR == EV_RXCHAR) { if( ReadFile (hPort, p, 1, &dwBytesTransferred, 0) == 0) break; if( *p == 0xA ) { // one line is received if(strncmp(linebuf, "$GPGGA,", 7) == 0) { // this is the line that we want! // parse the line memset(&GGA_info, 0, sizeof(GGA_info)); int j = 1; pField = linebuf 7; for(q = pField; *q != 0; q ) { if(*q == ',' || *q == 0xD || *q == 0xA) { *q = 0; if (j == 1) strcpy(GGA_info.strUttcTime, pField); if (j == 2) strcpy(GGA_info.varLatitude, pField); if (j == 3) strcpy(GGA_info.strNSIndicator, pField); if (j == 4) strcpy(GGA_info.varLongitude, pField); if (j == 5) strcpy(GGA_info.strEWIndicator, pField); if (j == 6) strcpy(GGA_info.strPositionFix, pField); if (j == 7) strcpy(GGA_info.strSatsUsed, pField); if (j == 8) strcpy(GGA_info.strIIDOP, pField); if (j == 9) strcpy(GGA_info.strAltitude, pField); if (j == 10) strcpy(GGA_info.strAltUnits, pField); if (j == 11) strcpy(GGA_info.strGeoid, pField); if (j == 12) strcpy(GGA_info.strSepUnits, pField); if (j == 13) strcpy(GGA_info.strDgpsAge, pField); if (j == 14) strcpy(GGA_info.strDgpsid, pField); q ; pField = q; j ; } } // Chack here Edit1->Text=GGA_info.strUttcTime; Edit2->Text=GGA_info.strEWIndicator; Edit3->Text=GGA_info.varLongitude; Edit4->Text=GGA_info.varLatitude; Edit5->Text=GGA_info.strNSIndicator; Edit6->Text=CarNo; Edit7->Text="$GPGGA"; } [/code] 小弟是BCB介面的新手,若問題太笨,請見諒 也順便問一下 若要加入一個可以探測使用者有那些正在用的COMPORT的介面選項 這大概要怎麼寫呢? 可以提供思考方式,或一些提示嗎? 因為我現在的COM號碼依舊是用打入的... 以上就是我的問題 先在這感謝回答的人
------
就是因為什麼都不知道... 才能體會成長的喜悅.... 所以繼續學習吧.... |
GGL
資深會員 發表:104 回覆:600 積分:335 註冊:2006-11-05 發送簡訊給我 |
|
good3125
一般會員 發表:2 回覆:2 積分:0 註冊:2008-05-16 發送簡訊給我 |
===================引 用 GGL 文 章=================== 先回答妳的第二個問題 讀取使用中的port可透過讀取機碼的方式 HKEY_LOCAL_MOCHINE/HARDWARE/DEVICEMAP/SERIALCOMM 感謝大大回答 其實我介面的問題已經解決了 全都是因為那個WHILE...但那個WHILE又是我程式,可以不斷抓資料的核心 所以,我已經換了別的寫法,並且在介面下寫出來了 不過第2個問題,也就是大大你回答的 我倒是沒想到可以這做呢.... 感謝大大的提供,詳細的方法,我會在去找找的
------
就是因為什麼都不知道... 才能體會成長的喜悅.... 所以繼續學習吧.... |
mephise
高階會員 發表:4 回覆:149 積分:205 註冊:2004-02-09 發送簡訊給我 |
我補充一下第二點好了 下面這段是用 Delphi 寫成的, 換成 BCB 很簡單, 函數名稱都一樣
Reg: TRegistry; Reg:=TRegistry.Create(KEY_READ); Reg.RootKey:=HKEY_LOCAL_MACHINE; if Reg.KeyExists('\HARDWARE\DEVICEMAP\SERIALCOMM') then begin Reg.OpenKey('\HARDWARE\DEVICEMAP\SERIALCOMM',False); Data:=TStringList.Create; Reg.GetValueNames(Data); for i:=0 to Data.Count-1 do ListBox1.Items.Add(Reg.ReadString(Data.Strings[i])); end; 不過在 BCB 中 HARDWARE\DEVICEMAP\SERIALCOMM 要換成 HARDWARE\\DEVICEMAP\\SERIALCOMM \ --> 換成 \\ 因為在C中 \是控制字元符號 關於第一個問題 你的 RS232 沒有實作 Multi-Threading 這是會有問題的 許多同好都是使用 SPComm 元件, 我建議你不妨試試看 雖然她是用 Delphi 寫成的 BCB 還是能直接使用
------
Mephise Chen 前興德工程師 |
good3125
一般會員 發表:2 回覆:2 積分:0 註冊:2008-05-16 發送簡訊給我 |
===================引 用 mephise 文 章=================== 我補充一下第二點好了 下面這段是用 Delphi 寫成的, 換成 BCB 很簡單, 函數名稱都一樣 Reg: TRegistry; Reg:=TRegistry.Create(KEY_READ); Reg.RootKey:=HKEY_LOCAL_MACHINE; if Reg.KeyExists('\HARDWARE\DEVICEMAP\SERIALCOMM') then begin Reg.OpenKey('\HARDWARE\DEVICEMAP\SERIALCOMM',False); Data:=TStringList.Create; Reg.GetValueNames(Data); for i:=0 to Data.Count-1 do ListBox1.Items.Add(Reg.ReadString(Data.Strings[i])); end; 不過在 BCB 中 HARDWARE\DEVICEMAP\SERIALCOMM 要換成 HARDWARE\\DEVICEMAP\\SERIALCOMM \ --> 換成 \\ 因為在C中 \是控制字元符號 關於第一個問題 你的 RS232 沒有實作 Multi-Threading 這是會有問題的 許多同好都是使用 SPComm 元件, 我建議你不妨試試看 雖然她是用 Delphi 寫成的 BCB 還是能直接使用 感謝大大提供詳細用法 至於開PORT的元件,小弟是找不到好,應該說找不到有解釋怎麼用的 不過大大你說的SPCOMM,小弟倒是沒試過,有空會來試看看 目前小弟還是乖乖的用API來開PORT... 雖然很麻煩,但我想怎改都可以.... 再次感謝回覆
------
就是因為什麼都不知道... 才能體會成長的喜悅.... 所以繼續學習吧.... |
mephise
高階會員 發表:4 回覆:149 積分:205 註冊:2004-02-09 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |