经典的串口调试助手源代码
C语言串口通信助手代码
该程序全部由C写成没有C++ 更没用MFC完全是自娱自乐给需要的人一个参考#include "stdafx.h"#include <windowsx.h>#include "resource.h"#include "MainDlg.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>HANDLE hComm;//用于获取串口打开函数的返回值(句柄或错误值)OVERLAPPED m_ov;COMSTAT comstat;DWORD m_dwCommEvents;TCHAR cRecs[200],cSends[100]; //接收字符串发送字符串char j=0,*cCom; //接收用统计数据大小变量端口选择BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){switch(uMsg){HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);}return FALSE;}/*系统初始化函数*/BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);ComboBox_InsertString(hwndCombo1,-1,TEXT("COM1"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM2"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM3"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM4"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM5"));ComboBox_SetCurSel(hwndCombo1,0);void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime);SetTimer(hwnd,1,1000,TimerProc);return TRUE;}/*监视串口错误时使用的函数*/boolProcessErrorMessage(char* ErrorText){char *Temp = new char[200];LPVOID lpMsgBuf;FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &lpMsgBuf,NULL);sprintf(Temp, "WARNING: %s Failed with the following error:\n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, "com2"); MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP); LocalFree(lpMsgBuf);delete[] Temp;return true;}boolopenport(char *portname)//打开串口{hComm = CreateFile(portname, //串口号“com1”“com2” 调用方法:bool open; open=openport("com2");GENERIC_READ | GENERIC_WRITE, //允许读写0, //通讯设备必须以独占方式打开0, //无安全属性OPEN_EXISTING, //通讯设备已存在FILE_FLAG_OVERLAPPED, //异步I/O0); //通讯设备不能用模板打开if (hComm == INVALID_HANDLE_VALUE) //如果被占用或是没有打开时返回的是这个错误代码CloseHandle(hComm);return FALSE;}elsereturn true;}boolsetupdcb(intrate_arg)//设置port的属性{DCB dcb;int rate= rate_arg;memset(&dcb,0,sizeof(dcb));if(!GetCommState(hComm,&dcb))//获取当前DCB配置return FALSE;// set DCB to configure the serial portdcb.DCBlength = sizeof(dcb);dcb.BaudRate = rate;dcb.Parity = NOPARITY; //奇偶校验值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零dcb.fParity = 0; //为1的话激活奇偶校验检查dcb.StopBits = ONESTOPBIT;//停止位个数,0~2分别对应1位、1.5位、2位停止位dcb.ByteSize = 8; //数据位数dcb.fOutxCtsFlow = 0;dcb.fOutxDsrFlow = 0;dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = 0;dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fOutX = 0;dcb.fInX = 0;dcb.fErrorChar = 0;dcb.fBinary = 1;dcb.fNull = 0;dcb.fAbortOnError = 0;dcb.wReserved = 0;dcb.XonLim = 2;dcb.XoffLim = 4;dcb.XonChar = 0x13;dcb.XoffChar = 0x19;dcb.EvtChar = 0;// set DCBif(!SetCommState(hComm,&dcb))return false;elsereturn true;}/*串口读取相关时间设置*/boolsetuptimeout(DWORDReadInterval,DWORDReadTotalMultiplier,DWORDReadTotalconstant,DW ORDWriteTotalMultiplier,DWORDWriteTotalconstant){COMMTIMEOUTS timeouts;timeouts.ReadIntervalTimeout=ReadInterval; //读取两个字节间隔最大值mS如超过立即返回不再读取timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //如果同下面一个都为0 则无论是否读到数据都返回// 可以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; // 以毫秒为单位指定一个常数,用于计算读操作的总限时时间0表示不限时timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;// 写操作延时同上timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;if(!SetCommTimeouts(hComm, &timeouts))return false;elsereturn true;}intClearn() //清除buff中的内容并返回buff中现有数据量的大小并读取错误原因{DWORD dwError = 0;DWORD BytesRead = 0;ClearCommError(hComm, &dwError, &comstat);return comstat.cbInQue; //返回buff中数据量}/*串口数据接收读取函数*/void ReceiveChar(){BOOL bRead = TRUE;BOOL bResult = TRUE;DWORD dwError = 0;DWORD BytesRead = 0;char i=0,n;char RXBuff;j=0;while (i-n){n=i;Sleep(10);bResult = ClearCommError(hComm, &dwError, &comstat); i=(char)comstat.cbInQue;for (;i>0;i--){if (bRead)bResult = ReadFile(hComm, // Handle to COMM port &RXBuff, // RX Buffer Pointer1, // Read one byte&BytesRead, // Stores number of bytes read&m_ov); // pointer to the m_ov structure// printf("%c",RXBuff);cRecs[j++]=(char)RXBuff;if (!bResult){switch (dwError = GetLastError()){case ERROR_IO_PENDING:{bRead = FALSE;break;}default: break;}elsebRead = TRUE; // close if (bRead)if (!bRead){bRead = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port&m_ov, // Overlapped structure&BytesRead, // Stores number of bytes readTRUE); // Wait flag}}}boolWriteChar(char* m_szWriteBuffer,DWORDm_nToSend) //写字符的函数{BOOL bWrite = TRUE;BOOL bResult = TRUE;DWORD BytesSent = 0;HANDLE m_hWriteEvent;ResetEvent(m_hWriteEvent);if (bWrite){m_ov.Offset = 0;m_ov.OffsetHigh = 0;// Clear bufferbResult = WriteFile(hComm, // Handle to COMM Portm_szWriteBuffer, // Pointer to message buffer in calling finction m_nToSend, // Length of message to send&BytesSent, // Where to store the number of bytes sent&m_ov ); // Overlapped structureif (!bResult){DWORD dwError = GetLastError();switch (dwError){case ERROR_IO_PENDING:{// continue to GetOverlappedResults()BytesSent = 0;bWrite = FALSE;break;}default:// all other error codesbreak;}}} // end if(bWrite)if (!bWrite){bWrite = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port &m_ov, // Overlapped structure&BytesSent, // Stores number of bytes sentTRUE); // Wait flag// deal with the error codeif (!bResult){printf("GetOverlappedResults() in WriteFile()");}} // end if (!bWrite)// Verify that the data size send equals what we tried to send if (BytesSent != m_nToSend){printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));}return true;}/*window时间函数回调*/void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime){SYSTEMTIME time; //定义机构体变量timeGetLocalTime(&time); //取系统时间以指针方式TCHAR strTime[256]; //程序只有一个作用wsprintf(strTime,"%04d-%02d-%02d %02d:%02d:%02d",time.wYear, //就是读取系统时间time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond);//然后写进strTimeSetDlgItemText(hwnd,IDC_TIME,strTime); //这个字符串}void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){switch(id){case IDC_SEND:{GetDlgItemText (hwnd,IDC_EDIT2,cSends,sizeof(cSends)); unsigned n=sizeof(cSends); //n是通知串口将发送字节的长度char send[100];wsprintf (send,"%s",cSends);WriteChar(send,n-1);SetCommMask(hComm, EV_RXCHAR); //监视串口是否接收有数据ReceiveChar(); //读取串口sbuff中数据cRecs[j]='\0'; //将cRecs转为字符串SetDlgItemText(hwnd,IDC_EDIT1,cRecs);} break;/*case IDC_RECEIVE: //暂时未用采用直接显示的方式{}break;*/case IDC_CHECK:{intctr;HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);ctr = ComboBox_GetCurSel(hwndCombo1);switch (ctr){case 0:cCom="com1";break;case 1:cCom="com2";break;case 2:cCom="com3";break;case 3:cCom="com4";break;case 4:cCom="com5";break;default: cCom="com1";break;}if (openport(cCom)){ SetDlgItemText(hwnd,IDC_EDIT3,"OK !");MessageBox(hwnd,"串口打开成功!","",0); }elseSetDlgItemText(hwnd,IDC_EDIT3,"FAIL");if(setupdcb(9600)&&setuptimeout(1024,0,0,20,1000)) //初始化串口属性波特率9600SetDlgItemText(hwnd,IDC_EDIT4,"串口属性设置成功");elseSetDlgItemText(hwnd,IDC_EDIT4,"串口初始化失败!"); PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR |PURGE_RXABORT | PURGE_TXABORT);}default:break;}}void Main_OnClose(HWND hwnd) {EndDialog(hwnd, 0);}。
串口精灵源代码
for(int i=0;i<len;)
{
char lstr,hstr=str[i];
if(hstr==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
lstr=str[i];
//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1
char CSCommTestDlg::ConvertHexChar(char ch)
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
写出详细的编程过程,姑且叫串口调试助手源程序V1.0或VC串口通讯源程序吧,
我相信,如果你用VC编程,那么有了这个代码,就可以轻而易举地完成串口编
程任务了。(也许本文过于详细,高手就不用看)
开始吧:
(通信企业管理)经典串口调试助手源程序及串口通信设置精编
(通信企业管理)经典串口调试助手源程序及串口通信设置串口调试助手源程序及编程详细过程作者:龚建伟2001.6.20能够任意转载,但必须注明作者和说明来自,不得作为商用目次:1.建立项目2.于项目中插入MSComm控件3.利用ClassWizard定义CMSComm类控制变量4.于对话框中添加控件5.添加串口事件消息处理函数OnComm()6.打开和设置串口参数7.发送数据如果你仍没有下载源程序,又对本文有兴趣,请立即下载于众多网友的支持下,串口调试助手从2001年5月21日发布至今,短短壹个月,于全国各地累计下载量近5000人次,于近200多个电子邮件中,20多人提供了使用测试意见,更有50多位朋友提出要串口调试助手的源代码,为了答谢谢朋友们的支持,公开推出我最初用VC控件MSComm编写串口通信程序的源代码,且写出详细的编程过程,姑且叫串口调试助手源程序V1.0或VC串口通讯源程序吧,我相信,如果你用VC编程,那么有了这个代码,就能够轻而易举地完成串口编程任务了。
(也许本文过于详细,高手就不用见)开始吧:1.建立项目:打开VC++6.0,建立壹个基于对话框的MFC应用程序SCommTest(和我源代码壹致,等会你会方便壹点);2.于项目中插入MSComm控件选择Project菜单下AddToProject子菜单中的ComponentsandControls…选项,于弹出的对话框中双击RegisteredActiveXControls项(稍等壹会,这个过程较慢),则所有注册过的ActiveX控件出当下列表框中。
选择MicrosoftCommunicationsControl,version6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。
(如果你于控件列表中见不到MicrosoftCommunicationsControl,version6.0,那可能是你于安装VC6时没有把ActiveX壹项选上,重新安装VC6,选上ActiveX就能够了),这时于ClassView视窗中就能够见到CMSComm类了,(注意:此类于ClassWizard中见不到,重构clw 文件也壹样),且且于控件工具栏Controls中出现了电话图标(如图1所示),当下要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是见不到的。
串口调试助手代码分析42
第5章串口调试助手代码分析1、建立基于对话框的工程SCOMM2、绘制界面,如下图:接收区串口组合框:IDC_COMBO_COMSELECT,m_Com波特率组合框:IDC_COMBO_SPEED,m_Speed停止位组合框:IDC_COMBO_STOPBITS,m_StopBits数据位组合框:IDC_COMBO_DATABITS,m_DataBits校验位组合框:IDC_COMBO_PARITY,m_Parity十六进制显示(接收):IDC_CHECK_HEXRECIEVE,m_ctrlHexReceieve接收编辑框:IDC_EDIT_RECIVE ,m_ReceiveData m_ctrlReceiveData Style:Vertical Scroll MultiLine打开串口IDC_BUTTON_OPENPORT,m_ctrlOpenPort串口开关标志图标IDC _STATIC_OPENOFF,m_ctrlIconOpenoff数据文件保存路径IDC _EDIT_SA VEPATH,m_strCurPath保存显示数据文件路径IDC _EDIT_SA VEPATH, m_ctrlSavePath接收计数IDC_STATIC_RXCOUNT ,m_ctrlRXCOUNT发送区…。
3、添加CSeraiPort类文件将类文件SerialPort.h SerialPort.cpp 复制到工程所在文件夹中(选择改进后的类),然后单击VC 6.0菜单Projrct -> Add to Projrct ->Files… ,再在打开的文件选择对话框中选择SerialPort.h 和SerialPort.cpp ,点击OK,就把类文件加入当前工程,并在SCOMMDlg.h 中加入头文件,#include "SerialPort.h",通过上述步骤就在当前工程中加入了CSeraiPort类。
C#串口调试助手
//serialPort1.Parity = (Parity)Enum.Parse(typeof(Parityset), comboBox4.SelectedItem.ToString());
} public enum Parityset {
None, odd, Even, Mark, Space } private void comboBox5_SelectedIndexChanged(object sender, EventArgs e) //停止位 { serialPort1.StopBits = (StopBits)Enum.Parse(typeof(StopBits), boBox5.Text); }
serialPort1.BaudRate = int.Parse(comboBox2.Text); serialPort1.DataBits = int.Parse(comboBox3.Text); serialPort1.Parity = (Parity)Enum.Parse(typeof(Parityset),
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) {
textBox3.Text = serialPort.ReadExisting();
label10.Text = (int.Parse(label10.Text.Trim()) + 1).ToString(); //统计接收区 数据 组数
经典串口调试助手源程序及串口通信设置
什么是 VARIANT 数据类型?如何使用 VARIANT 数据类型? 怎么以十六进制或二进制发送和接收? 如果还想再深入了解,请看: 串口调试助手源程序及编程详细过程(二)2001.8.26 这是更新后适合本文的源程序(2001.8.25 制作),如果还没有下载源程序,又对本文有兴趣,请 立即 下载 (当然,你看完本文也可以自己做出来,这个程序是接着上一个做的,如果你没下载前面程序, 则没必要再下载了,本程序全部包含)。
描述380无效属性值cominvalidpropertyvalue383属性为只读comsetnotsupported394属性为只读comgetnotsupported8000端口打开时操作不合法comportopen8001超时值必须大于8002无效端口号comportinvalid8003属性只在运行时有效8004属性在运行时为只读8005端口已经打开comportalreadyopen8006设备标识符无效或不支持该标识符8007不支持设备的波特率8008指定的字节大小无效8009缺省参数错误8010硬件不可用被其它设备锁定8011函数不能分配队列8012设备没有打开comnoopen8013设备已经打开8014不能使用comm通知资料内容仅供您学习参考如有不当或者侵权请联系改正或者删除
现在你可以试试程序了,将串口线接好后(不会接?去看看我写的串口接线基本方法),打开串口调试助 手,并将串口设在com2,选上自动发送,也可以等会手动发送。再执行你编写的程序,接收框里应该有数 据显示了。 7.发送数据 先为发送按钮添加一个单击消息即 BN_CLICKED 处理函数,打开 ClassWizard->Message Maps,选择类 CSCommTestDlg,选择 IDC_BUTTON_MANUALSEND,双击 BN_CLICKED 添加 OnButtonManualsend()函数,并在函数中添加如下代码: void CSCommTestDlg::OnButtonManualsend() { // TODO: Add your control notification handler code here UpdateData(TRUE); //读取编辑框内容 m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据 } 运行程序,在发送编辑框中随意输入点什么,单击发送按钮,啊!看看,在另一端的串口调试助手(或别 的调试工具)接收框里出现了什么。 如果你真是初次涉猎串口编程,又一次成功,那该说声谢谢我了,因为我第一次做串口程序时可费劲了, 那时网上的资料也不好找。开开玩笑,谢谢你的支持,有什么好东西别忘了给我寄一份。 最后说明一下,由于用到 VC 控件,在没有安装 VC 的计算机上运行时要从 VC 中把 mscomm32.ocx、 msvcrt.dll、mfc42.dll 拷到 Windows 目录下的 System 子目录中(win2000 为 System32) 龚建伟 2001.6.20
串口调试软件代码
Private Sub Form_Load()MSComm1.Settings = "9600,n,8,1" ' 波特率9600bit/s,无校验,8位数据,1位停止位mPort = 4 '设定串口,1为com1,这里根据自己对应的com序号MSComm1.InBufferSize = 8 '设定返回接收缓冲区的大小,以字符为单位MSComm1.OutBufferSize = 2If MSComm1.PortOpen = True Then MSComm1.PortOpen = False '关串口MSComm1.RThreshold = 4 '设置并返回产生oncomm 事件的字符数,以字符为单位MSComm1.SThreshold = 1 '为1,传输缓冲区(发送)的每一个字符都会使MSCOMM 控件产生OnComm事件MSComm1.InputLen = 0 '设置从接收缓冲区读取的字数,为0读取整个缓冲区MSComm1.InputMode = comInputModeText '以文本方度接收If MSComm1.PortOpen = False Then MSComm1.PortOpen = TrueMSComm1.InBufferCount = 0Me.Caption = "温度"Text1.Text = "00.0"End SubPrivate Sub MSComm1_OnComm()Dim rec As StringSelect Case mEventCase comEvReceiverec = MSComm1.InputText1.Text = recMSComm1.InBufferCount = 0 '清空接收缓存区End SelectEnd SubOption ExplicitDim a As IntegerDim BytReceived() As ByteDim strData As StringDim lenInput As IntegerDim bytSendByte() As Byte '发送二进制数据Dim strSendText As String '发送文本数据Dim blnAutoSendFlag As BooleanDim openFlag As BooleanPrivate Sub cmdOpen_Click() '打开关闭端口If openFlag ThencmdOpen.Caption = "打开串口"MSComm1.PortOpen = False '打开端口Shape1.FillColor = vbRedLabel1 = "COM" & a & " 关闭"ElseOpenPortNumcmdOpen.Caption = "关闭串口"Shape1.FillColor = vbGreenLabel1 = "COM" & a & " 打开"End IfopenFlag = Not openFlagEnd SubPrivate Sub cmdSendASc_Click() '文本发送Dim sj_Txt As Stringsj_Txt = TxtSendIf MSComm1.PortOpen = True ThenMSComm1.Output = sj_TxtEnd IfEnd SubPrivate Sub cmdSendHex_Click() '16进制发送Dim sj() As ByteDim sj_Txt As StringDim i As Integersj_Txt = TxtSendIf Len(TxtSend) Mod 2 = 0 And Len(TxtSend) <> 0 Then '检验16进制字符串长ReDim sj(Len(sj_Txt) / 2 - 1)For i = 0 To Len(sj_Txt) - 1 Step 2sj(i / 2) = Val("&H" & Mid(sj_Txt, i + 1, 2))NextIf MSComm1.PortOpen = True ThenMSComm1.Output = sjElseMSComm1.PortOpen = TrueShape1.FillColor = vbGreenMSComm1.Output = sjEnd IfElseMsgBox ("格式不对!")End IfEnd Sub'字符串表示的十六进制数据转化为相应的字节串,返回转化后的字节数Private Sub OpenPortNum()On Error GoTo uerrorFor a = 1 To 16mPort = aMSComm1.PortOpen = TrueIf MSComm1.PortOpen = True Then'Print "可用Com号= "; aExit SubElseEnd IfNextExit Subuerror:'Print "出错或占用Com号= "; aResume NextEnd SubPrivate Sub Form_Load()MSComm1.Settings = "9600,n,8,1"MSComm1.InputMode = comInputModeBinary '采用二进制传输MSComm1.InBufferCount = 0 '清空接受缓冲区MSComm1.OutBufferCount = 0 '清空传输缓冲区MSComm1.RThreshold = 1 '产生MSComm事件MSComm1.InBufferSize = 1024TxtSend = ""TxtSend = "" '800A00113135323634389794"txtReceive = ""Text2 = ""Call cmdOpen_ClickEnd SubPrivate Sub MSComm1_OnComm() '接收数据Dim strBuff As StringSelect Case mEventCase 2MSComm1.InputLen = 0strBuff = MSComm1.InputBytReceived() = strBuffjieshoulenInput = Len(strData)Text2 = lenInput \ 2'数据处理代码End SelectEnd SubPublic Function jieshou() '接收数据处理为16进制Dim i As IntegerFor i = 0 To UBound(BytReceived)If Len(Hex(BytReceived(i))) = 1 ThenstrData = strData & "0" & Hex(BytReceived(i)) ElsestrData = strData & Hex(BytReceived(i))End IfNexttxtReceive = strDataEnd Function。
(串口通信编程)开源串口调试助手Common(ComMonitor)
(串⼝通信编程)开源串⼝调试助⼿Common(ComMonitor) 最新的⽂档见这⾥: 我写的串⼝调试助⼿程序以及源代码. 警告:请勿将本软件源代码⽤于任何商业⽤途。
其实吧, 我写的这个串⼝软件绝对⽐⽹上流传的⼀些串⼝调试软件好⽤很多, 对于软件,我本⾝并没有作 太多推⼴, ⼀些功能我由于懒也没有⽂档化; 如果您正在使⽤, 也觉得我说得没错, 还望您帮忙推⼴⼀下. 感激!本程序最近正在使⽤C++完全重构, github上⾯的源代码⽆法通过编译~~ 敬请期待最新版本!微云你就⼀坑货, 说了的链接永久有效呢?源代码: 声明:本软件为开源软件,绝对不包含任何对系统不利的代码,对于360的那种⾏为,我不想说什么. 软件界⾯:-------------------------------------------------------------------------------------------------------------------------说明: 更新信息可能不会再更新到这⾥, 请到上⾯查看. 更新:2014-07-07:①优化:接收数据时,如果最后⼀个字符是'\r'或'\n',则会在⼀定时间内等待接收所有'\r','\n'字符,避免导致读取'\r\n'可能造成的两次换⾏②更改:除已经提到的那三种情况, 还有使⽤'\r\n\r'三个字符作为换⾏符使⽤的, 已增加⽀持2014-07-07:①修复:回车换⾏字符'\r','\n','\r\n'均能达到换⾏效果②修复:⼀开始"忽略回车"等⽆法点击问题③优化:简化对数据中包含'\0'的数据的处理④增加:简洁界⾯模式时把⼯具栏放到左边⑤更改:只显⽰接收区按下的"回车"字符为"<Enter>",其它不显⽰⑥增加:接收区增加⼀个"清空数据"菜单2014-07-06 1.17:①增加:允许从接收区输⼊字符并发送(更友好的类交互模式) 会显⽰的字符包括: ' ' <Space> '\b' <Backspace> '\t' <Tab> '\r' <Enter> 感觉输⼊效果还不错:②更改:更改了字符接收区/发送区的字体为Consolas等宽字体,不再使⽤原来的Courier字体③增加:简洁模式 - 此模式下⼤部分界⾯元素会被隐藏, 有时候这样更舒服 见上图所⽰, 左下⾓为"简洁模式"开关, 开启简洁模式后就像上图, 是不是很简洁?④增加:主窗⼝的⾃动界⾯布局(允许拖动改变窗⼝⼤⼩,控件坐标⾃动调整)⑤更改:默认使⽤的模式改为:字符接收+字符发送2014-07-05 1.16 (未对外发布):①字符接收数据时,增加对控制字符Backspace的⽀持(即'\b'),效果就是向前删除⼀个字符②修复⼀处中⽂检测错误(原来是对的, 不知道什么时候改错了③删除了窗体⼤⼩调整(下个版本即将使⽤⾃动布局)2014-03-03 1.15: 更新:⽀持⼿动输⼊⾮标准波特率 改进:增加了⼏个功能快捷键,⽐如Alt+S为发送,.... 优化:修正:如果接收缓冲区有未显⽰的数据,则会在按下继续显⽰时进⾏提⽰,⽽不是原来的在接收到下⼀次的数据时进⾏提⽰; 2013-11-02 1.14: 更新:修改了原来的命令发送模式的界⾯,现在变得更加友好了 如下图, 先选择要发送的命令列表⽂件: 点击打开, 将会打开如下界⾯: 1.上⾯的代码是我测试蓝⽛芯⽚⽤到的命令列表⽂件, 点击"发送命令"就会发送对应的⼀条命令 2.16进制还是原来的要求, 2个⼀组即可; 对于字符数据:默认开启转义字符功能, ⽐如 '\n' 就代表换⾏, ⽀持字符型转义字符有6个, \n,\r,\\,\t,\a,\v,\b, 那些可见的字符不需要转义, ⽐如引号,问号... ⽀持的16进制转义字符格式:\x?? - 其中, ⼀个?代表⼀个16进制字符, 以上4个字符组成⼀个16进制值,缺⼀不可 3.⽂本框中的数据可以在发送时随时修改,回车键可看到效果, (但修改的内容⽬前不能更新到原来的本地⽂件上) 4.注意到数据类型后⾯的"双击改变"⼏个字样, 也就是说通过双击, 可以改变那条命令的解析格式 5.数据⼤⼩是指最终要被发送的数据的⼤⼩, ⽽不是转义前的⼤⼩ 命令⽂件的格式举例: C:初始化SPP库:at+init\r\n C:查询任意访问码的蓝⽛设备:at+iac=9e8b33\r\n C:查询设备类为0x1f1f的蓝⽛设备:at+class=1f1f\r\n C:设置查询模式:at+inqm=1,9,48\r\n C:过滤,查询周边蓝⽛设备:at+inq\r\n H:16进制测试:12 45 67 4f 分为3部分组成, 两者之间⽤冒号隔开: 第1部分:C或者H(⼤写), 代表数据是16进制还是字符数据 第2部分:命令的名字 第3部分:数据对应的数据 BUG修复: 上⼀个版本在发送数据前忘记检查串⼝是否已经打开了, 已修复~----------------------------------------------------------------------------------------------------------2012-12-24 1.0.0.0:发布第1个版本2012-12-26:⾃动识别当前存在,插⼊,移除的串⼝号2013-01-11 1.0.0.1:增加保存接收区数据到⽂件(16进制/⽂本形式)增加从⽂件读数据到发送区(16进制/⽂本形式)增加暂停显⽰功能增加复制发送/接收区数据到剪贴板2013-01-18 1.0.0.2:修复:⽂本⽂件,16⼆进制⽂件读取错误修复:程序内部缓冲区满后使程序进⼊死循环修复:⽂本字符⽅式显⽰接收的数据时产⽣不正确的换⾏符的错误,若要产⽣换⾏符, 请使⽤"\n"2013-02-08 1.0.0.3:内部程序作了许多的优化⼯作,包含数据的发送⽅式等修复接收数据时⿏标在接收区的⽂本选择造成的⼲扰2013-02-14 1.0.0.4:增加显⽰出0~127号ASCII对应8,10,16进制功能2013-02-24 1.0.0.5,今天元宵节:更改原来的1~64串⼝列表到⾃动检测计算机上的可⽤串⼝2013-02-27 1.0.0.6:若发送⽂本,则⾃动发送被⾃动取消(若⾃动发送选项已打开)在显⽰模式下不允许对接收区数据进⾏选择操作提供硬件⽀持的串⼝设备设置为⽤户提供串⼝超时设置提供⼿动设置DTR/RTS引脚电平2013-03-01 1.0.0.7:修改原计算器(系统)为表达式求值计算器(简单版本)2013-03-03:添加:<其它>菜单添加<设备管理器>修改:在关闭串⼝后⾃动发送前⾯的钩不再⾃动取消(如果已经选中)修改:串⼝被关闭/移除后串⼝列表回到第⼀个串⼝设备的BUG2013-03-04:修改:现在在串⼝列表中可以显⽰串⼝在设备管理器中的名字了修正:⽆法显⽰ MSP430-FETUIF Debugger 的串⼝号(现在调⽤SetupApi更新列表)2013-03-05:为了⽅便数据的统计与显⽰,16进制内容与字符内容被显⽰到不同的编辑框中2013-03-09 1.0.0.8:修正在使⽤SetupApi枚举串⼝设备时未检测并⼝设备⽽造成的内存异常访问错误减少在某些波特率(如:19200bps)下丢包严重的情况(如:MSP430串⼝),有时候还是会发⽣,等待修复.某些软件(如:SComAssistant采⽤每次只读⼀个字节的办法效果还⾏, 就是速度有点慢. 我改成了WaitCommEvent函数调⽤了(原来是Pending ReadFile),减少了CPU占⽤(有些串⼝驱动并不总是⽀持同步操作.以前只管ReadFile+输出nRead字节,这⾥错误,ReadFile并不保证读取到要求的数据量后才返回,这⾥会导致严重丢包,WriteFile亦然.速度减慢,但数据更完整2013-03-10 1.0.0.9:修正:因为在格式化字符串的最后少写了⼀句 *pb = '\0',导致接收区数据显⽰错误! 修复:对utils.hex2chs和add_text作了⼤量修改,⼤⼤减少数据丢包,貌似没有丢包?,细节处理参见源程序 1.0.0.8版本因为内部原因速度严重减慢, 1.0.0.9回到原来的快速!2013-03-18:更正:若为字符显⽰⽅式,16进制⽅式保存不被允许,因为格式基本上不满⾜!2013-03-23 1.10:添加:⼯作模式中,右键点击接收区字符⽂本框可以使能中⽂显⽰模式(不推荐),由于中⽂字符由两个字节构成,所以:⼀旦在某⼀次接收过程中只接收到了中⽂字符的⼀个字节,那么数据就会显⽰出错, 这个⽆法避免, 所以建议尽量不使能中⽂显⽰模式.修正:⽤C语⾔的⼈们都习惯使⽤'\n'作为换⾏符,我也这样使⽤,但偏偏Windows的编辑框以'\r\n'作为换⾏符,没有办法,我不得不把所有的'\n'换成'\r\n',效率必然会下降,⽽且我不得不计算出\n的个数先 --> 为了计算所需缓冲区的⼤⼩.添加:现在可以显⽰出还未被发送出去的数据计数.添加:新增计时器,打开串⼝后开始计时,关闭后停⽌计时.2013-03-25:修正:⼤⼤减少中⽂乱码的问题.细节处理见代码.增加:字符串转16进制数组功能,⼯具菜单⾥⾯.2013-04-04:修正:⽆法复制接收区字符⽂本的BUG.⼩提⽰:在选择串⼝时,如果没有任何可⽤的串⼝,则进⾏提⽰更新.2013-04-07:修改:完全修改了utils.str2hex的实现,⼤⼤增加了16进制输⼊的灵活性.现在的要求:每个16进制值由两个相邻字符组成,⽆其它限制.(以前是2个相邻字符+⼀个空格)2013-04-11:发送字符数据时,对于换⾏,只发送'\n',不再发送'\r\n',注意:结尾的'\0\'不被发送!2013-04-13:修正:更改发送与接收⽅式为异步⽅式.添加:简单波形显⽰.2013-04-23:修正:发送与接收⽅式改回同步⽅式!坑~修正:当发送操作达到100次时⽆法继续发送的BUG!修改:优化内部线程同步机制,避免程序停⽌⼯作(失去响应)!优化:优化⾃动发送数据的⽅式,提⾼精度,减⼩内存/CPU占⽤!⼩提⽰:在加载/保存⽂件时,若不清楚打开/保存⽅式,可以查看简单的帮助信息!2013-05-11:明天母亲节修正:终于找到⼀个⽐较好的办法来处理⾃动发送⽤到的重复数据了,呵呵,时间下限减少到10ms2013-07-05:临时修正:选择从⽂件加载并取消后, 串⼝号选择的ComboBox会消失不见,不知道原因,临时已解决2013-07-14:改进:程序内部改进内存分配算法,避免因程序错误造成内存泄漏2013-07-20 1.12:2013-09-10 1.13 今天教师节:增加:现在可以⼿动编写待发送的命令⽂件,并发送命令了 - 在发送⽂件时选择命令⽂件, 格式见博客后⾯的介绍增加:字符发送模式下,可以选择取消回车换⾏符的发送,可以选择插⼊转义字符 1.⽀持的字符型转义字符:\r,\n,\t,\v,\a,\b,\\2.⽀持的16进制转义字符格式:\x?? - 其中⼀个问号代表⼀个16进制字符, 不可省略其⼀,必需保证4个字符的格式3.'?',''','"', 等print-able字符不需要转义 ⼥孩不哭 @ 2012-12-27 14:47:59 @。
串口调试助手VC源程序及详细编程过程
据数留残除清以区冲缓读预先//;)(tupnIteG.mmoClrtc_m 0为度长据数区收接前当置设// ;)0(neLtupnIteS.mmoClrtc_m 件事mmoCnO的据数收接个一发引将时符字个1于等或于多有中区冲缓收接口串当每示表1数参// ; ) 1 ( d l o h s er h T R t e S . m m oCl r t c _ m ; ) 1 ( e d o M tu p n I t e S . m m oCl r t c _ m 据数取检式方制进二以 // 位止停个1�位据数个8�验校无�0069率特波// ;)"1,8,n,0069"(sgnitteSteS.mmoClrtc_m ; )" t r o p l a i r es n e p o t o nn a c " ( x o B e g ass e M x f A esle 口串开打//;)EURT(nepOtroPteS.mmoClrtc_m ) )( n e p O t r o P te G . m m o C l r t c_m ! ( f i 1moc择选// ;)1(troPmmoCteS.mmoClrtc_m ; )E S L A F ( n e p Ot r o P t e S . m m oCl r t c _ m ) ) ( n e p O t r oP t e G . m m o C l rtc _ m ( f i e r e h n o i t az i l a i t i n i a r t x e d d A :OD O T / / �码代下如入加�口串开打)(golaiDtinInO::glDtseTmmoCSC的框话对主在们我在现。口串开打中数函 理处的钮按该在�钮按始开个一做中序程在如例�口串开打候时的要需你在以可你 数 参 口 串 置 设 和 口 串 开 打 . 6
VC编写串口调试助手(含VC6工程源文件)
纯业余者用VC(MFC)编写串口调试助手1.序毕业到现在,转眼就做射频开发10年了,一直从事直放站、干放等通信边缘行业,从低噪放、锁相源、选频、功放到整机,射频就那么点东西,而且越来越集成化,软件无线电是必然趋势。
做射频从业面会越来越窄,我知道所有人都会说,当你成为专家的时候,一切就都不是问题,可有几个真正的专家,再者说,射频需要经验的积累,只有实际项目做的越多越广,经验也就积累得越多,并不是一朝一夕能达到的。
前不久突然觉得,我的射频模块控制要是也是自己来编程控制多好啊!那就得学单片机编程,学习上位机编程了,可我都不会啊,要不就先来整整上位机,windows方面的。
大学唯一学的编程语言是C语言,可根本不能理解用C做什么,还都还给老师10多年了,这怎么办?从BASIC,C/C++,JAVA,PASCAL搜索了一圈,还是选C++吧,毕竟是C 语言发展而来,用VC环境,身边有可以请教的人。
在网上转悠了很久,发现《windows程序设计》是必看,《MFC Windows程序设计》是学MFC最经典的书籍。
OMG,这些书啊,都是上千页的,白天都在上班,哪有时间看哦,只有先下载下来作为参考资料了。
扯远了啊。
这也不行那也不行,怎么办呢?干脆硬着头皮上吧,找几个实例照搬,再修修改改加深理解吧。
第一个目标,自己编写个串口调试助手,掌握串口通信编程,这样上位机的编写就有希望了。
好了,目标定下来了。
网上下载了个串口调试助手,确定基本功能:1.自动寻找串口,并自动添加到下拉框中共选择;2.有波特率、数据位、停止位、校验位的选择设置;3.串口打开控制按钮;4.发送、清除按钮;5.接收是自动实现的;6.有定时自动发送功能;7.有传送文件功能;8.有状态栏显示,指示串口状态,设置参数和发送接收显示。
下面就一步步实现,本人纯业余,只是记录下来这个学习过程,请勿拍砖。
开发平台Visual C++6.0英文版,电脑是i7-2670Q四核8G内存1G独显的笔记本,装的win764位旗舰版,因此VC6兼容不是太好,有些小毛病,不过不影响编写。
串口调试助手源码
串口调试助手程序框架(一)【截图】【源码】main.cpp#include<windows.h>#include<commctrl.h>#include<iostream>#include<stdio.h>#include"resource.h"using namespace std;HINSTANCE hInst;//窗口实例HWND hRDCLEAR, hSDCLEAR;HMENU hRDCHAR;void Init(HWND hwndDlg){SetWindowText(GetDlgItem(hwndDlg, SETXONC), "0x13");SetWindowText(GetDlgItem(hwndDlg, SETXOFFC), "0x19");SetWindowText(GetDlgItem(hwndDlg, SETTO), "0");SendDlgItemMessage(hwndDlg, RDCHAR, BM_SETCHECK, 1, 0);//把RadioBox RDCHAR设置为选中SendDlgItemMessage(hwndDlg, SDCHAR, BM_SETCHECK, 1, 0);//默认发送字符SendDlgItemMessage(hwndDlg, CTASY, BM_SETCHECK, 1, 0);//默认异步通信//在一个groupbox中必须有一个radiobox的属性:组为真//串口号SetWindowText(GetDlgItem(hwndDlg, SETCOMNO), "COM4");//默认值SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM1"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM2"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM3"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM4"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM5"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM6"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM7"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM8"));SendDlgItemMessage(hwndDlg, SETCOMNO, CB_ADDSTRING, 0, (LPARAM)("COM9"));//波特率SetWindowText(GetDlgItem(hwndDlg, SETBR), "9600");//默认值SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("1200"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("2400"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("4800"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("9600"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("14400"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("28800"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("38400"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("57600"));SendDlgItemMessage(hwndDlg, SETBR, CB_ADDSTRING, 0, (LPARAM)("115200"));//数据位SetWindowText(GetDlgItem(hwndDlg, SETBS), "8");//默认值SendDlgItemMessage(hwndDlg, SETBS, CB_ADDSTRING, 0, (LPARAM)("4"));SendDlgItemMessage(hwndDlg, SETBS, CB_ADDSTRING, 0, (LPARAM)("5"));SendDlgItemMessage(hwndDlg, SETBS, CB_ADDSTRING, 0, (LPARAM)("6"));SendDlgItemMessage(hwndDlg, SETBS, CB_ADDSTRING, 0, (LPARAM)("7"));SendDlgItemMessage(hwndDlg, SETBS, CB_ADDSTRING, 0, (LPARAM)("8"));//校验位SetWindowText(GetDlgItem(hwndDlg, SETPAR), "N");//默认值SendDlgItemMessage(hwndDlg, SETPAR, CB_ADDSTRING, 0, (LPARAM)("N"));SendDlgItemMessage(hwndDlg, SETPAR, CB_ADDSTRING, 0, (LPARAM)("odd"));SendDlgItemMessage(hwndDlg, SETPAR, CB_ADDSTRING, 0, (LPARAM)("even"));//停止位SetWindowText(GetDlgItem(hwndDlg, SETSB), "1");//默认值SendDlgItemMessage(hwndDlg, SETSB, CB_ADDSTRING, 0, (LPARAM)("1"));SendDlgItemMessage(hwndDlg, SETSB, CB_ADDSTRING, 0, (LPARAM)("2"));}BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {//窗口回调函数switch (uMsg)//消息处理{case WM_INITDIALOG://初始化{Init(hwndDlg);}return TRUE;case WM_CLOSE://关闭窗口{EndDialog(hwndDlg, 0);}return TRUE;case WM_COMMAND://菜单消息{switch (LOWORD(wParam)){case RDCLEAR://清空接收框数据{SetWindowText(hRDCLEAR, "");}return TRUE;case SDCLEAR://清空发送框数据{SetWindowText(GetDlgItem(hwndDlg, SDTEXT), "");}return TRUE;case SDSEND://发送数据{TCHAR szBuf[80];//缓存区string temp;GetWindowText(GetDlgItem(hwndDlg, SDTEXT), szBuf, 80);//获得接收框的文本temp = szBuf;//拼接字符串//cout<<temp;SetWindowText(GetDlgItem(hwndDlg, RDTEXT), temp.c_str());}return TRUE;case SETOP:{//打开串口}return TRUE;case SETCP:{//关闭串口}return TRUE;case SETSO:{}return TRUE;}}return TRUE;}return FALSE;}int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {hInst = hInstance;InitCommonControls();return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DlgMain);}【源码】resource.h#ifndef IDC_STATIC#define IDC_STATIC (-1)#endif#define DLG_MAIN 100#define RDBOX 40000#define RDTEXT 40001#define RDCHAR 40002#define RDHEX 40003#define RDCLEAR 40004#define SDCHAR 40005#define SDHEX 40006#define SDCLEAR 40007#define SDSEND 40008#define SDAS 40009#define SDASTIME 40010#define SETCOMNO 40011#define CTSYN 40012#define CTASY 40013#define SETBR 40014#define SDTEXT 40015#define SETXONC 40016#define SETXOFFC 40017#define SETTO 40018#define SETPAR 40019#define SETSB 40020#define SETBS 40021#define SETOP 40022#define SETCP 40023#define SETSO 40024【源码】resource.rc#include<windows.h>#include<commctrl.h>#include<richedit.h>#include"resource.h"//// Dialog resources//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRALDLG_MAIN DIALOG 0, 0, 635, 304STYLE DS_3DLOOK| DS_CENTER| DS_MODALFRAME| DS_SHELLFONT| WS_CAPTION| WS_VISIBLE| WS_POPUP| WS_SYSMENU CAPTION "SerialPortDebug"FONT 8, "Ms Shell Dlg"{GROUPBOX "Setting", 0, 257, 7, 365, 290, 0, WS_EX_LEFTLTEXT "Select Port", 0, 284, 30, 36, 8, SS_LEFT, WS_EX_LEFTGROUPBOX "Communication Type", 0, 278, 62, 295, 35, 0, WS_EX_LEFTLTEXT "ByteSize", 0, 469, 120, 28, 8, SS_LEFT, WS_EX_LEFTLTEXT "BaudRate", 0, 297, 122, 33, 8, SS_LEFT, WS_EX_LEFTGROUPBOX "Send Data", 0, 12, 135, 240, 162, 0, WS_EX_LEFTLTEXT "StopBits", 0, 471, 161, 27, 8, SS_LEFT, WS_EX_LEFTLTEXT "Parity", 0, 299, 162, 18, 8, SS_LEFT, WS_EX_LEFTAUTOCHECKBOX "fParity", 0, 401, 162, 35, 8, 0, WS_EX_LEFTAUTOCHECKBOX "CTS", 0, 296, 202, 30, 8, 0, WS_EX_LEFTAUTOCHECKBOX "DSR", 0, 365, 202, 31, 8, 0, WS_EX_LEFTAUTOCHECKBOX "DTR", 0, 436, 202, 31, 8, 0, WS_EX_LEFTAUTOCHECKBOX "XON/XOFF", 0, 507, 202, 53, 8, 0, WS_EX_LEFTLTEXT "ms", 0, 131, 228, 10, 8, SS_LEFT, WS_EX_LEFTLTEXT "ms", 0, 562, 237, 10, 8, SS_LEFT, WS_EX_LEFTLTEXT "XonChar", 0, 293, 238, 28, 8, SS_LEFT, WS_EX_LEFTLTEXT "XoffChar", 0, 383, 238, 28, 8, SS_LEFT, WS_EX_LEFTLTEXT "Timeouts", 0, 478, 238, 30, 8, SS_LEFT, WS_EX_LEFTGROUPBOX "Receive Data", RDBOX, 15, 10, 235, 120, 0, WS_EX_LEFTEDITTEXT RDTEXT, 20, 25, 225, 75, ES_AUTOHSCROLL | ES_MULTILINE | ES_READONLY, WS_EX_LEFTAUTORADIOBUTTON "Char", RDCHAR, 26, 112, 31, 8, WS_GROUP, WS_EX_LEFTAUTORADIOBUTTON "Hex", RDHEX, 80, 112, 29, 8, 0, WS_EX_LEFTPUSHBUTTON "Clear", RDCLEAR, 196, 108, 45, 14, 0, WS_EX_LEFTAUTORADIOBUTTON "Char", SDCHAR, 26, 208, 31, 8, WS_GROUP, WS_EX_LEFTAUTORADIOBUTTON "Hex", SDHEX, 82, 208, 29, 8, 0, WS_EX_LEFTPUSHBUTTON "Clear", SDCLEAR, 132, 204, 45, 14, 0, WS_EX_LEFTPUSHBUTTON "Send", SDSEND, 196, 204, 45, 14, 0, WS_EX_LEFTAUTOCHECKBOX "Auto send", SDAS, 26, 228, 48, 8, 0, WS_EX_LEFTEDITTEXT SDASTIME, 86, 225, 40, 14, ES_RIGHT | ES_AUTOHSCROLL, WS_EX_LEFTCOMBOBOX SETCOMNO, 337, 27, 95, 30, CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_LEFTAUTORADIOBUTTON "Synchronous ", CTSYN, 326, 75, 59, 8, WS_GROUP, WS_EX_LEFTAUTORADIOBUTTON "Asynchronous ", CTASY, 472, 77, 63, 8, 0, WS_EX_LEFTCOMBOBOX SETBR, 337, 120, 48, 30, CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_LEFTEDITTEXT SDTEXT, 20, 147, 227, 45, ES_AUTOHSCROLL, WS_EX_LEFTEDITTEXT SETXONC, 325, 235, 40, 14, ES_AUTOHSCROLL, WS_EX_LEFTEDITTEXT SETXOFFC, 417, 235, 40, 14, ES_AUTOHSCROLL, WS_EX_LEFTEDITTEXT SETTO, 512, 235, 40, 14, ES_AUTOHSCROLL, WS_EX_RIGHTCOMBOBOX SETPAR, 338, 160, 48, 30, CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_LEFTCOMBOBOX SETSB, 512, 159, 48, 30, CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_LEFTCOMBOBOX SETBS, 512, 117, 48, 30, CBS_DROPDOWN | CBS_HASSTRINGS, WS_EX_LEFTPUSHBUTTON "Open Port", SETOP, 297, 272, 45, 14, 0, WS_EX_LEFTPUSHBUTTON "Close Port", SETCP, 387, 272, 45, 14, 0, WS_EX_LEFTDEFPUSHBUTTON "Stop I/O", SETSO, 473, 271, 45, 14, 0, WS_EX_LEFT}//// Manifest resources//LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL1 RT_MANIFEST".\\manifest.xml"【源码】manifest.xml< ? xml version = "1.0" encoding = "UTF-8" standalone = "yes" ? ><assembly xmlns = "urn:schemas-microsoft-com:asm.v1" manifestVersion = "1.0"><dependency><dependentAssembly><assemblyIdentity type = "win32" name = "mon-Controls" version = "6.0.0.0" processorArchitecture = "*" publicKeyToken = "6595b64144ccf1df" language = "*" / >< / dependentAssembly>< / dependency><trustInfo xmlns = "urn:schemas-microsoft-com:asm.v3"><security><requestedPrivileges><requestedExecutionLevel level = "asInvoker" uiAccess = "false" / > < / requestedPrivileges> < / security>< / trustInfo>< / assembly>。
串口调试助手源代码
串口调试助手预源代码using System;using System.Collect ion s.Ge neric;using p onen tModel;using System.Data;using System.Draw ing;using System.Linq;using System.Text;using System.Thread in g.Tasks;using System.Wi ndows.Forms;using Syste m.IO;using Syste m.IO .Ports;using System.Thread ing;using DevExpress.XtraEditors;using System.Text.RegularExpressi ons;n amespace Win dowsFormsApplicatio n3 {public partial class Form1 : XtraForm {SerialPort sp1 = new SerialPort(); int Flag = 0;int StateCha nged = 0;int StateCha nged_Ascii = 1; int StateCha nged_16 = 0;string Temp = null;stri ng Temp_memoSe nd = n ull;private void memoSe nd_EditValueCha nged(object sen der, Even tArgs e) { - }public Form1(){In itializeComp onen t();sp1.DataReceived += sp1_DataReceived; }private void Form1_Load(object sen der, Even tArgs e) { -this.MaximizeBox = false;// 检查是否有串口stri ng[] str = SerialPort.GetPortNames();if (str == null) __________ |{MessageBox.Show(”本机没有串口!", "error");return;}// 添加串口项目foreach (stri ng port in Syste m.IO.P orts.SerialPort.GetPortNames()) { cbSerial.Properties .I tems.Add(port);}// 串口设置默认选择项cbSerial.Selectedl ndex = 0;Con trol.CheckForlllegalCrossThreadCalls = false; spl.DataReceived += new SerialDataReceivedEve ntHa ndler(sp1_DataReceived); //订阅委托e)//SerialPort sp1 = new SerialPort();if (!sp1.lsOpe n)〃串口是关闭的,设置参数,打开串口{try{// 获取串口号string serialName = cbSerial.Selectedltem.ToString(); sp1.PortName = serialName;// 设置各参数stri ng strBaudRate = cbBaudRate.Text;string strDateBits = cbDataBits.Text;string strStopBits = cbStop.Text;sp1.BaudRate = Con vert.ToI nt32(strBaudRate);〃波特率sp1.DataBits = Con vert.ToI nt32(strDateBi ts);// 数据位switch (cbStop.Text) // 停止位{case "1":sp1.StopBits = StopBits. On e;break;case "1.5":sp1.StopBits = StopBits. On e;break;case "2":sp1.StopBits = StopBits.Two;break; default:case " 奇校验":sp1.Parity = Parity.Odd; break;精品文档", "Error");case "偶校验":spl.Parity = Parity.Eve n; break; default:MessageBox.Show("Error: 参数不正确!break;labSerial.Text =" 串口号:” + sp1 .P ortName; labState.Text ="状 态:打开";}catch (System.Excepti on ex) {MessageBox.Show("Error:" + ex.Message, "Error"); return; } } }//private void CloseSerial_Click(object sen der, Even tArgs e) 〃{// if (sp1.lsOpe n) // { // sp1.Close(); // labSerial.Text =" 串口号:” + sp1.PortName; // labState.Text ="状 态:关闭";// } 〃}private void Sen d_Click(object sen der, Even tArgs e) { - stri ng StrSe nd = memoSe nd.Text; if (!sp1.lsOpe n) {MessageBox.Show (” 请先打开串口! ", "Error");return; } else {if (rbt nSen dStr.Checked)//〃bt nOpe n.En abled =false; 字符串发送{if (ckTimeSe nd.Checked&& !(stri ng.lsNullOrEmpty(textTime.Text)))//判断是否定时发送数据{string Time = textTime.Text;tmSe nd.l nterval = int. Parse(Time) * 1000;//时间单位是秒,化成毫秒单位后的空格//stri ng StrSe nd_2 = StrSe nd_1.Replace (” ", ""); //stri ng StrSe nd_3 = stri ng.J oi n (” ",Regex.Matches(StrSend_2, @"..|.").Cast<Match>().ToList());stri ng[] StrArray = StrSe nd_1.Split(' '); // 用空格符隔开字符串数组var Str_Se nd = new List<stri ng>();// i nt byteBufferLe ngth = StrArray.Le ngth; 数组StrArray 的长度for (int i = 0; i < StrArray.Le ngth; i++){if (StrArray[i].Trim()=="") {//byteBufferLe ngth--; con ti nue; }else} else //{if (ckTimeSe nd.Checked&& !(string.IsNullOrEmpty(textTime.Text))){卜六进制发送//tmSe nd.Start();//开启定时器{if (StrArray[i].Le ngth < 3){Str_Se nd.Add(StrArray[i]);}else{Str_Se nd.AddRa nge(Devide(StrArray[i]));}}}int byteBufferLe ngth = Str_Se nd.Cou nt; byte[] byteBuffer = new byte[byteBufferLe ngth];in t ii = 0;//decNum = Con vert.ToI nt32(Str_Se nd[i], 16); // 把字符串转成16进制数〃byteBuffer[ii] = Co nvert.ToByte(decNum);〃}try{decNum = Con vert.ToI nt32(Str_Se nd[i], 16); // 把字符串转成16进制数byteBuffer[ii] = Co nvert.ToByte(decNum);}catch (System.Exceptio n ex){MessageBox.Show(”输入错误!","提示");return;}ii++;}sp1.Write(byteBuffer, 0, byteBuffer.Length);// 从第0个开始写入byteBuffer ,长度bytebuffer 的长度。
C语言串口通信助手代码
该程序全部由C写成没有C++更没用MFC完全是自娱自乐给需要的人一个参考#include "stdafx.h"#include <windowsx.h>#include "resource.h"#include "MainDlg.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>HANDLE hComm;/用于获取串口打开函数的返回值(句柄或错误值) OVERLAPPED m_ov;COMSTAT comstat;DWORD m_dwCommEvents;TCHAR cRecs[200],cSends[100]; 接//收字符串发送字符串char j=0,*cCom; //接收用统计数据大小变量端口选择BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam){switch(uMsg){HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);}return FALSE;}/* 系统初始化函数*/BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAMlParam){HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);ComboBox_InsertString(hwndCombo1,-1,TEXT("COM1"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM2"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM3"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM4"));ComboBox_InsertString(hwndCombo1,-1,TEXT("COM5"));ComboBox_SetCurSel(hwndCombo1,0);void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID,DWORD dwTime);SetTimer(hwnd,1,1000,TimerProc);return TRUE;}/* 监视串口错误时使用的函数*/boolProcessErrorMessage(char* ErrorText)char *Temp = new char[200];LPVOID lpMsgBuf;FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Defaultlanguage(LPTSTR) &lpMsgBuf,0,NULL);sprintf(Temp, "WARNING: %s Failed with the following error:\n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, "com2");MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);LocalFree(lpMsgBuf);delete[] Temp;return true;}boolopenport(char *portname)// 打开串口{hComm = CreateFile(portname, //串口号“ comT “ cc调用方法:bool open;open=openport("com2");GENERIC_READ | GENERIC_WRIT允许读写0, //通讯设备必须以独占方式打开0, // 无安全属性OPEN_EXISTING,通讯设备已存在FILE_FLAG_OVERLAPPED异步I/O0); //通讯设备不能用模板打开if (hComm == INVALID_HANDLE_VALUE如/果被占用或是没有打开时返回的是这个错误代码{CloseHandle(hComm);return FALSE;}elsereturn true;}boolsetupdcb(intrate_arg)// 设置port 的属性{DCB dcb;int rate= rate_arg;memset(&dcb,0,sizeof(dcb));if(!GetCommState(hComm,&dcb))〃获取当前DCB配置return FALSE;// set DCB to configure the serial portdcb.DCBlength = sizeof(dcb);dcb.BaudRate = rate;dcb.Parity = NOPARITY; 奇// 偶校验值0~4分别对应无校验、奇校验、偶校验、校验置位、校验清零dcb.fParity = 0; //为1的话激活奇偶校验检查dcb.StopBits = ONESTOPBIT停止位个数,0~2分别对应1位、1.5位、2位停止位dcb.ByteSize = 8; //数据位数dcb.fOutxCtsFlow = 0;dcb.fOutxDsrFlow = 0;dcb.fDtrControl = DTR_CONTROL_DISABLE;dcb.fDsrSensitivity = 0;dcb.fRtsControl = RTS_CONTROL_DISABLE;dcb.fOutX = 0;dcb.fInX = 0;dcb.fErrorChar = 0;dcb.fBinary = 1;dcb.fNull = 0;dcb.fAbortOnError = 0;dcb.wReserved = 0;dcb.XonLim = 2;dcb.XoffLim = 4;dcb.XonChar = 0x13;dcb.XoffChar = 0x19;dcb.EvtChar = 0;// set DCBif(!SetCommState(hComm,&dcb))return false;elsereturn true;}/* 串口读取相关时间设置*/boolsetuptimeout(DWORDReadInterval,DWORDReadTotalMultiplier,DWORDReadTotalconstant,DWORDW riteTotalMultiplier,DWORDWriteTotalconstant){COMMTIMEOUTS timeouts;timeouts.ReadIntervalTimeout=ReadInterval; // 读取两个字节间隔最大值mS 如超过立即返回不再读取timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //如果同下面一个都为0 则无论是否读到数据都返回// 可以毫秒为单位指定一个乘数,该乘数用来计算读操作的总限时时间timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; // 以毫秒为单位指定一个常数,用于计算读操作的总限时时间0 表示不限时timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;// 写操作延时同上timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;if(!SetCommTimeouts(hComm, &timeouts))return false;elsereturn true;}intClearn() // 清除buff 中的内容并返回buff 中现有数据量的大小并读取错误原因{DWORD dwError = 0;DWORD BytesRead = 0;ClearCommError(hComm, &dwError, &comstat);return comstat.cbInQue; // 返回buff 中数据量}/* 串口数据接收读取函数*/void ReceiveChar(){BOOL bRead = TRUE;BOOL bResult = TRUE;DWORD dwError = 0;DWORD BytesRead = 0;char i=0,n;char RXBuff;j=0;while (i-n){n=i;Sleep(10);bResult = ClearCommError(hComm, &dwError, &comstat); i=(char)comstat.cbInQue;}for (;i>0;i--)if (bRead)bResult = ReadFile(hComm, // Handle to COMM port &RXBuff, // RX Buffer Pointer1, // Read one byte&BytesRead, // Stores number of bytes read&m_ov); // pointer to the m_ov structure// printf("%c",RXBuff);cRecs[j++]=(char)RXBuff;if (!bResult){switch (dwError = GetLastError()){case ERROR_IO_PENDING:{bRead = FALSE;break;}default: break;}}elsebRead = TRUE; // close if (bRead)if (!bRead)bRead = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port&m_ov, // Overlapped structure&BytesRead, // Stores number of bytes readTRUE); // Wait flag}}}boolWriteChar(char* m_szWriteBuffer,DWORDm_nToSend) //写字符的函数{BOOL bWrite = TRUE;BOOL bResult = TRUE;DWORD BytesSent = 0;HANDLE m_hWriteEvent;ResetEvent(m_hWriteEvent);if (bWrite){m_ov.Offset = 0;m_ov.OffsetHigh = 0;// Clear bufferbResult = WriteFile(hComm, // Handle to COMM Portm_szWriteBuffer, // Pointer to message buffer in calling finctionm_nToSend, // Length of message to send&BytesSent, // Where to store the number of bytes sent&m_ov ); // Overlapped structureif (!bResult)DWORD dwError = GetLastError();switch (dwError){case ERROR_IO_PENDING:{// continue to GetOverlappedResults()BytesSent = 0;bWrite = FALSE;break;}default:// all other error codesbreak;}}} // end if(bWrite)if (!bWrite){bWrite = TRUE;bResult = GetOverlappedResult(hComm, // Handle to COMM port&m_ov, // Overlapped structure&BytesSent, // Stores number of bytes sentTRUE); // Wait flag// deal with the error codeif (!bResult){printf("GetOverlappedResults() in WriteFile()");}} // end if (!bWrite)// Verify that the data size send equals what we tried to sendif (BytesSent != m_nToSend){printf("WARNING: WriteFile() error.. Bytes Sent: %d; MessageLength: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));}return true;}/*window 时间函数回调*/void CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID,DWORD dwTime){SYSTEMTIME time; /定/ 义机构体变量timeGetLocalTime(&time); // 取系统时间以指针方式TCHAR strTime[256]; //程序只有一个作用wsprintf(strTime,"%04d-%02d-%02d %02d:%02d:%02d",time.wYear, /就/ 是读取系统时间time.wMonth,time.wDay,time.wHour,time.wMinute,time.wSecond);// 然后写进strTimeSetDlgItemText(hwnd,IDC_TIME,strTime); /这/ 个字符串}void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINTcodeNotify) {switch(id){case IDC_SEND:{GetDlgItemText (hwnd,IDC_EDIT2,cSends,sizeof(cSends));un sig ned n二sizeof(cSe nds); 〃n是通知串口将发送字节的长度char send[100];wsprintf (send,"%s",cSends);WriteChar(send,n-1);SetCommMask(hComm, EV_RXCHAR)监视串口是否接收有数据ReceiveChar(); /读取串口sbuff 中数据cRecs[j]='\0'; // 将cRecs转为字符串SetDlgItemText(hwnd,IDC_EDIT1,cRecs);} break;/*case IDC_RECEIVE暂时未用采用直接显示的方式{}break;*/case IDC_CHECK:{intctr;HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1);ctr = ComboBox_GetCurSel(hwndCombo1);switch (ctr){case 0:cCom="com1";break;case 1:cCom="com2";break;case 2:cCom="com3";break;case 3:cCom="com4";break;case 4:cCom="com5";break;default: cCom="com1";break;}if (openport(cCom))Ko t pu/v\q)6o|8!apu3}(pu/v\u aNMH)eso|9UO_uie|/\| p|OA{{ 制eaiq4ine)ep91 / 91{X丄doavxi_39dnd I 丄doavxd_39dndI dV^IOXl^Odnd I dV319Xd_39dnd l ujuj09M)ujuj09e6jndK.. iWWMB ^^lia^-QarpuMM^xe 丄UJ 引Qimes esp K.. 宙17丄ICH—OCirpu/v\U)1xe丄UJ引Qimes0096 重畀徹刑圜口宙刑畀似 //((000 i1021010>20 Oinoeujudrnes^(o096)qopdrnes)j!K H IIV Z I./C丄ICH—OCirpu/v\U)!xe 丄UJ 引Qimes esp{ KO1...?., i ^..t PUMM)xoae6esse|A|■Ci >10.?£丄ICH—OCIlTu/v\Mxe丄ujeWimes }。
经典串口调试助手源程序及串口通信设置
经典串口调试助手源程序及串口通信设置串口调试助手是一种用于串口通信调试的工具,它可以通过串口与外部设备进行数据的读写和处理,常用于单片机、嵌入式系统、电子设备等领域的开发调试中。
经典串口调试助手源程序经典串口调试助手是一款经典的串口调试工具,其源程序使用C语言编写,提供了丰富的功能和易于使用的界面,被广泛应用于各种领域的开发调试中。
该工具可以在Windows操作系统中运行,并支持多种串口通信协议,包括RS232、RS485、RS422等。
以下是经典串口调试助手部分源程序的示例:```c// 打开串口HANDLE OpenSerialPort(const char* portName){ HANDLE hCom; hCom = CreateFile(portName, // 串口名称GENERIC_READ | GENERIC_WRITE, // 读写访问0,// 无共享NULL,// 安全描述符OPEN_EXISTING,// 打开方式FILE_ATTRIBUTE_NORMAL, // 文件属性NULL); // 文件模板if (hCom ==INVALID_HANDLE_VALUE) // 判断是否打开成功{ return NULL; } return hCom;}// 发送数据int SendData(HANDLE hCom, const char* data, int len){ DWORD writeSize; if (!WriteFile(hCom, data, len, &writeSize, NULL)) // 写入数据{ return -1; } return writeSize;}// 接收数据int ReceiveData(HANDLE hCom, char* data, int len){ DWORD readSize; if (!ReadFile(hCom, data, len,&readSize, NULL)) // 读取数据{ return -1; } return readSize;}// 关闭串口int CloseSerialPort(HANDLE hCom){ if(!CloseHandle(hCom)) // 关闭句柄{ return-1; } return 0;}```上述函数实现了打开串口、发送数据、接收数据和关闭串口等基本功能,可以作为串口通信的底层驱动实现。
经典的串口调试工具源代码(二)
经典的串口调试工具源代码(二)Private Sub cmdswitch_Click()On Error GoTo ErrIf MSComm.PortOpen = True ThenComSwitch = TrueElseComSwitch = FalseEnd IfIf ComSwitch = False ThenStatusBar1.Panels(1).Text = "Connected"mnuconnect.Caption = "Dis&connect"OpenCom ' 打开串口ComSwitch = TrueElseCloseCom ' 关闭串口ComSwitch = FalseStatusBar1.Panels(1).Text = "Disconnected"mnuconnect.Caption = "&Connect"StatusBar1.Panels(2).Text = "COM" & mPort StatusBar1.Panels(3).Text = MSComm.SettingsIf (OutputAscii) ThenStatusBar1.Panels(4) = "ASCII"ElseStatusBar1.Panels(4) = "HEX"End IfEnd IfErr:End SubPrivate Sub Form_Load()On Error GoTo ErrlblWEB.FontUnderline = True ' WEB上加下划线lblWEB.ForeColor = vbBlue ' 蓝色显示WEBtxtsend.Text = "" ' 载入发送信息If MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭' 初始化串口Call Comm_initial(Val(Mid(cbocom.Text, 4, 1)), cbobaudrate.Text, Left(cboparitybit.Text, 1),cbodatabit.Text, cbostopbit.Text)' 数据位载入cbodatabit.AddItem "8"cbodatabit.AddItem "7"cbodatabit.AddItem "6"' 停止位载入cbostopbit.AddItem "1"cbostopbit.AddItem "1.5"cbostopbit.AddItem "2"Err:End SubPrivate Sub hexReceive()On Error GoTo ErrDim ReceiveArr() As Byte ' 接收数据数组Dim receiveData As String ' 数据暂存Dim Counter As Integer ' 接收数据个数计数器Dim i As Integer ' 循环变量If (MSComm.InBufferCount > 0) ThenCounter = MSComm.InBufferCount ' 读取接收数据个数receiveData = "" ' 清缓冲ReceiveArr = MSComm.Input ' 数据放入数组For i = 0 To (Counter - 1) Step 1 ' 数据格式处理If (ReceiveArr(i) < 16) ThenreceiveData = receiveData & "0" + Hex(ReceiveArr(i)) & Space(1) ' 小于16,前面加0ElsereceiveData = receiveData & Hex(ReceiveArr(i)) & Space(1) ' 加空格显示End IfNext iTxtReceive.Text = TxtReceive.Text + receiveData ' 显示接收的十六进制数据TxtReceive.SelStart = Len(TxtReceive.Text) ' 显示光标位置End IfReceiveCount = ReceiveCount + Counter ' 接收计数txtRXcount.Text = "RX:" & ReceiveCount ' 接收字节数显示If chkautoclear.Value = 1 Then ' 自动清空判断If ReceiveCount >= 65535 ThenTxtReceive.Text = ""End IfEnd IfErr:End SubPrivate Sub hexSend()On Error Resume NextDim outputLen As Integer ' 发送数据长度Dim outData As String ' 发送数据暂存Dim SendArr() As Byte ' 发送数组Dim TemporarySave As String ' 数据暂存Dim dataCount As Integer ' 数据个数计数Dim i As Integer ' 局部变量outData = UCase(Replace(txtsend.Text, Space(1), Space(0))) ' 先去掉空格,再转换为大写字母outData = UCase(outData) ' 转换成大写outputLen = Len(outData) ' 数据长度For i = 0 To outputLenTemporarySave = Mid(outData, i + 1, 1) ' 取一位数据If (Asc(TemporarySave) >= 48 And Asc(TemporarySave) <= 57) Or (Asc(TemporarySave) >= 65And Asc(TemporarySave) <= 70) ThendataCount = dataCount + 1ElseExit ForExit SubEnd IfNextIf dataCount Mod 2 <> 0 Then ' 判断十六进制数据是否为双数dataCount = dataCount - 1 ' 不是双数,则减1End IfoutData = Left(outData, dataCount) ' 取出有效的十六进制数据ReDim SendArr(dataCount / 2 - 1) ' 重新定义数组长度For i = 0 To dataCount / 2 - 1SendArr(i) = Val("&H" + Mid(outData, i * 2 + 1, 2)) ' 取出数据转换成十六进制并放入数组中NextSendCount = SendCount + (dataCount / 2) ' 计算总发送数txtTXcount.Text = "TX:" & SendCountMSComm.Output = SendArr ' 发送数据End SubPrivate Sub OpenCom() '打开串口On Error GoTo ErrIf MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭Call Comm_reSet(Val(Mid(cbocom.Text, 4, 1)), cbobaudrate.Text, Left(cboparitybit.Text, 1),cbodatabit.Text, cbostopbit.Text) ' 串口设置If MSComm.PortOpen = True Thentxtstatus.Text = "STATUS:" & cbocom.Text & " OPEND," & cbobaudrate.Text & "," & Left(cboparitybit.Text, 1) & "," & cbodatabit.Text & "," & cbostopbit.Textcmdswitch.Caption = "关闭串口"mnuconnect.Caption = "disconnect"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\kai.jpg") ' 显示串口已经打开的图标ImgSwitchon.Visible = TrueImgSwitchoff.Visible = FalseElsetxtstatus.Text = "STATUS:COM Port Cloced" ' 串口状态显示cmdswitch.Caption = "打开串口"mnuconnect.Caption = "connect"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\guan.jpg") ' 显示串口已经关闭的图标ImgSwitchoff.Visible = TrueImgSwitchon.Visible = FalseEnd IfErr:End SubPrivate Sub textReceive()On Error GoTo ErrInputSignal = MSComm.InputReceiveCount = ReceiveCount + LenB(StrConv(InputSignal, vbFromUnicode)) ' 计算总接收数据If DisplaySwitch = False Then ' 显示接收文本TxtReceive.Text = TxtReceive.Text & InputSignal ' 单片机内存的值用TextReceive显示出TxtReceive.SelStart = Len(TxtReceive.Text) ' 显示光标位置End IftxtRXcount.Text = "RX:" & ReceiveCount ' 接收字节数显示If chkautoclear.Value = 1 Then ' 自动清空判断If ReceiveCount >= 65535 ThenTxtReceive.Text = ""End IfEnd IfErr:End SubPrivate Sub textSend()On Error GoTo ErrIf ModeSend = True ThenOutputSignal = FileData ' 发送文件ElseOutputSignal = txtsend.Text ' 发送文本End IfSendCount = SendCount + LenB(StrConv(OutputSignal, vbFromUnicode)) ' 计算总发送数txtTXcount.Text = "TX:" & SendCount ' 发送字节数显示Err:End SubPrivate Sub Image1_Click()End SubPrivate Sub mnuautosend_Click()On Error GoTo Err'If TmrAutoSend.Enabled = True Then ' 如果有效则,自动发送If MSComm.PortOpen = True Then ' 串口状态判断ChkAutoSend.Value = 1TmrAutoSend.Interval = Val(TxtAutoSendTime) ' 设置自动发送时间mnuautosend.Caption = "取消自动发送"TmrAutoSend.Enabled = True ' 打开自动发送定时器Elsemnuautosend.Caption = "自动发送"ChkAutoSend.Value = 0 ' 串口没有打开去掉自动发送MsgBox "串口没有打开,请打开串口", 48, "串口调试助手" ' 如果串口没有被打开,提示打开串口End If'ElseIf TmrAutoSend.Enabled = False Then ' 如果无效,不发送' mnuautosend.Caption = "autosend"' TmrAutoSend.Enabled = False ' 关闭自动发送定时器'End IfErr:End SubPrivate Sub mnucom_Click(Index As Integer)Dim i As IntegerDim OldPort As LongOn Error Resume NextWith MSCommOldPort = .CommPortIf MSComm.PortOpen Then.PortOpen = False.CommPort = Index.PortOpen = TrueIf Err.Number <> 0 Then ' This should not happen...MsgBox "Com" & Index & " is not available." & _vbCrLf & Err.DescriptionErr.Clear.CommPort = OldPortElseFor i = 1 To 4mnucom(i).Checked = FalseNext imnucom(Index).Checked = TrueEnd IfElse.CommPort = IndexFor i = 1 To 4mnucom(i).Checked = FalseNext imnucom(Index).Checked = TrueEnd IfEnd WithUpdateStatusEnd SubPrivate Sub mnuconnect_Click()On Error Resume NextIf MSComm.PortOpen = True ThenComSwitch = TrueElseComSwitch = FalseEnd IfWith MSCommIf .PortOpen = True Then.PortOpen = Falsetxtstatus.Text = "STATUS:COM Port Cloced" ' 串口状态显示cmdswitch.Caption = "打开串口"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\guan.jpg") ' 显示串口已经关闭的图标ImgSwitchoff.Visible = TrueImgSwitchon.Visible = FalseElse.PortOpen = TrueComSwitch = Truetxtstatus.Text = "STATUS:" & cbocom.Text & " OPEND," & cbobaudrate.Text & "," & Left(cboparitybit.Text, 1) & "," & cbodatabit.Text & "," & cbostopbit.Textcmdswitch.Caption = "关闭串口"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\kai.jpg") ' 显示串口已经打开的图标ImgSwitchon.Visible = TrueImgSwitchoff.Visible = FalseIf Err.Number <> 0 ThenMsgBox "Com" & .CommPort & " is not available." & vbCrLf & _Err.DescriptionErr.ClearEnd IfEnd IfEnd WithUpdateStatusEnd SubPrivate Sub mnusave_Click()On Error GoTo Err ' 错误处理SaveTextPath = txtsavepath ' 路径暂存Open txtsavepath & "\1.txt" For Output As #1 ' 打开文件' 不存在的话会创建文件,如已存在会覆盖' output 改为append 为追加' 改为input 则只读Print #1, Year(Date) & "年" & Month(Date) & "月" & Day(Date) & _"日" & Hour(Time) & "时" & Minute(Time) & "分" & Second(Time) & _"秒" & vbCrLf & TxtReceive.Text + vbCrLf ' 把接收区的文本保存文本前加上保存时间(0000年00月00日00时00分00秒)' vbcrlf 为回车换行Close #1 ' 关闭文件txtsavepath = "OK,1.txt Save" ' 提示保存成功cmdsavedisp.Enabled = FalseSavetime = Timer ' 记下开始的时间While Timer < Savetime + 5 ' 循环等待5 - 要延时的时间DoEvents ' 转让控制权,以便让操作系统处理其它的事件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/article/446.html/hinzn/blog/item/4e81b4459b390a2ecffca3bb.html/modeng_2005/blog/static/265611200981142011329//mod eng_2005/blog/static/265611200981142011329/Dim OutputAscii As BooleanDim InputString As StringDim OutputString As String'============================================================================== =======' 变量定义'============================================================================== =======Option Explicit ' 强制显式声明Dim ComSwitch As Boolean ' 串口开关状态判断Dim FileData As String ' 要发送的文件暂存Dim SendCount As Long ' 发送数据字节计数器Dim ReceiveCount As Long ' 接收数据字节计数器Dim InputSignal As String ' 接收缓冲暂存Dim OutputSignal As String ' 发送数据暂存Dim DisplaySwitch As Boolean ' 显示开关Dim ModeSend As Boolean ' 发送方式判断Dim Savetime As Single ' 时间数据暂存延时用Dim SaveTextPath As String ' 保存文本路径' 网页超链接申明Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPrivate Sub CloseCom() '关闭串口On Error GoTo ErrIf MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭txtstatus.Text = "STATUS:COM Port Cloced" ' 串口状态显示mnuconnect.Caption = "断开串口"cmdswitch.Caption = "打开串口"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\guan.jpg") ' 显示串口已经关闭的图标ImgSwitchoff.Visible = TrueImgSwitchon.Visible = FalseErr:End SubPrivate Sub UpdateStatus()If MSComm.PortOpen ThenStatusBar1.Panels(1).Text = "Connected"mnuautosend.Caption = "自动发送"mnuconnect.Caption = "断开串口"ElseStatusBar1.Panels(1).Text = "断开串口"mnuautosend.Caption = "disautosend"mnuconnect.Caption = "打开串口"End IfStatusBar1.Panels(2).Text = "COM" & mPortStatusBar1.Panels(3).Text = MSComm.SettingsIf (OutputAscii) ThenStatusBar1.Panels(4) = "ASCII"ElseStatusBar1.Panels(4) = "HEX"End If'On Error GoT o ErrIf ChkAutoSend.Value = 1 Then ' 如果有效则,自动发送If MSComm.PortOpen = True Then ' 串口状态判断mnuautosend.Caption = "Dis&autosend"TmrAutoSend.Interval = Val(TxtAutoSendTime) ' 设置自动发送时间TmrAutoSend.Enabled = True ' 打开自动发送定时器Elsemnuautosend.Caption = "autosend"ChkAutoSend.Value = 0 ' 串口没有打开去掉自动发送MsgBox "串口没有打开,请打开串口", 48, "串口调试助手" ' 如果串口没有被打开,提示打开串口End IfElseIf ChkAutoSend.Value = 0 Then ' 如果无效,不发送mnuautosend.Caption = "autosend"TmrAutoSend.Enabled = False ' 关闭自动发送定时器End IfErr:End SubPrivate Sub CmdSendFile_Click() '发送文件On Error GoTo ErrIf MSComm.PortOpen = True Then ' 如果串口打开了,则可以发送数据If FileData = "" Then ' 判断发送数据是否为空MsgBox "发送的文件为空", 16, "串口调试助手" ' 发送数据为空则提示ElseIf ChkHexReceive.Value = 1 Then ' 如果按十六进制接收时,按二进制发送,否则按文本发送MSComm.InputMode = comInputModeBinary ' 二进制发送ElseMSComm.InputMode = comInputModeText ' 文本发送End IfMSComm.Output = Trim(FileData) ' 发送数据ModeSend = True ' 设置文本发送方式End IfElseMsgBox "串口没有打开,请打开串口", 48, "串口调试助手" ' 如果串口没有被打开,提示打开串口End IfErr:End SubPrivate Sub Comm_initial(Port As Byte, BaudRate As String, ParityBit As String, DataBit As Integer, StopBit As Integer)On Error GoTo ErrorTrap ' 错误则跳往错误处理If MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭mPort = Port ' 设定端口MSComm.Settings = BaudRate & "," & ParityBit & "," & DataBit & "," & StopBit ' 设置波特率,无校验,8位数据位,1位停止位MSComm.InBufferSize = 1024 ' 设置接收缓冲区为1024字节MSComm.OutBufferSize = 4096 ' 设置发送缓冲区为4096字节MSComm.InBufferCount = 0 ' 清空输入缓冲区MSComm.OutBufferCount = 0 ' 清空输出缓冲区MSComm.SThreshold = 1 ' 发送缓冲区空触发发送事件MSComm.RThreshold = 1 ' 每X个字符到接收缓冲区引起触发接收事件MSComm.OutBufferCount = 0 ' 清空发送缓冲区MSComm.InBufferCount = 0 ' 滑空接收缓冲MSComm.PortOpen = True ' 打开串口If MSComm.PortOpen = True Thentxtstatus.Text = "STATUS:" & cbocom.Text & " OPEND," & cbobaudrate.Text & "," & Left(cboparitybit.Text, 1) & "," & cbodatabit.Text & "," & cbostopbit.TextElsetxtstatus.Text = "STATUS:COM Port Cloced" ' 串口没打开时,提示串口关闭状态End IfExit SubErrorTrap: ' 错误处理Select Case Err.NumberCase comPortAlreadyOpen ' 如果串口已经打开,则提示MsgBox "没有发现此串口或被占用", 49, "串口调试助手"CloseComCase ElseMsgBox "没有发现此串口或被占用", 49, "串口调试助手"CloseComEnd SelectErr.ClearEnd SubPrivate Sub Comm_reSet(Port As Byte, BaudRate As String, ParityBit As String, DataBit As Integer,StopBit As Integer)On Error GoTo ErrorHint ' 错误则跳往错误处理If MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭mPort = Port ' 设定端口MSComm.Settings = BaudRate & "," & ParityBit & "," & DataBit & "," & StopBit ' 设置波特率,无校验,8位数据位,1位停止位MSComm.PortOpen = True ' 打开串口If MSComm.PortOpen = True Thencmdswitch.Caption = "关闭串口"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\kai.jpg") ' 显示串口已经打开的图标ImgSwitchoff.Visible = Falsemnuconnect.Caption = "disconnect"ImgSwitchon.Visible = Truetxtstatus.Text = "STATUS:" & cbocom.Text & " OPEND," & cbobaudrate.Text & "," & Left(cboparitybit.Text, 1) & "," & cbodatabit.Text & "," & cbostopbit.TextElsecmdswitch.Caption = "打开串口"'ImgSwitch.Picture = LoadPicture("f:\我的VB\串口调试软件\图片\guan.jpg") ' 显示串口已经关闭的图标ImgSwitchon.Visible = FalseImgSwitchoff.Visible = Truetxtstatus.Text = "STATUS:COM Port Cloced"End IfExit SubErrorHint: ' 错误处理Select Case Err.NumberCase comPortAlreadyOpen ' 如果串口已经打开,则提示MsgBox "没有成功,请重试", vbExclamation, "串口调试助手"CloseCom ' 调用关闭串口函数Case ElseMsgBox "没有成功,请重试", vbExclamation, "串口调试助手"CloseCom ' 调用关闭串口函数End SelectErr.Clear ' 清除Err 对象的属性End SubPrivate Sub Command1_Click()End SubPrivate Sub cbobaudrate_Change()Call Comm_reSet(Val(Mid(cbocom.Text, 4, 2)), cbobaudrate.Text, Left(cboparitybit.Text, 1), cbodatabit.Text, cbostopbit.Text) '串口设置End SubPrivate Sub cbocom_Change()Call Comm_reSet(Val(Mid(cbocom.Text, 4, 2)), cbobaudrate.Text, Left(cboparitybit.Text, 1), cbodatabit.Text, cbostopbit.Text) '串口设置End SubPrivate Sub cbodatabit_Change()Call Comm_reSet(Val(Mid(cbocom.Text, 4, 2)), cbobaudrate.Text, Left(cboparitybit.Text, 1), cbodatabit.Text, cbostopbit.Text) '串口设置End SubPrivate Sub cboparitybit_Change()Call Comm_reSet(Val(Mid(cbocom.Text, 4, 2)), cbobaudrate.Text, Left(cboparitybit.Text, 1), cbodatabit.Text, cbostopbit.Text) '串口设置End SubPrivate Sub cbostopbit_Change()Call Comm_reSet(Val(Mid(cbocom.Text, 4, 2)), cbobaudrate.Text, Left(cboparitybit.Text, 1), cbodatabit.Text, cbostopbit.Text) '串口设置End SubPrivate Sub chkautosend_Click()On Error GoTo ErrIf ChkAutoSend.Value = 1 Then ' 如果有效则,自动发送If MSComm.PortOpen = True Then ' 串口状态判断mnuautosend.Caption = "取消自动发送"TmrAutoSend.Interval = Val(TxtAutoSendTime) ' 设置自动发送时间TmrAutoSend.Enabled = True ' 打开自动发送定时器ElseChkAutoSend.Value = 0 ' 串口没有打开去掉自动发送MsgBox "串口没有打开,请打开串口", 48, "串口调试助手" ' 如果串口没有被打开,提示打开串口End IfElseIf ChkAutoSend.Value = 0 Then ' 如果无效,不发送mnuautosend.Caption = "自动发送数据"TmrAutoSend.Enabled = False ' 关闭自动发送定时器End IfErr:End SubPrivate Sub cmdamend_Click()Dim spShell As Object ' 定义存放引用对象的变量Dim spFolder As Object ' 定义存放引用对象的变量Dim spFolderItem As Object ' 定义存放引用对象的变量Dim spPath As String ' 定义存放的变量On Error GoTo Err ' 错误处理,防止取消打开文件夹时报错Const WINDOW_HANDLE = 0Const NO_OPTIONS = 0Set spShell = CreateObject("Shell.Application")Set spFolder = spShell.BrowseForFolder(WINDOW_HANDLE, "选择目录:", NO_OPTIONS, "C:\Scripts")Set spFolderItem = spFolder.SelfspPath = spFolderItem.PathspPath = Replace(spPath, "\", "\") ' Replace函数的返回值是一个字符串txtsavepath.Text = spPath ' 把文件夹路径显示在标签上SaveTextPath = txtsavepath.Text ' 路径暂存Err:End SubPrivate Sub CmdClearCounter_Click()On Error GoTo ErrSendCount = 0 ' 发送计数器清零ReceiveCount = 0 ' 接收计数器清零txtRXcount.Text = "RX:" & 0 ' 接收计数txtTXcount.Text = "TX:" & 0 ' 发送计数Err:End SubPrivate Sub cmdclearrecieve_Click()TxtReceive.Text = ""End SubPrivate Sub cmdclearsend_Click()txtsend.Text = ""End SubPrivate Sub CmdHelp_Click()FrmHelp.ShowEnd SubPrivate Sub CmdQuit_Click()If MSComm.PortOpen = True Then MSComm.PortOpen = False ' 先判断串口是否打开,如果打开则先关闭Unload Me ' 卸载窗体,并退出程序EndEnd SubPrivate Sub cmdsavedisp_Click()On Error GoTo Err ' 错误处理SaveTextPath = txtsavepath ' 路径暂存Open txtsavepath & "\1.txt" For Output As #1 ' 打开文件' 不存在的话会创建文件,如已存在会覆盖' output 改为append 为追加' 改为input 则只读Print #1, Year(Date) & "年" & Month(Date) & "月" & Day(Date) & _"日" & Hour(Time) & "时" & Minute(Time) & "分" & Second(Time) & _"秒" & vbCrLf & TxtReceive.Text + vbCrLf ' 把接收区的文本保存文本前加上保存时间(0000年00月00日00时00分00秒)' vbcrlf 为回车换行Close #1 ' 关闭文件txtsavepath = "OK,1.txt Save" ' 提示保存成功cmdsavedisp.Enabled = FalseSavetime = Timer ' 记下开始的时间While Timer < Savetime + 5 ' 循环等待5 - 要延时的时间DoEvents ' 转让控制权,以便让操作系统处理其它的事件。