其于MFC的串口调试助手编辑过程
一、新建
打开VC6.0 文件新建工程 MFC AppWiard(exe) 位置(选择保存工程位置)工程名称(输入工程名XXXX)确定选择基本对话框下一步下一步下一步选择(CXXXXDlg)完成确定在生成的基本对话框内将不需要按钮及提示框(自动生成的“确定”“取消”及提示框)删除或修改使用,至此基本框架完成如下图:
二、往生成的基本框架中添加控件
1、因为控件列表框内没有串口通信用到的通信控件,所以要先添加到控件列表框内再
将控件添加到基本框内使用,步骤如下:
菜单栏工程添加到工程Components and controls…
Registered ActiveX Controls 选择“Microsoft Communications Control, version
6.0” Insert
确定 OK 关闭此子窗口完成添加操作标志如上图所示。
2、将刚才添加添加到控件列表框内的串口控件添加到基本框架内
点击控件列表框内的串口控件,此时光标变为“十”形,在基本框架内随意划取一矩形区域,即可以添加串口控件,不需要修改此控件的大小及位置,因为程编译运行后此控件是看不到的,步骤结果如下图:此控件(标志)是下面步骤添加进来的串口控件
基本框架
3、继续往基本框架内添加用于编辑发送数据的输入编辑框及输出编辑框,同理选择控
件列表框内的“编辑框控件”,以相同的操作即可添加两个编辑窗口及一个按纽控件如
下图所示:
选择其中任
意一个作为
输入编辑框
及输出编辑
框
这两个窗口需要修改大小及位置,因为程序运行后将会显示而串口通信控件则不显示,
上图是运行后的效果。
4、对以上四个控件编程步骤如下:
a、右击串口通信控件建立类向导 Member variables Control IDS中
选择IDC_MSCOMM1 add variable… Member variable name中输入控件变量名
m_ctrlComm(变量名可以随意选取,但程序中应与所取变量名一致) OK 确定
b、右击编辑框、属性、常规、ID:中输入ID号,此编辑框用于接收显示数据的其ID 号为IDC_EDIT_RXDATA(可以随意选取,但程序中应与所取ID号一致),再在此窗口的样式中勾选”多行”,同时将“自动水平滚动(T)”勾选去掉,再勾选“垂直滚动(V)”,此勾选操作是用于垂直多行显示的,按回车后即可输入;同理右击另一编辑框输入ID号为IDC_EDIT_TXDATA此编辑框用于编辑发送数据的,同样也选上用于垂直多行显示,发送框可以不用垂直多行显示;再为按钮控件添加ID号,为IDC_BUTTON_MANUALSEND,并将标题中的“Button1”改为“发送”,功能是按一次就把发送编辑框中的内容发送一次。
C、为以上两个编辑框添加变量,与串口通信控件一样添加,为IDC_EDIT_RXDATA添加CString型变量m_strRXData ;为IDC_EDIT_TXDATA添加CString型变量m_strTXData。说明: m_strRXData和m_strTXData分别用来放入接收和发送的字符数据。
D、添加串口事件消息处理函数OnComm() 打开ClassWizard->Message Maps,选择IDC_MSCOMM1,双击消息OnComm,将弹出的对话框中将函数名改为OnComm,(好记而已)OK。
这个函数是用来处理串口消息事件的,如每当串口接收到数据,就会产生一个串口接收数据缓冲区中有字符的消息事件,我们刚才添加的函数就会执行,我们在OnComm()
代码段1:
void CScommTestDlg::OnComm()
{
VARIANT variant_inp;//定义一个VARIANT类对象
COleSafeArray safearray_inp;//定义一个COleSafeArray对象
LONG len,k;
BYTE rxdata[2048];//设置BYTE数组 AN 8—intterthat is not signed.
CString strtemp;
if (m_ctrlComm.GetCommEvent()==2)//事件值为2表示接收缓冲区内有数据
{
////以下你可以根据自己的通信协议加入处理代码
variant_inp=m_ctrlComm.GetInput();//读缓冲区
safearray_inp=variant_inp;//VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize();
for(k=0;k { safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组} 将数组转换为Cstring型变量 BYTE bt=*(char*)(rxdata+k); 如果是HEX显示则转为16进制 strtemp.Format("%02x ",bt); //将16进制数送入临时变量strtemp存// else strtemp.Format("%c",bt);//将字符送入临时变量strtemp存放 m_strRXData+=strtemp;//加入接收编辑框对应字符串 } } UpdateData(FALSE);//更新编辑框内容(主要是接收编辑框中的) } 到目前为止还不能在接收编辑框中看到数据,因为我们还没有打开串口,但运行程序不应该有任何错误,不然,你肯定哪儿没看仔细,因为我是打开VC6对照着做一步写一行的,运行试试。没错吧?那么做下一步: E、打开串口和设置串口参数你可以在你需要的时候打开串口,例如在程序中做一个开始按钮,在该按钮的处理函数中打开串口。现在我们在主对话框的CSCommTestDlg::OnInitDialog()打开串口,加入如下代码: 代码段2: BOOL CSCommTestDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } 打开软件时串口选择框默认显示COM1 m_BaudRate_M.SetCurSel(0);//打开软件时波特率选择框默认显示9600 m_Date_Select_M.SetCurSel(0);//打开软件时数据位选择框默认显示8 // m_StopBit_M.SetCurSel(0);//打开软件时停止位选择框默认显示1 // m_ParityCheck_M.SetCurSel(0);//打开软件时奇偶校验选择框默认显示无校验N //下面if语句用于打开默认串口 /************************************************************/ if(m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(FALSE);//关闭串口 } m_ctrlComm.SetCommPort(1);//打开软件时默认使用COM1串口 if(!m_ctrlComm.GetPortOpen()) { m_ctrlComm.SetPortOpen(TRUE);//打开串口 } else { AfxMessageBox("cannot open serial port"); } /*************************************************************/ m_ctrlComm.SetSettings("9600,n,8,1");//打开软件时端口设置默认为波特率9600,无校验位,8位数据,1位停止位 m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据 m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0 m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据 return TRUE; // return TRUE unless you set the focus to a control } F、发送数据,先为发送按钮添加一个单击消息即BN_CLICKED处理函数,打开ClassWizard->Message Maps,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED添加OnButtonManualsend()函数,并在函数中添加如下代码: 代码段3: void CSCommTestDlg::OnButtonManualsend() { // TODO: Add your control notification handler code here UpdateData(TRUE); //读取编辑框内容 m_ctrlComm.SetOutput(COleVariant(m_strTXData));//发送数据 } 此时运行程序,在发送编辑框中随意输入数,单击发送按钮,若出错则修改后再测试,直到成功再进行以下操作。 5、添加两个“组框”或“静态文本”控件,调整位置及大小,在标师处输入提示文字,这两个控件不用编程,效果如下图: 6、添加5个“静态文本”控件并由属性修改其标题,均不用编程,效果如下图: 7、添加5个“组框”控件,效果如下图: 逐一对各个组框属性编辑如下: 串口号: 常规 ID:IDC_COMBO_CommSelect 数据输入列表框项目(N):COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9(注意每输入一个数据选项以Ctrl+Enter回车后再输入下一个数据选项) 样式将“分类勾选去掉” 进入类向导添加变量,为IDC_COMBO_CommSelect添加一个value类int型变量m_Index,点击OK后,再添加一个Control类CComboBox型变量m_ComboBox点击OK 最后“确定” 波特率: 常规 ID:IDC_COMBO_BaudRate_Select 数据输入列表框项目(N):9600、14400、19200、38400、56000、57600、115200、128000、256000 样式将“分类勾选去掉” 进入类向导添加变量,为IDC_COMBO_BaudRate_Select添加一个value类int型变量m_ BaudRate点击OK后,再添加一个Control类CComboBox型变量m_ BaudRate_M点击OK最后“确定” 数据位: 常规 ID:IDC_COMBO_Date_Select 数据输入列表框项目(N):8、7、6、5、4 样式将“分类勾选去掉” 进入类向导添加变量,为IDC_COMBO_Date_Select添加一个value类int型变量m_Date_Select点击OK后,再添加一个Control类CComboBox型变量m_Date_Select _M 点击OK最后“确定” 停止位: 常规 ID:IDC_COMBO_StopBit 数据输入列表框项目(N):1、2 样式将“分类勾选去掉” 进入类向导添加变量,为IDC_COMBO_StopBit添加一个value类int型变量 m_StopBit点击OK后,再添加一个Control类CComboBox型变量m_StopBit_M点击OK 最后“确定” 奇偶校验位: 常规 ID:IDC_COMBO_ParityCheck 数据输入列表框项目(N):N、O、E、 样式将“分类勾选去掉” 进入类向导添加变量,为IDC_COMBO_ParityCheck添加一个value类int型变量 m_ParityCheck点击OK后,再添加一个Control类CComboBox型变量m_ParityCheck_M 点击OK最后“确定” 说明:以上数据配置添加的Control类CComboBox型变量可能用不到,但value类必须为int型 8、为各个列表框添加处理函数: A、在建立类向导中Message Maps ,object IDs中选中IDC_COMBO_CommSelect再在 Messages中选中CBN_SELCHANG双击后单击OK,再在Member funtions中双击刚才生成的函数进入程序编辑页面,添加程序代码如下: 代码段4: void CSCommTestDlg::OnSelchangeCOMBOCommSelect() { // TODO: Add your control notification handler code here m_Index=((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->GetCurSel();//当前选中的行 ((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->SetCurSel(m_Index);//设置当前选中的行的内容为显示的内容 if(m_ctrlComm.GetPortOpen())// 所以先判断当前串口是否打开 {//如果是打开的则先关闭 m_ctrlComm.SetPortOpen(FALSE);//关闭串口 } SetDlgItemText(IDC_BUTTON1,"打开串口");//将打开或关才按钮改为"打开串口" 状态 } B、同理为IDC_COMBO_BaudRate_Select添加处理函数程序代码如下: 代码段5: void CSCommTestDlg::OnSelchangeCOMBOBaudRateSelect() { // TODO: Add your control notification handler code here UpdateData(true); m_BaudRate=((CComboBox*)GetDlgItem(IDC_COMBO_BaudRate_Select))->GetCurSel(); //当前选中的行 ////***********************************************************/ ///根据当前选中的值进行波特率设置 ///************************************************************/ switch(m_BaudRate) { case 1: m_ctrlComm.SetSettings("14400,,,"); break; case 2: m_ctrlComm.SetSettings("19200,,,"); break; case 3: m_ctrlComm.SetSettings("38400,,,"); break; case 4: m_ctrlComm.SetSettings("56000,,,"); break; case 5: m_ctrlComm.SetSettings("57600,,,"); break; case 6: m_ctrlComm.SetSettings("115200,,,"); break; case 7: m_ctrlComm.SetSettings("128000,,,"); break; case 8: m_ctrlComm.SetSettings("256000,,,"); break; default:m_ctrlComm.SetSettings("9600,,,"); break; } //*************************************************//// UpdateData(false); } C、同理为IDC_COMBO_Date_Select添加处理函数程序代码如下: 代码段6: void CSCommTestDlg::OnSelchangeCOMBODateSelect() { // TODO: Add your control notification handler code here UpdateData(true); m_Date_Select=((CComboBox*)GetDlgItem(IDC_COMBO_Date_Select))->GetCurSel(); //当前选中的行 ///************************************************************************* ******/ ///************************************************************************* *******/ switch(m_Date_Select) { case 1: m_ctrlComm.SetSettings(",,7,"); break; case 2: m_ctrlComm.SetSettings(",,6,"); break; case 3: m_ctrlComm.SetSettings(",,5,"); break; case 4: m_ctrlComm.SetSettings(",,4,"); break; default:m_ctrlComm.SetSettings(",,8,"); break; } //************************************************************************** *******// UpdateData(false); } D、同理为IDC_COMBO_StopBit添加处理函数程序代码如下: 代码段6: void CSCommTestDlg::OnSelchangeCOMBOStopBit() { // TODO: Add your control notification handler code here UpdateData(true); m_StopBit=((CComboBox*)GetDlgItem(IDC_COMBO_StopBit))->GetCurSel();//当前选中的行 ///************************************************************************* ******/ ///************************************************************************* *******/ switch(m_StopBit) { case 1: m_ctrlComm.SetSettings(",,,2"); break; default:m_ctrlComm.SetSettings(",,,1"); break; } //************************************************************************** *******// UpdateData(false); } E、同理为IDC_COMBO_ParityCheck添加处理函数程序代码如下: 代码段7: void CSCommTestDlg::OnSelchangeCOMBOParityCheck() { // TODO: Add your control notification handler code here UpdateData(true); m_ParityCheck=((CComboBox*)GetDlgItem(IDC_COMBO_ParityCheck))->GetCurSel();/ /当前选中的行 ///************************************************************************* ******/ ///************************************************************************* *******/ switch(m_ParityCheck) { case 1: m_ctrlComm.SetSettings(",O,,"); break; case 2: m_ctrlComm.SetSettings(",O,,"); break; default:m_ctrlComm.SetSettings(",N,,"); break; } //************************************************************************** *******// UpdateData(false); } 此时应将代码段2:提示4中所指的那5个语句前的“//”删除 9、串口添加打开或关闭按钮 以同样的方式添加按钮,并将标题修改为“关闭串口”字样,为此按钮添加处理函数程序代码如下: 代码段8: void CSCommTestDlg::OnButton1Start() { //检查是否改变默认的串口值,没有改变m_Index的值是0的,否则则不为0 if(m_Index<0)//串口的默认值没有改变 { switch(m_ctrlComm.GetPortOpen())//点击打开或关闭串口按键时,根据当前串口是否打开进行相应操作 { case 1: /************************************************************** 关闭串口前先将自动发送功能关闭 ***************************************************************/ SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示 KillTimer(1); /**************************************************************/ //当前串口是打开的则进行关串口操作 m_ctrlComm.SetPortOpen(FALSE);//关闭串口 SetDlgItemText(IDC_BUTTON1,"打开串口");//更改按键指示 UpdateData(FALSE);//更新按键状态 break; case 0://当前串口是关闭的则进行开串口操作 m_ctrlComm.SetCommPort(1);//如果要打开串口则应先选择哪个串口 m_ctrlComm.SetPortOpen(TRUE);//打开串口 SetDlgItemText(IDC_BUTTON1,"关闭串口");//更改按键指示 UpdateData(FALSE); break; default : AfxMessageBox("cannot open or close serial port"); } } else//串口的默认值有改变 { switch(m_ctrlComm.GetPortOpen())//点击打开或关闭串口按键时,根据当前串口是否打开进行相应操作 { case 0://当前串口是关闭的则进行开串口操作 m_ctrlComm.SetCommPort(m_Index+1);//如果要打开串口则应先选择哪个串口 m_ctrlComm.SetPortOpen(TRUE);//打开串口 SetDlgItemText(IDC_BUTTON1,"关闭串口");//更改按键指示 UpdateData(FALSE);//更新按键状态 break; case 1: /************************************************************** 关闭串口前先将自动发送功能关闭 ***************************************************************/ SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示 KillTimer(1); /**************************************************************/ //当前串口是打开的则进行关串口操作 m_ctrlComm.SetPortOpen(FALSE); SetDlgItemText(IDC_BUTTON1,"打开串口"); UpdateData(FALSE); break; default : AfxMessageBox("cannot open serial port"); } } if(m_Index<0) ((CComboBox*)GetDlgItem(IDC_COMBO_CommSelect))->SetCurSel(0);//如果没有另外进行串口选择则显示COM1 if(m_BaudRate<0) ((CComboBox*)GetDlgItem(IDC_COMBO_BaudRate_Select))->SetCurSel(0);//如果没有另外进行波特率选择则显示9600 if(m_Date_Select<0) ((CComboBox*)GetDlgItem(IDC_COMBO_Date_Select))->SetCurSel(0);////如果没有另外进行数据位选择则显示8 if(m_StopBit<0) ((CComboBox*)GetDlgItem(IDC_COMBO_StopBit))->SetCurSel(0);//如果没有另外进行停止位选择则显示1 if(m_ParityCheck<0) ((CComboBox*)GetDlgItem(IDC_COMBO_ParityCheck))->SetCurSel(0);//如果没有另外进行校验位选择则显示没有校验位N } 10、添加自动发送功能: A、添加一个“编辑框”控件,此控件用于获取自动发送的时间间隔的,修改其ID 为IDC_EDIT_Timer,为其添加一个value类UINT型变量m_Timer B、添加一个“按钮”控件,修改其ID为IDC_BUTTON_AutoSend修改其标题为“自动发送” C、添加一个“按钮”控件,修改其ID为IDC_BUTTON_StopAutoSend修改其标题为“停止自动发送” D、为“自动发送”按钮添加BN_CLICKED处理函数,程序代码如下: 代码段9: void CSCommTestDlg::OnBUTTONAutoSend() { UpdateData(TRUE); if(m_Timer<=0)//判断是否设置自动发送时间间隔 AfxMessageBox("请设置自动发送时间间隔"); else if(!m_ctrlComm.GetPortOpen())//判断是否打开串口 AfxMessageBox("请打开串口"); else {SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送...");//更改按键指示 SetTimer(1,m_Timer,NULL);} } E、为“停止自动发送”按钮添加BN_CLICKED处理函数,程序代码如下: 代码段9: void CSCommTestDlg::OnBUTTONStopAutoSend() { // TODO: Add your control notification handler code here SetDlgItemText(IDC_BUTTON_AutoSend,"自动发送");//更改按键指示 KillTimer(1); } F、因为要设置自发送,所以要添加一个Windows定时函数,步骤如下: 进入类向导,Message Maps中的Object IDs中选择CScommTestDlg再选择Messages中的WM_TIMER,进入TIMER函数后,添加如下程序代码如下: 代码段10: void CSCommTestDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default UpdateData(TRUE); if(m_ctrlHexSend.GetCheck()) { CByteArray hexdate; int len=String2Hex(m_strTXData,hexdate); m_ctrlComm.SetOutput(COleVariant(hexdate)); } else m_ctrlComm.SetOutput(COleVariant(m_strTXData)); CDialog::OnTimer(nIDEvent); } 11、十六进制数据发送及接收显示 添加一个“复选框”控件,修改ID为IDC_CHECK_HexSend,标题为“HEX发送”,进入类向导添加control类CButton型变量,变量名为m_ctrlHexSend,然后为为 SCommTestDlg类添加以下两个PUBLIC成员函数,在Class view中右击CCommTestDlg 选中Add Member Function…然后在函数类型中输入“int”,在函数描述中输 入“String2Hex(CString str, CByteArray &senddate)”然后确定。编辑函数 体如下: 代码段11: int CSCommTestDlg::String2Hex(CString str, CByteArray &senddate) { int hexdate,lowhexdate; int hexdatelen=0; int len=str.GetLength(); senddate.SetSize(len/2); for(int i=0;i { char lstr,hstr=str[i]; if(hstr==' ') { i++; continue; } i++; if(i>=len) break; lstr=str[i]; hexdate=ConvertHexChar(hstr); lowhexdate=ConvertHexChar(lstr); if((hexdate==16)||(lowhexdate==16)) break; else hexdate=hexdate*16+lowhexdate; i++; senddate[hexdatelen]=(char)hexdate; hexdatelen++; } senddate.SetSize(hexdatelen); return hexdatelen; } 再添加别一个CCommTestDlg添加两个成员函数,在函数类型中输入“char”,在函数描述中输入“ConvertHexChar(char ch)”然后确定。编辑函数体如下: 代码段12: char CSCommTestDlg::ConvertHexChar(char ch) { if((ch>='0')&&(ch<='9')) { return ch-0x30; } else if((ch>='A')&&(ch<='F')) { return ch-'A'+10; } else if((ch>='a')&&(ch<='f')) { return ch-'a'+10; } else return (-1); } 再将CSCommTestDlg::OnButtonManualsend()修改成以下形式: 代码段13: void CSCommTestDlg::OnButtonManualsend() { // TODO: Add your control notification handler code here if(!m_ctrlComm.GetPortOpen())//判断是否打开串口 AfxMessageBox("请打开串口"); else { UpdateData(TRUE); if(m_ctrlHexSend.GetCheck())//判断是否是自动发送 { CByteArray hexdate; int len=String2Hex(m_strTXData,hexdate); m_ctrlComm.SetOutput(COleVariant(hexdate)); } else m_ctrlComm.SetOutput(COleVariant(m_strTXData)); } } 在接收框中以十六进制显示 将代码段1,提示2的三句程序代码前的“//”去掉即可。 至此,基本功能已完成,编译运行程序是否能实现各功能,如果出错,则细仔改正,再通过添加“组合框”控件或“静态文本”可以添加相应提示,再由菜单栏中的布局内的各种功能选择可以实现将各控件整齐排列效果如下: 12、保存数据功能 添加一个按钮控件,ID为IDC_BUTTON_SaveData,标题为:保存数据,添加两个“复选框”控件,一个ID为IDC_CHECK_HEXSave,标题为:HEX保存,另一个ID为IDC_CHECK_BCDSave,标题为:BCD 保存,选择HEX保存则保存的数据为十六进制数据,选择BCD保存则保存的数据为十进制数据,但不可两都同时选择,再为两个复选框选添加两个control类CButton型变量,一个变量名为:m_HEXSave,另一个为m_BCDSave;为“保存数据”按钮添加一个BN_CLICKED函数;另外再为为SCommTestDlg类添加以下两个PUBLIC成员函数,此函数只要用于十六进制与十进制数据之间的转换,函数类型为CString,函数描述为HEX_To_BCD(CString HexData),函数体如下:代码段13: 再为“保存数据”按钮添,的BN_CLICKED函数添加函数体,代码如下: 代码段14: 13:清除数据: 添加一个“清除数据”按钮控件,ID为IDC_BUTTON_CleanRXData,标题为:清空数据区,添加一个BN_CLICKED函数,函数体代码如下: 代码段14: void CSCommTestDlg::OnBUTTONCleanRXData() { // TODO: Add your control notification handler code here m_strRXData.Empty(); UpdateData(FALSE); } 至此其串口调试助手其本功能已全部实现,编译程序运行后效果如下: 该程序全部由C写成没有C++ 更没用MFC 完全是自娱自乐给需要的人一个参考 #include "stdafx.h" #include 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")); 一个c语言的串口通信程序范例 分类:技术笔记 标签: c语言 串口通信 通信程序 it 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; f=(Baud/100); f=1152/f; High=f/256; Low=f-High*256; outp(ComPortAddr+3,0x80); outp(ComPortAddr,Low); outp(ComPortAddr+1,High); Data=(Data-5)|((Stop-1)*4); if(Parity==2) Data=Data|0x18; else if(Parity==1) Data=Data|0x8; outp(ComPortAddr+3,Data); outp(ComPortAddr+4,0x0a); 一、程序代码 #include TI = 0; } T_counter = 0; } uart_receive(void) interrupt 4 { if(RI) { RI = 0; indata[R_counter] = SBUF; R_counter++; if(R_counter>=4) { R_counter = 0; flag = 1; } } } void system_initial(void) { P1M1 = 0x00; P1M0 = 0xff; P1 = 0xff; //初始化为全部关闭 temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致 temp = 0xf0; R_counter = 0; T_counter = 0; } void initial_comm(void) { SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload PCON = 0x80; //波特率不加倍SMOD = 1 TH1 = 0xfa; //baud: 9600;fosc = 11.0596 IE = 0x90; // enable serial interrupt TR1 = 1; // timer 1 RI = 0; TI = 0; ES = 1; EA = 1; } c语言串口通信范例 This manuscript was revised by the office on December 22, 2012 一个c语言的串口通信程序范例 标签:分类: 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include <> #include <> #include <> #include <> #define COM232 0x2f8 #define COMINT 0x0b #define MaxBufLen 500 #define Port8259 0x20 #define EofInt 0x20 static int comportaddr; static char intvectnum; static unsigned char maskb; static unsigned char Buffer[MaxBufLen]; static int CharsInBuf,CircIn,CircOut; static void (interrupt far *OldAsyncInt)(); static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; f=(Baud/100); #include void main() { delayms(100); init(); //初始化系统 delayms(100); init_wdt(); //初始化看门狗 while(1) { while(!RI_0) //是否收到数据 { clr_wdt(); } RI_0=0; //清除接收中断标志 buffer=S0BUF; if(buffer==0x5a) //检测祯头0 start0=1; if(buffer==0x54) //检测祯头1 start1=1; if(buffer==0x5a) //检测祯尾0 end0=1; if(buffer==0xfe) //检测祯尾1 end1=1; if((start0==1)&(start1==1)) { buff[i]=buffer; //从祯头1开始存储数据 i++; } if((end0==1)&(end1==1)) //是否已经接收祯尾 { count=i; //数据长度为count个 i=1; if((buff[2]==0x03)&(count==107)) //是否422指令 { buff[0]=0x5a; //重填祯头0 buff[count-4]=0; //校验和清零 for(k=2;k<(count-4);k++) //计算校验和 { buff[count-4]+=buff[k]; } for(k=0;k S0BUF=buff[k]; while(!TI_0); //等待发送完成 TI_0=0; //清除发送中断标志 } reset(); } else if((buff[2]==0x05)&(count==7)) //是否AD测试指令 { sendad(); reset(); } else if((buff[2]==0x18)&(count==7)) //是否发送时序信号指令 { sendpaulse(); reset(); } else //如果接收错误,则恢复各标志位为初始状态以便下次接收 { reset(); } } } } void reset() { start0=0; //祯头祯尾标志位清零 start1=0; end0=0; end1=0; for(k=0;k c语言串口通信范例标准化管理处编码[BBX968T-XBB8968-NNJ668-MM9N] 一个c语言的串口通信程序范例 标签:分类: 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include <> #include <> #include <> #include <> #define COM232 0x2f8 #define COMINT 0x0b #define MaxBufLen 500 #define Port8259 0x20 #define EofInt 0x20 static int comportaddr; static char intvectnum; static unsigned char maskb; static unsigned char Buffer[MaxBufLen]; static int CharsInBuf,CircIn,CircOut; static void (interrupt far *OldAsyncInt)(); static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; ? /*write*/ #include 摘要: 本文说明了异步串行通信(RS-232)的工作方式,探讨了查询和中断两种软件接口利弊,并给出两种方式的C语言源程序的I/O通道之一,以最简单方式组成的串行双工线路只需两条信号线和一条公共地线,因此串行通信既有线路简单的优点同时也有它的缺点,即通信速率无法同并行通信相比,实际上EIA RS-232C在标准条件下的最大通信速率仅为20Kb/S。 尽管如此,大多数外设都提供了串行口接口,尤其在工业现场 RS-232C的应用更为常见。IBM PC及兼容机系列都有RS-232的适配器,操作系统也提供了编程接口,系统接口分为DOS功能调用和BIOS 功能调用两种:DOS INT 21H的03h和04h号功能调用为异步串行通信的接收和发送功能;而BIOS INT 14H有4组功能调用为串行通信服务,但DOS和BIOS功能调用都需握手信号,需数根信号线连接或彼此间互相短接,最为不便的是两者均为查询方式,不提供中断功能,难以实现高效率的通信程序,为此本文采用直接访问串行口硬件端口地址的方式,用C语言编写了串行通信查询和中断两种方式的接口程序。 1.串行口工作原理 微机串行通信采用EIA RS-232C标准,为单向不平衡传输方式,信号电平标准±12V,负逻辑,即逻辑1(MARKING)表示为信号电平-12V,逻辑0(SPACING)表示为信号电平12V,最大传送距离15米,最大传送速率19.6K波特,其传送序列如图1,平时线路保持为1,传送数据开始时,先送起始位(0),然后传8(或7,6,5)个数据位(0,1), 接着可传1位奇偶校验位,最后为1~2个停止位(1),由此可见,传送一个ASCII字符(7位),加上同步信号最少需9位数据位。 @@T8S12300.GIF;图1@@ 串行通信的工作相当复杂,一般采用专用芯片来协调处理串行数据的发送接收,称为通用异步发送/接收器(UART),以节省CPU的时间,提高程序运行效率,IBM PC系列采用8250 UART来处理串行通信。在BIOS数据区中的头8个字节为4个UART的端口首地址,但DOS 只支持2个串行口:COM1(基地址0040:0000H)和COM2(基地址0040:0002H)。8250 UART共有10个可编程的单字节寄存器,占用7个端口地址,复用地址通过读/写操作和线路控制寄存器的第7位来区分。这10个寄存器的具体功能如下: COM1(COM2) 寄存器 端口地址功能DLAB状态 3F8H(2F8H) 发送寄存器(写) 0 3F8H(2F8H) 接收寄存器(读) 0 3F8H(2F8H) 波特率因子低字节1 3F9H(2F9H) 波特率因子高字节1 3F9H(2F9H) 中断允许寄存器0 3FAH(2FAH) 中断标志寄存器 3FBH(2FBH) 线路控制寄存器 3FCH(2FCH) MODEM控制寄存器 3FDH(2FDH) 线路状态寄存器 c语言串口通信范例 SANY GROUP system office room 【SANYUA16H- 一个c语言的串口通信程序范例 分类:技术笔记 标签: c语言 串口通信 通信程序 it 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; f=(Baud/100); f=1152/f; High=f/256; Low=f-High*256; outp(ComPortAddr+3,0x80); outp(ComPortAddr,Low); outp(ComPortAddr+1,High); Data=(Data-5)|((Stop-1)*4); if(Parity==2) Data=Data|0x18; else if(Parity==1) Data=Data|0x8; outp(ComPortAddr+3,Data); outp(ComPortAddr+4,0x0a); #include 用C语言实现串口通信 姓名: 学号: 专业:通信工程 用C语言实现串口通信(单片机和单片机) 摘要:介绍用汇编语言实现单片机与单片机之间的串口通信,通过对其中一个单片机的操作,完成另一个单片机功能的实现。并介绍了实现该功能的原理算法、硬件框图、软件流程图,以及调试过程、步骤和结果。并对结果进行了分析。 引言:简要介绍了RS232,为什么要用RS232 ,RS232和其他接口的比较优缺点。 原理: 1什么是RS232:RS是指推荐标准的英文缩写,232是标识号。RS232是由电子工业协会(Electronic Industries Association,EIA) 所制定的异步传输标准接口,是个人计算机上的通讯接口之一。通常RS-232 接口以9个引脚(DB-9) 或是25个引脚(DB-25) 的型态出现,一般个人计算机上会有两组RS-232 接口,分别称为COM1 和COM2。 2.RS232接口及其接法 实现RS232通信的关键点是:RXD连TXD,TXD连RXD,GND接地。只要这三根线连接好,就可以实现串口通信。 3.串口初始化 串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。具体步骤如下: ●确定T1的工作方式(编程TMOD寄存器); ●计算T1的初值,装载TH1、TL1; ●启动T1(编程TCON中的TR1位); ●确定串行口控制(编程SCON寄存器);串行口在中断方式工作时,要进行中断设置(编 程IE、IP寄存器)。 4.语句说明 1)发送函数 void com(uchar com) { SBUF=com; while(!TI); TI=0; } 2)串口初始化 一、引言: 现在在工业现场很少有人再用C语言做串口通讯程序了,但是基于DOS环境的程序还是有它的优势的。DOS系统的单任务环境是系统运行更加稳定、可靠;在一些追求很高的可靠性的系统中还是有一定的价值的。本文通过C语言控制PLC实现简单的物料传送为例子。 二、硬件介绍: 1、CPM1A采用RS232串口通讯与上位机连接,在PLC的DM区中可以设定串口参数,本文采用默认值: 串口通信格式: 1位---起始位、9600---波特率、7位---数据位、2位---停止位、偶校验 2、C语言中用于串口读写的函数:bioscom,在bios.h头文件中。 Bioscom用法:bioscom(int cmd,char byte,int port) Cmd的值:0 设置通信参数为btye值 1 发送一个字符到串口 2 从串口接收一个字符 3 返回串口端口的状态 byte的值:0x02 7数据位0x03 8位数据位 0x00 1个停止位0x04 2个停止位 0x00 无奇偶校验0x08奇校验 0x18偶校验0x80 1200波特率 0xA0 2400波特率0xC0 4800波特率 0xE0 9600波特率 注意:在对串口初始化时,上述参数值相或附给byte。 Port的值:0 端口1 1 端口2 三、完整源代码: #include /* 此头函数请不要删除*/ #include #include #define F1 0x3B /*启动*/ #define F2 0x3C /*停止*/ #define F3 0x3D /*混料*/ #define F4 0x3E /*出料*/ #define F5 0x3F /*退出*/ #define PORT 0 /*定义端口号*/ #define SETTINGS (0x02|0x04|0x18|0xE0) /*设定参数*/ /* 定义发送字符函数send */ void sendPort(int port,char cc) { union{ char ch[2]; int status; 一个c语言的串口通信程序例 标签: 分类:技术笔记 c语言 串口通信 通信程序 it 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include 一个c语言的串口通信程序范例 标签: 分类:技术笔记 c语言 串口通信 通信程序 it 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include 摘要本文说明了异步串行通信(RS-232)的工作方式,探讨了查询和中断两种软件接口利弊,并给出两种方式的C语言源程序。 的I/O通道之一,以最简单方式组成的串行双工线路只需两条信号线和一条公共地线,因此串行通信既有线路简单的优点同时也有它的缺点,即通信速率无法同并行通信相比,实际上EIA RS-232C在标准条件下的最大通信速率仅为20Kb/S。尽管如此,大多数外设都提供了串行口接口,尤其在工业现场RS-232C的应用更为常见。IBM PC及兼容机系列都有RS-232的适配器,操作系统也提供了编程接口,系统接口分为DOS功能调用和BIOS功能调用两种:DOS INT 21H的03h和04h号功能调用为异步串行通信的接收和发送功能;而BIOS INT 14H有4组功能调用为串行通信服务,但DOS和BIOS功能调用都需握手信号,需数根信号线连接或彼此间互相短接,最为不便的是两者均为查询方式,不提供中断功能,难以实现高效率的通信程序,为此本文采用直接访问串行口硬件端口地址的方式,用C语言编写了串行通信查询和中断两种方式的接口程序。 1.串行口工作原理 微机串行通信采用EIA RS-232C标准,为单向不平衡传输方式,信号电平标准±12V,负逻辑,即逻辑1(MARKING)表示为信号电平-12V,逻辑0(SPACING)表示为信号电平+12V,最大传送距离15米,最大传送速率19.6K波特,其传送序列如图1,平时线路保持为1,传送数据开始时,先送起始位(0),然后传8(或7,6,5)个数据位(0,1),接着可传1位奇偶校验位,最后为1~2个停止位(1),由此可见,传送一个ASCII字符(7位),加上同步信号最少需9位数据位。 @@T8S12300.GIF;图1@@ 串行通信的工作相当复杂,一般采用专用芯片来协调处理串行数据的发送接收,称为通用异步发送/接收器(UART),以节省CPU的时间,提高程序运行效率,IBM PC系列采用8250 UART来处理串行通信。 在BIOS数据区中的头8个字节为4个UART的端口首地址,但DOS只支持2个串行口:COM1(基地址0040:0000H)和COM2(基地址0040:0002H)。8250 UART共有10个可编程的单字节寄存器,占用7个端口地址,复用地址通过读/写操作和线路控制寄存器的第7位来区分。这10个寄存器的具体功能如下:COM1(COM2) 寄存器 端口地址功能DLAB状态 3F8H(2F8H) 发送寄存器(写) 0 3F8H(2F8H) 接收寄存器(读) 0 3F8H(2F8H) 波特率因子低字节1 3F9H(2F9H) 波特率因子高字节1 3F9H(2F9H) 中断允许寄存器0 3FAH(2FAH) 中断标志寄存器 3FBH(2FBH) 线路控制寄存器 3FCH(2FCH) MODEM控制寄存器 3FDH(2FDH) 线路状态寄存器 3FEH(2FEH) MODEM状态寄存器 注:DLAB为线路控制寄存器第七位在编写串行通信程序时,若采用低级方式,只需访问UART的这10个寄存器即可,相对于直接控制通信的各个参量是方便 该程序全部由C写成没有C++更没用MFC 完全是自娱自乐给需要的人一个参考 #include "stdafx.h" #include 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 |C语言串口通信助手代码
c语言串口通信范例
单片机串口通信C程序及应用实例
c语言串口通信范例
C语言串口通信-源代码
用C编写的RS232串口通信程序
c语言串口通信范例
串口通信linux c语言实现
C语言实现串口通信
c语言串口通信范例
51单片机的串口通信程序(C语言)
用C语言实现串口通信
C语言 做串口通讯程序
c语言串口通信范例
c语言串口通信范例
C语言实现串行通信接口程序
C语言串口通信助手代码