SerialPortTestDlg.cpp
上传用户:guqin_vip
上传日期:2022-06-17
资源大小:1993k
文件大小:17k
源码类别:

串口编程

开发平台:

C/C++

  1. // SerialPortTestDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "SerialPortTest.h"
  5. #include "SerialPortTestDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAboutDlg dialog used for App About
  13. class CAboutDlg : public CDialog
  14. {
  15. public:
  16. CAboutDlg();
  17. // Dialog Data
  18. //{{AFX_DATA(CAboutDlg)
  19. enum { IDD = IDD_ABOUTBOX };
  20. //}}AFX_DATA
  21. // ClassWizard generated virtual function overrides
  22. //{{AFX_VIRTUAL(CAboutDlg)
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. //}}AFX_VIRTUAL
  26. // Implementation
  27. protected:
  28. //{{AFX_MSG(CAboutDlg)
  29. //}}AFX_MSG
  30. DECLARE_MESSAGE_MAP()
  31. };
  32. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAboutDlg)
  35. //}}AFX_DATA_INIT
  36. }
  37. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. //{{AFX_DATA_MAP(CAboutDlg)
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  44. //{{AFX_MSG_MAP(CAboutDlg)
  45. // No message handlers
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CSerialPortTestDlg dialog
  50. CSerialPortTestDlg::CSerialPortTestDlg(CWnd* pParent /*=NULL*/)
  51. : CDialog(CSerialPortTestDlg::IDD, pParent)
  52. {
  53. //{{AFX_DATA_INIT(CSerialPortTestDlg)
  54. m_strEditReceiveMsg = _T("");
  55. m_strEditSendMsg = _T("");
  56. m_unEditPosition = 0;
  57. m_unEditVelocity = 0;
  58. m_unEditVelocity2 = 0;
  59. m_unEditPosition2 = 0;
  60. m_strEditDispData2 = _T("");
  61. //}}AFX_DATA_INIT
  62. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  63. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  64. m_bSerialPortOpened=FALSE; //初始状态:串口1没有打开
  65. m_bSerialPortOpened2=FALSE; //初始状态:串口2没有打开
  66. m_unPort=1;
  67. m_unPort2=2;
  68. m_strPortRXData2="";
  69. m_strChecksum2="";
  70. }
  71. void CSerialPortTestDlg::DoDataExchange(CDataExchange* pDX)
  72. {
  73. CDialog::DoDataExchange(pDX);
  74. //{{AFX_DATA_MAP(CSerialPortTestDlg)
  75. DDX_Control(pDX, IDC_STATIC_ICONS1, m_ctrlStaticIconS1);
  76. DDX_Control(pDX, IDC_STATIC_ICONS2, m_ctrlStaticIconS2);
  77. DDX_Control(pDX, IDC_STATIC_ICONS3, m_ctrlStaticIconS3);
  78. DDX_Control(pDX, IDC_STATIC_ICONS4, m_ctrlStaticIconS4);
  79. DDX_Control(pDX, IDC_STATIC_ICONS5, m_ctrlStaticIconS5);
  80. DDX_Control(pDX, IDC_STATIC_ICONS6, m_ctrlStaticIconS6);
  81. DDX_Control(pDX, IDC_STATIC_ICONS7, m_ctrlStaticIconS7);
  82. DDX_Control(pDX, IDC_STATIC_ICONS8, m_ctrlStaticIconS8);
  83. DDX_Control(pDX, IDC_STATIC_ICONS9, m_ctrlStaticIconS9);
  84. DDX_Control(pDX, IDC_CHECK_SWITCH1, m_ctrlCheckSwitch1);
  85. DDX_Control(pDX, IDC_CHECK_SWITCH2, m_ctrlCheckSwitch2);
  86. DDX_Control(pDX, IDC_CHECK_SWITCH3, m_ctrlCheckSwitch3);
  87. DDX_Control(pDX, IDC_CHECK_SWITCH4, m_ctrlCheckSwitch4);
  88. DDX_Control(pDX, IDC_CHECK_SWITCH5, m_ctrlCheckSwitch5);
  89. DDX_Control(pDX, IDC_CHECK_SWITCH6, m_ctrlCheckSwitch6);
  90. DDX_Control(pDX, IDC_CHECK_SWITCH7, m_ctrlCheckSwitch7);
  91. DDX_Control(pDX, IDC_CHECK_SWITCH8, m_ctrlCheckSwitch8);
  92. DDX_Control(pDX, IDC_CHECK_SWITCH9, m_ctrlCheckSwitch9);
  93. DDX_Control(pDX, IDC_COMBO_COMPORT2, m_ctrlComboComPort2);
  94. DDX_Control(pDX, IDC_COMBO_COMPORT, m_ctrlComboComPort);
  95. DDX_Text(pDX, IDC_EDIT_RECEIVEMSG, m_strEditReceiveMsg);
  96. DDX_Text(pDX, IDC_EDIT_SENDMSG, m_strEditSendMsg);
  97. DDX_Text(pDX, IDC_EDIT_POSITION, m_unEditPosition);
  98. DDV_MinMaxUInt(pDX, m_unEditPosition, 0, 31);
  99. DDX_Text(pDX, IDC_EDIT_VELOCITY, m_unEditVelocity);
  100. DDV_MinMaxUInt(pDX, m_unEditVelocity, 0, 120);
  101. DDX_Text(pDX, IDC_EDIT_VELOCITY2, m_unEditVelocity2);
  102. DDX_Text(pDX, IDC_EDIT_POSITION2, m_unEditPosition2);
  103. DDX_Text(pDX, IDC_EDIT_DISPDATA2, m_strEditDispData2);
  104. //}}AFX_DATA_MAP
  105. }
  106. BEGIN_MESSAGE_MAP(CSerialPortTestDlg, CDialog)
  107. //{{AFX_MSG_MAP(CSerialPortTestDlg)
  108. ON_WM_SYSCOMMAND()
  109. ON_WM_PAINT()
  110. ON_WM_QUERYDRAGICON()
  111. ON_MESSAGE(WM_COMM_RXCHAR, OnComm)
  112. ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
  113. ON_BN_CLICKED(IDC_BUTTON_CLOSE, OnButtonClose)
  114. ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
  115. ON_BN_CLICKED(IDC_BUTTON_OPEN2, OnButtonOpen2)
  116. ON_BN_CLICKED(IDC_BUTTON_CLOSE2, OnButtonClose2)
  117. //}}AFX_MSG_MAP
  118. END_MESSAGE_MAP()
  119. /////////////////////////////////////////////////////////////////////////////
  120. // CSerialPortTestDlg message handlers
  121. BOOL CSerialPortTestDlg::OnInitDialog()
  122. {
  123. CDialog::OnInitDialog();
  124. // Add "About..." menu item to system menu.
  125. // IDM_ABOUTBOX must be in the system command range.
  126. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  127. ASSERT(IDM_ABOUTBOX < 0xF000);
  128. CMenu* pSysMenu = GetSystemMenu(FALSE);
  129. if (pSysMenu != NULL)
  130. {
  131. CString strAboutMenu;
  132. strAboutMenu.LoadString(IDS_ABOUTBOX);
  133. if (!strAboutMenu.IsEmpty())
  134. {
  135. pSysMenu->AppendMenu(MF_SEPARATOR);
  136. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  137. }
  138. }
  139. // Set the icon for this dialog.  The framework does this automatically
  140. //  when the application's main window is not a dialog
  141. SetIcon(m_hIcon, TRUE); // Set big icon
  142. SetIcon(m_hIcon, FALSE); // Set small icon
  143. // TODO: Add extra initialization here
  144. m_ctrlComboComPort.SetCurSel(0); //初始选择串口1
  145. m_ctrlComboComPort2.SetCurSel(1); //初始选择串口2
  146. //以下两句分别设置“打开串口”、“关闭串口”两个按状态的使能状态
  147. GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bSerialPortOpened);
  148. GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_bSerialPortOpened);
  149. GetDlgItem(IDC_BUTTON_OPEN2)->EnableWindow(!m_bSerialPortOpened2);
  150. GetDlgItem(IDC_BUTTON_CLOSE2)->EnableWindow(m_bSerialPortOpened2);
  151. //载入图标
  152. m_hIconRed  = AfxGetApp()->LoadIcon(IDI_ICON_RED);
  153. m_hIconOff = AfxGetApp()->LoadIcon(IDI_ICON_OFF);
  154.      
  155. return TRUE;  // return TRUE  unless you set the focus to a control
  156. }
  157. void CSerialPortTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
  158. {
  159. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  160. {
  161. CAboutDlg dlgAbout;
  162. dlgAbout.DoModal();
  163. }
  164. else
  165. {
  166. CDialog::OnSysCommand(nID, lParam);
  167. }
  168. }
  169. // If you add a minimize button to your dialog, you will need the code below
  170. //  to draw the icon.  For MFC applications using the document/view model,
  171. //  this is automatically done for you by the framework.
  172. void CSerialPortTestDlg::OnPaint() 
  173. {
  174. if (IsIconic())
  175. {
  176. CPaintDC dc(this); // device context for painting
  177. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  178. // Center icon in client rectangle
  179. int cxIcon = GetSystemMetrics(SM_CXICON);
  180. int cyIcon = GetSystemMetrics(SM_CYICON);
  181. CRect rect;
  182. GetClientRect(&rect);
  183. int x = (rect.Width() - cxIcon + 1) / 2;
  184. int y = (rect.Height() - cyIcon + 1) / 2;
  185. // Draw the icon
  186. dc.DrawIcon(x, y, m_hIcon);
  187. }
  188. else
  189. {
  190. CDialog::OnPaint();
  191. }
  192. }
  193. // The system calls this to obtain the cursor to display while the user drags
  194. //  the minimized window.
  195. HCURSOR CSerialPortTestDlg::OnQueryDragIcon()
  196. {
  197. return (HCURSOR) m_hIcon;
  198. }
  199. #define CR 0X0D    //回车
  200. #define LF 0X0A    //换行
  201. LONG CSerialPortTestDlg::OnComm(WPARAM ch, LPARAM port)
  202. {
  203. static char checksum=0,checksum1=0;
  204. static int count1=0;//,count2=0,count3=0;
  205. static unsigned char buf[20]; 
  206.     static char c1,c2;    //用于计算半Byte校验
  207. static int flag;     //用于接收阶段标记
  208. static int twoflag=0;
  209. if(port == m_unPort)
  210. {
  211. if(ch>127)   //是不是首字节
  212. {
  213. count1=0;  //记录接收字符的个数
  214. buf[count1]=ch;
  215. checksum1= ch-128;  //开始计算校验值
  216. }
  217. else
  218. {
  219. count1++;
  220. buf[count1]=ch;
  221. checksum1 = checksum1^ch;
  222. if(count1==3)  //包括校验字节在内的全部接收完毕
  223. {
  224. if(checksum1)  //校验错
  225. {
  226. m_strEditReceiveMsg = "接收校验出错";
  227. UpdateData(FALSE);
  228. }
  229. else 
  230. {
  231. CString str;
  232. unsigned char * temp=(unsigned char*)buf;
  233. m_strEditReceiveMsg ="接收到的简单通信协议字节为:";
  234. for(int i=0;i<4;i++)
  235. {
  236. str.Format("%02X ",*(buf+i));
  237. m_strEditReceiveMsg += str;
  238. }
  239. UpdateData(FALSE);
  240. }
  241. if(count1>5)   //防止出错
  242. count1=0;
  243. }
  244. }
  245. }
  246. if(port==m_unPort2)   //串口2的数据处理
  247. {
  248. m_strPortRXData2 += (char)ch;
  249. switch(ch)
  250. {
  251. case '$':
  252. checksum=0; //开始计算CheckSum
  253. flag=0;
  254. break;
  255. case '*':  //有效数据结束,可以$和*之间数据的半Byte校验值了
  256. flag=2;
  257. c2=checksum & 0x0f; c1=((checksum >> 4) & 0x0f);
  258. if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;
  259. if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;
  260. break;
  261. case CR:   //这句必须加上,否则会出错的
  262. break;
  263. case LF:   //数据包的最后一个字符
  264. m_strPortRXData2.Empty();
  265. break;
  266. default:
  267. if(flag>0)  //注意:只有在接收到'*'后,flag才大于0
  268. {
  269. m_strChecksum2 += ch;  
  270. if(flag==1) 
  271. {
  272. CString strCheck="";
  273. strCheck.Format("%c%c",c1,c2);
  274. if(strCheck!=m_strChecksum2)  //校验计算不正确,说明接收数据出错
  275. {
  276. m_strPortRXData2.Empty();
  277. }
  278. else  //校验计算正确则处理数据
  279. {
  280. CString strSwitchSetData;
  281. strSwitchSetData = m_strPortRXData2.Mid(1,9);
  282. //以下设置信号灯状态
  283. for(int i=0;i<9;i++)
  284. {
  285. if(strSwitchSetData.Mid(i,1)=="1")
  286. SetSwitchStatus(i+1,TRUE);
  287. else
  288. SetSwitchStatus(i+1,FALSE);
  289. }
  290. //以下取出位置与速度数据
  291. CString strTemp;
  292. strTemp = m_strPortRXData2.Mid(10,5);
  293. char *temp=(char*)((LPCTSTR)strTemp);
  294. char tbuf[4];
  295. tbuf[0]=temp[0]; tbuf[1]=temp[1]; tbuf[2]=0;
  296. m_unEditPosition2 = atoi(tbuf);  //得到位置状态值
  297. tbuf[0]=temp[2]; tbuf[1]=temp[3]; 
  298. tbuf[2]=temp[4]; tbuf[3]=0;
  299. m_unEditVelocity2 = atoi(tbuf);  //得到速度值
  300. //将接收到的数据包内容显示
  301. m_strEditDispData2 = "接收到NMEA数据包:"+m_strPortRXData2;
  302. //下面准备发送"简单自定义通信协议"数据包
  303. unsigned char ucChar[4];
  304. //首字节
  305. ucChar[0]=0x80;   //首字节最高位置1
  306. if(strSwitchSetData.Mid(0,1)=="1")  // 开关1状态
  307. ucChar[0] |= 0x40;            //0100 0000 
  308. else
  309. ucChar[0] &= 0xBF;           //1011 1111
  310. if(strSwitchSetData.Mid(1,1)=="1")  // 开关2状态
  311. ucChar[0] |= 0x20;            //0010 0000 
  312. else
  313. ucChar[0] &= 0xDF;           //1101 1111
  314. if(m_unEditPosition2>31)      //对位置值进行限值
  315. m_unEditPosition2=31;
  316. ucChar[0] &= 0xE0;    //将首字节的低5位置0
  317. ucChar[0] += m_unEditPosition2; //再加上位置值
  318. ucChar[3] = ucChar[0];    //同时计算校验值
  319. //第二字节
  320. unsigned char ucTemp=0x40;
  321. for(i=0; i<7; i++)
  322. {
  323. if(strSwitchSetData.Mid(2+i,1)=="1")  
  324. ucChar[1] |= ucTemp;             
  325. else
  326. ucChar[1] &= (~ucTemp);
  327. ucTemp >>= 1;
  328. }
  329. ucChar[1] &= 0x7F; //前面做了那么多运算,用这条语句保证一下最高位为0
  330. ucChar[3] ^= ucChar[1];   //计算校验值
  331. //第三字节
  332. if(m_unEditVelocity2>120)
  333. m_unEditVelocity2=120;
  334. ucChar[2] = m_unEditVelocity2;
  335. ucChar[3] ^= ucChar[2];   //计算校验值
  336. //第四字节
  337. ucChar[3] &= 0x7F;
  338. //把"简单自定义通信协议"数据包发送出去
  339. if(m_bSerialPortOpened2)
  340. m_SerialPort2.WriteToPort(ucChar,4);
  341. //同时把发送的内容显示
  342. CString strTemp1;
  343. strTemp=   _T("发送的内容为: ");
  344. for(int j=0;j<4;j++)
  345. {
  346. strTemp1.Format("0x%02X",ucChar[j]);
  347. strTemp +=  strTemp1 + ",";
  348. }
  349. m_strEditDispData2 += strTemp;
  350. UpdateData(FALSE);
  351. }
  352. m_strChecksum2.Empty();
  353. }
  354. //从'*'后收,flag=2,1次减1操作,正好将数据包的校验值保存在m_strChecksum中
  355. flag--;  
  356. }
  357. else
  358. checksum=checksum^ch;  //当flag<=0时,计算校验值
  359. break;
  360. }
  361. }
  362. return 0;
  363. }
  364. void CSerialPortTestDlg::OnButtonOpen() 
  365. {
  366. // TODO: Add your control notification handler code here
  367. int nPort=m_ctrlComboComPort.GetCurSel()+1; //得到串口号,想想为什么要加1
  368. if(m_SerialPort.InitPort(this, nPort, 9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
  369. {
  370. m_SerialPort.StartMonitoring();
  371. m_bSerialPortOpened=TRUE;
  372. m_unPort=nPort;
  373. }
  374. else
  375. {
  376. AfxMessageBox("没有发现此串口或被占用");
  377. m_bSerialPortOpened=FALSE;
  378. }
  379. GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bSerialPortOpened);
  380. GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_bSerialPortOpened);
  381. }
  382. void CSerialPortTestDlg::OnButtonClose() 
  383. {
  384. // TODO: Add your control notification handler code here
  385. m_SerialPort.ClosePort();//关闭串口
  386.     m_bSerialPortOpened=FALSE;
  387. GetDlgItem(IDC_BUTTON_OPEN)->EnableWindow(!m_bSerialPortOpened);
  388. GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(m_bSerialPortOpened);
  389. }
  390. void CSerialPortTestDlg::OnButtonSend() 
  391. {
  392. // TODO: Add your control notification handler code here
  393. if(!m_bSerialPortOpened) //检查串口是否打开
  394. {
  395. AfxMessageBox("串口没有打开");
  396. return; 
  397. }
  398. UpdateData(TRUE); //读入编辑框中的数据
  399. CString strSend=""; //要发送的NEMA字符串
  400. //以下读入9个开关的设置状态
  401. for(int i=1;i<=9;i++)
  402. {
  403. if(GetSwitchStatus(i))
  404. strSend+='1';
  405. else
  406. strSend+='0';
  407. }
  408. CString strTemp;
  409. strTemp.Format("%02d",m_unEditPosition);
  410. strSend+=strTemp;
  411. strTemp.Format("%03d",m_unEditVelocity);
  412. strSend+=strTemp;
  413. SendNMEAData(strSend);
  414. }
  415. //该函数用于设置开关的信号灯状态,如开关5开启,
  416. //可设置为 SetSwitchStatus(5,TRUE);
  417. void CSerialPortTestDlg::SetSwitchStatus(UINT unSwtich,BOOL bStatus)
  418. {
  419. if(bStatus)
  420. {
  421. switch(unSwtich) {
  422. case 1: 
  423. m_ctrlStaticIconS1.SetIcon(m_hIconRed);
  424. break;
  425. case 2: 
  426. m_ctrlStaticIconS2.SetIcon(m_hIconRed);
  427. break;
  428. case 3: 
  429. m_ctrlStaticIconS3.SetIcon(m_hIconRed);
  430. break;
  431. case 4: 
  432. m_ctrlStaticIconS4.SetIcon(m_hIconRed);
  433. break;
  434. case 5: 
  435. m_ctrlStaticIconS5.SetIcon(m_hIconRed);
  436. break;
  437. case 6: 
  438. m_ctrlStaticIconS6.SetIcon(m_hIconRed);
  439. break;
  440. case 7: 
  441. m_ctrlStaticIconS7.SetIcon(m_hIconRed);
  442. break;
  443. case 8: 
  444. m_ctrlStaticIconS8.SetIcon(m_hIconRed);
  445. break;
  446. case 9: 
  447. m_ctrlStaticIconS9.SetIcon(m_hIconRed);
  448. break;
  449. default:
  450. break;
  451. }
  452. }
  453. else
  454. {
  455. switch(unSwtich) {
  456. case 1: 
  457. m_ctrlStaticIconS1.SetIcon(m_hIconOff);
  458. break;
  459. case 2: 
  460. m_ctrlStaticIconS2.SetIcon(m_hIconOff);
  461. break;
  462. case 3: 
  463. m_ctrlStaticIconS3.SetIcon(m_hIconOff);
  464. break;
  465. case 4: 
  466. m_ctrlStaticIconS4.SetIcon(m_hIconOff);
  467. break;
  468. case 5: 
  469. m_ctrlStaticIconS5.SetIcon(m_hIconOff);
  470. break;
  471. case 6: 
  472. m_ctrlStaticIconS6.SetIcon(m_hIconOff);
  473. break;
  474. case 7: 
  475. m_ctrlStaticIconS7.SetIcon(m_hIconOff);
  476. break;
  477. case 8: 
  478. m_ctrlStaticIconS8.SetIcon(m_hIconOff);
  479. break;
  480. case 9: 
  481. m_ctrlStaticIconS9.SetIcon(m_hIconOff);
  482. break;
  483. default:
  484. break;
  485. }
  486. }
  487. }
  488. //该函数用于得到设置的开关状态值
  489. BOOL CSerialPortTestDlg::GetSwitchStatus(UINT unSwitch)
  490. {
  491. BOOL bStatus=FALSE;
  492. switch(unSwitch) {
  493. case 1:
  494. bStatus = m_ctrlCheckSwitch1.GetCheck();
  495. break;
  496. case 2:
  497. bStatus = m_ctrlCheckSwitch2.GetCheck();
  498. break;
  499. case 3:
  500. bStatus = m_ctrlCheckSwitch3.GetCheck();
  501. break;
  502. case 4:
  503. bStatus = m_ctrlCheckSwitch4.GetCheck();
  504. break;
  505. case 5:
  506. bStatus = m_ctrlCheckSwitch5.GetCheck();
  507. break;
  508. case 6:
  509. bStatus = m_ctrlCheckSwitch6.GetCheck();
  510. break;
  511. case 7:
  512. bStatus = m_ctrlCheckSwitch7.GetCheck();
  513. break;
  514. case 8:
  515. bStatus = m_ctrlCheckSwitch8.GetCheck();
  516. break;
  517. case 9:
  518. bStatus = m_ctrlCheckSwitch9.GetCheck();
  519. break;
  520. default:
  521. break;
  522. }
  523. return bStatus;
  524. }
  525. void CSerialPortTestDlg::OnButtonOpen2() 
  526. {
  527. // TODO: Add your control notification handler code here
  528. int nPort=m_ctrlComboComPort2.GetCurSel()+1; //得到串口号
  529. if(m_SerialPort2.InitPort(this, nPort, 9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512))
  530. {
  531. m_SerialPort2.StartMonitoring();
  532. m_bSerialPortOpened2=TRUE;
  533. m_unPort2=nPort;   //记录打开的串口号
  534. }
  535. else
  536. {
  537. AfxMessageBox("没有发现此串口或被占用");
  538. m_bSerialPortOpened2=FALSE;
  539. }
  540. GetDlgItem(IDC_BUTTON_OPEN2)->EnableWindow(!m_bSerialPortOpened2);
  541. GetDlgItem(IDC_BUTTON_CLOSE2)->EnableWindow(m_bSerialPortOpened2);
  542. }
  543. void CSerialPortTestDlg::OnButtonClose2() 
  544. {
  545. // TODO: Add your control notification handler code here
  546. m_SerialPort2.ClosePort();//关闭串口2
  547.     m_bSerialPortOpened2=FALSE;
  548. GetDlgItem(IDC_BUTTON_OPEN2)->EnableWindow(!m_bSerialPortOpened2);
  549. GetDlgItem(IDC_BUTTON_CLOSE2)->EnableWindow(m_bSerialPortOpened2);
  550. }
  551. //用于将字符串打包成NMEA通信协议包
  552. void CSerialPortTestDlg::SendNMEAData(CString &strData)
  553. {
  554. char checksum=0,cr=13,ln=10;
  555.     char c1,c2; //2个 半Bype 校验值 
  556. for(int i=0;i<strData.GetLength();i++)
  557. checksum = checksum^strData[i];
  558.     c2=checksum & 0x0F; c1=((checksum >> 4) & 0x0F);
  559.     if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;
  560.     if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;
  561. CString strNMEAData;
  562. //加上包头,尾和校验值和回车换行符
  563. strNMEAData='$'+strData+"*"+c1+c2+cr+ln; 
  564. //以下几行程序关不通用,在自己的程序中注意修改
  565. m_SerialPort.WriteToPort((LPCTSTR)strNMEAData);
  566. m_strEditSendMsg.Format("发送的数据包为:%s",strNMEAData);
  567. UpdateData(FALSE);  //在发送显示编辑框中显示发送的数据包
  568. }