搜档网
当前位置:搜档网 › (完整版)VC6.0MFC串口通信编写全过程

(完整版)VC6.0MFC串口通信编写全过程

(完整版)VC6.0MFC串口通信编写全过程
(完整版)VC6.0MFC串口通信编写全过程

其于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()

{

// TODO: Add your control notification handler code here

V ARIANT variant_inp;//定义一个V ARIANT类对象

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;//V ARIANT型变量转换为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); } }

// Set the icon for this dialog.

//

SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);

// m_ComboBox.SetCurSel(0);//打开软件时串口选择框默认显示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写成没有C++ 更没用MFC 完全是自娱自乐给需要的人一个参考 #include "stdafx.h" #include #include "resource.h" #include "MainDlg.h" #include #include #include 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"));

串行通信接收接口(LED)

串行通信接收接口(LED) 基本要求:掌握RS232串口的协议,运用DE2的串口进行接收PC的数据。波特率为9600,8位数据位,无奇偶校验,一个停止位。 硬件验证要求:在PC机通过“串行通信调试助手”软件 发送数据,DE2通过串口接收数据,完成接收数据后在LED上面进行显示。 在完成基本要求的基础上,可以通过拨码开关来选择奇偶校验的类别。 分频模块流程图: 分频模块的程序 module clk_div (clk_in,nreset,clk_out); input clk_in; input nreset; output clk_out; reg clk_out=0;

reg [8:0]cnt=0; parameter T = 217; always @(posedge clk_in or negedge nreset) begin if(nreset == 0) begin cnt <= 0; clk_out <= 0; end else if(cnt == T) begin clk_out <= ~clk_out; cnt <=0; end else cnt<=cnt+1; end endmodule 发送模块的程序: module rx(clk,nreset,rxd,data); input clk,rxd,nreset; //clk=0.1152MHz output [7:0] data; reg [3:0] t; reg [3:0] s; reg [7:0] data0; reg [7:0] data; always @(posedge clk or negedge nreset ) //baud=9600hz if(nreset ==0) begin data <= 8'h00; s <= 0; t <= 0; data0 <= 8'h00; end else begin case(s) 0:if(rxd==1) begin s<=1;t<=0;end 1:if(rxd==0) begin s<=2;t<=t+1;end 2:if(t==6)begin if(rxd==0) begin s<=3;t<=0;end

c语言串口通信范例

一个c语言的串口通信程序范例 分类:技术笔记 标签: c语言 串口通信 通信程序 it 最近接触一个项目,用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); 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);

RS232串行接口实现GPIB接口的发送和接收

摘要:本文的目的是利用一台电脑RS232串行接口实现GPIB接口的发送和接收,并有能力跟RS232及周边设备的GPIB进行连接。其主要特点在于串行通信的波特率可以由用户和被自动化的数据流调整。 1、引言 如今,越来越多的测试和测量仪器可连接到通用接口总线(GPIB),这使该技术的掌握和交流更为容易。所以,必须有一个GPIB接口。在一般情况下,如果该仪器是基于个人计算机(PC ),则现有的PCI-GPIB卡或USB接口的GPIB卡都可以使用,但成本较高。此外,有大部分是基于微控制器上的,它有RS232接口但不具备PCI或USB接口。因此,RS232 - GPIB接口是一种扩大GPIB的功能的低成本的解决方案。尽管还有一些的RS232- GPIB卡,我们证实简化RS232 - GPIB接口架构和加快串行通信的速度可以来满足更高的要求。 2硬件设计研究的RS232 - GPIB接口 2.1硬体架构的界面 该RS232 - GPIB接口,其核心部分是8051单片机,有两个端口,一个是RS232端口另一个是GPIB的端口。它不仅可以通过RS232串口端口连接PC,而且还可以连接其他设备来扩大GPIB接口。串行设备为了满足不同波特率的串行传输,可以由用户来设置波特率。此外,在数据量和处理速度的基础上数据流可以自动控以确保数据传输的可靠性。除微控制器外最重要的部分是RS232 - GPIB接口的TNT4882 GPIB接口芯片。 2.2 TNT4882使用范围 国际TNT4882提供了一个单片机向GPIB发送/接收的接口。它有三个不同的内部硬件架构:单芯片模式,涡轮7210模式,与Turbo 9914模式。其中第一个芯片的模式是最简单和最快的TNT4882体系机构,其中先入先出(先进先出)缓冲器的TNT4882是直接连接到GPIB 的。它可以很容易地接到任何16 或8位微处理器。除了一个40 MHz的时钟电路外,TNT4882可以直接连接到GPIB的。 在设计方面,bus B(D7类- 0 )的TNT4882是用于8位输入/输出通道,连接到8051数据总线。32个寄存器分别位于8051外部数据存储器和32字节输入/输出内存0x00 ? 0x1f 。该TNT4882可以中断处理器断言其中断信号INTR以及哪些是活跃高的。因为8051的IRQ线是低作用的,所以INTR以及信号TNT4882必须倒置,然后连接到一个可用的中断线路。因此,一个通用阵列逻辑(GAL器件)芯片是用来锁存地址总线信号,并产生了积极的CSN和中断信号。此外,max708是用来复位的8051微控制器和TNT4882 。 2.3波特率调整和串行通信的流量控制串行通信 RS232 - GPIB接口可通过一个RS-232C电缆连接到串口设备。由于串行通信设备的波特率相关性,连接到8051单片机端口1的一组交换机的波特率可以从1200到115200中设置。 作为核心部分的RS232 - GPIB接口,8051单片机串行通信提供与RXD (串行输入端口)边和TXD脚发送(串行输出端口)密码的功能。无流量控制线定义了RS232系列的标准,当在处理时间内接收缓冲区满或没有接收准确的数据时,数据可能会丢失。为了提高传输的可靠性,免插脚的8051采用硬件握手方式,以允许或拒绝转让信息请求。硬件握手功能始终活跃在串行数据传输。该p1.0的8051 ,被作为RTS的信号线来连接到一级转换芯片的RS232连接器的CTS线9针的标准。当RTS的路线是中断的,它表明RS232 - GPIB接口准备好从串行设备中接收数据。同时,以串口设备接收和发送的信号作为CTS的信号。如果

单片机串口通信C程序及应用实例

一、程序代码 #include//该头文件可到https://www.sodocs.net/doc/1e11700119.html,网站下载#define uint unsigned int #define uchar unsigned char uchar indata[4]; uchar outdata[4]; uchar flag; static uchar temp1,temp2,temp3,temp; static uchar R_counter,T_counter; void system_initial(void); void initial_comm(void); void delay(uchar x); void uart_send(void); void read_Instatus(void); serial_contral(void); void main() { system_initial(); initial_comm(); while(1) { if(flag==1) { ES = 0; serial_contral(); ES = 1; flag = 0; } else read_Instatus(); } } void uart_send(void) { for(T_counter=0;T_counter<4;T_counter++) { SBUF = outdata[T_counter]; while(TI == 0);

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; }

串行通信技术-模拟信号转换接口

微机原理与应用实验报告6 实验9 串行通信技术 实验10A 模拟信号转换接口 实验报告

实验九串行通信技术 一、实验目的 1. 了解异步串行通信原理; 2. 掌握MSP430异步串行通信模块及其编程方法; 二、实验任务 1. 了解MSP430G2553实验板USB转串口的通信功能,掌握串口助手的使用 (1)利用PC机的串口助手程序控制串口,实现串口的自发自收功能 为实现PC串口的自发自收功能,须现将实验板上的扩展板去下,并将单片机板上的BRXD和BTXD用杜邦线进行短接,连接图如下所示: 由此可以实现PC串口的自收自发功能。 (2)思考题:异步串行通信接口的收/发双方是怎么建立起通信的 首先在异步通信中,要求接收方和发送方具有相同的通信参数,即起始位、停止位、波特率等等。在满足上面条件的情况下,发送方对于每一帧数据按照起始位数据位停止位的顺序进行发送,而接收方则一直处于接受状态,当检测到起始位低电平时,看是采集接下来发送方发送过来的数据,这样一帧数据(即一个字符)传送完毕,然后进行下一帧数据的接受。这样两者之间就建立起了通信。 2. 查询方式控制单片机通过板载USB转串口与PC机实现串行通信 (1)硬件连接图

(2)C语言程序 采用SMCLK=1.0MHz时,程序如下:

其中SMCLK=1MHz,波特率采用的是9600,采用低频波特方式,则N=1000000/9600=104.1666…,故UCA0BR1=0,UCA0BR0=104,UCBRS=1; 当采用外部晶振时,时钟采用默认设置即可,程序如下:

也是采用了低频波特率方式,所以关于波特率设置的相关计算和上面是一样的。 (3)思考:如果在两个单片机之间进行串行通信,应该如何设计连线和编程? 由于在上面的连线中将单片机上的P1.2和BRXD相连,P1.1和BTXD相连,所以若要在两个单片机之间进行通信,首先应该将两个单片机的P1.2和P1.1交叉相连,并根据上面的程序进行相同的关于端口和波特率相关的设置即可实现两个单片机之间的通信。 3. (提高)利用PC机RS232通信接口与单片机之间完成串行通信 (1)硬件连接图 在实验时,采用了将PC机的串口com1直接连接至MSP430F149的孔型D9连接器上,G2553单片机的输出引脚P1.1和P1.2分别与F149单片机上的URXD1和UTXD1相连接,连接图如下所示:

c语言串口通信范例

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);

串口通信测试方法

串口通信测试方法 1 关于串口通信的一些知识: RS-232C是目前最常用的串行接口标准,用来实现计算机和计算机之间、计算机和外设之间的数据通信。 在PC机系统中都装有异步通信适配器,利用它可以实现异步串行通信。而且MCS-51单片机本身具有一个全双工的串行接口,因此只要配以电平转换的驱动电路、隔离电路就可以组成一个简单可行的通信接口。 由于MCS-51单片机的输入和输出电平为TTL电平,而PC机配置的是RS-232C 标准串行接口,二者电气规范不一致,因此要完成PC机与单片机的数据通信,必须进行电平转换。 注明:3)RS-232C上传送的数字量采用负逻辑,且与地对称 逻辑1:-3 ~-15V 逻辑0:+3~+15V 所以与单片机连接时常常需要加入电平转换芯片: 2 实现串口通信的三个步骤: (1)硬件连接 51单片机有一个全双工的串行通讯口,所以单片机和计算机之间可以方便地进行串口通讯。进行串行通讯时要满足一定的条件,比如计算机的串口是RS232电平的,而单片机的串口是TTL电平的,两者之间必须有一个电平转换电路,我们采用了专用芯片MAX232进行转换。我们采用了三线制连接串口,也就是说和计算机的9针串口只连接其中的3根线:第5脚的GND、第2脚的RXD、第3脚的TXD。电路如下图所示,MAX232的第10脚和单片机的11脚连接,第9脚和单片机的10脚连接,第15脚和单片机的20脚连接。 使用MAX232串口通信电路图(9孔串口接头) (2)串行通信程序设计 ①通信协议的使用 通信协议是通信设备在通信前的约定。单片机、计算机有了协议这种

约定,通信双方才能明白对方的意图,以进行下一步动作。假定我们需要在PC 机与单片机之间进行通信,在设计过程中,有如下约定:

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); 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);

串口通信发送接口-(LED)

硬件描述语言设计报告设计题目串行通信接收接口(LED) 学院电子信息学院 班级电子101 姓名梁嘉诚 学号1011002006 设计时间2013年1月7~11日

引言: 随着计算机系统的应用和微机网络的发展,通信功能越来越显的重要。这里所说的通信是只计算机与外界的信息交换。因此,通信既包括计算机与外部设备之间,也包括计算机和计算机之间的信息交换。由于串行通信是在一根传输线上一位一位的传送信息,所用的传输线少,并且可以借助现成的电话网进行信息传送,因此,特别适合于远距离传输。对于那些与计算机相距不远的人-机交换设备和串行存储的外部设备如终端、打印机、逻辑分析仪、磁盘等,采用串行方式交换数据也很普遍。在实时控制和管理方面,采用多台微机处理机组成分级分布控制系统中,各CPU之间的通信一般都是串行方式。所以串行接口是微机应用系统常用的接口。 许多外设和计算机按串行方式进行通信,这里所说的串行方式,是指外设与接口电路之间的信息传送方式,实际上,CPU与接口之间仍按并行方式工作。 RS-232C标准的全称是EIA-RS-232C标准(Electronic Industrial Associate-Recommended Standard 232C)是美国EIA(电子工业联合会)与BELL等公司一起开发的1969年公布的通信协议。232标准与CCITT的V.24基本相同。 它适合于数据传输速率在0~20,000bit/s范围内、传输距离在15m以内的通信。由于通信设备厂商大都生产与RS-232C制式兼容的通信设备,因此,它作为一种标准,目前已在微机串行通信接口中广泛采用。 RS-232C标准最初是为远程通信连接数据终端设备DTE与数据通信设备DCE而制定的。因此,这个标准的制定,并未考虑计算机系统的应用要求。但目前它又广泛地被借来用于计算机(更准确地说,是计算机接口)与终端或外设之间的近端连接标准。很显然,这个标准的有些规定及定义和计算机系统是不一致的,甚至是相矛盾的。 RS-232C标准中所提到的“发送”和“接收”,都是站在DTE的立场上,而不是站在DCE的立场来定义的。由于在计算机系统中,往往是CPU和I/O设备之间传送信息,两者都是DTE,因此双方都能发送或接收 通常 RS-232 接口以9个引脚 (DB-9) 或是25个引脚 (DB-25) 的型态出现,一般个人计算机上会有两组 RS-232 接口,分别称为 COM1 和 COM2。 RS-232 标准规定的数据传输速率为每秒150、300、600、1200、2400、4800、9600、19200波特。 RS-232 标准规定,驱动器允许有2500pF的电容负载,通信距离将受此电容限制,例如,采用150pF/m的通信电缆时,最大通信距离为15m;若每米电缆的电容量减小,通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。 设计原理: 串行通信是指使用一条数据线(另外需要地线,可能还需要控制线),将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。其只需要少数几条线就可以在系统间交换信息,特别使用于计算机与计算机、计算机与外设之间的远距离通信。使用串口通信时,发送和接收到的每一个字符实际上都是一次一位的传送的,每一位为1或者为0。

【整理】常用通信接口一(串口、RS232、RS485、USB、TYPE-C原理与区别)

By bingge 【整理】常用通信接口一(串口/RS232/RS485/USB/TYPE-C 原理与区别) 一、什么是串口通信 ? 常见的串口通信一般是指异步串行通信。 与串行通信相对的是并行通信。数据传输一般都是以字节传输的,一个字节8个位。拿一个并行通信举例来说,也就是会有8根线,每一根线代表一个位。一次传输就可以传一个字节,而串口通信,就是传数据只有一根线传输,一次只能传一个位,要传一个字节就需要传8次。 异步串口通信:就只需要一根线就可以发送数据了 。 串口通信主要为分232,485,422通信三种方式。 二、RS232接口标准设计电路 232通信主要是由RX,T X,G ND 三根线组成。 RX 与TX ,TX 接RX ,GND 接GND 。这样还是比较好理解吧。因为发送和接收分别是由不同的线处理的,也就是能同时发送数据和接收数据,这就是所谓的全双工。

By bingge 三、RS485EMC 标准设计电路 1.RS485概念 是为了解决232通信距离的问题。485主要是以一种差分信号进行传输,只需要两根线,+,-两根线,或者也叫A ,B 两根线。A ,B 两根线的差分电平信号就是作为数据信号传输。发送和接收都是靠这两根的来传输,也就是每次只能作发送或者只能作接收,这就是半双工的概念了,这在效率上就比232弱很多了。 RS-485只能构成主从式结构系统,通信方式也只能以主站轮询的方式进行,系统的实时性、可靠性较差;

By bingge 2.422通信 422是为了保留232的全双工,又可以像485这样提高传输距离。有些标注为485-4。而485就标注为485-2。有什么区别 呢。就是为了好记呢。485-2就是2根线。485-4就是4根线。 3.RS232与RS485接口的差别 由于RS232接口标准出现较早,难免有不足之处,主要有以下四点: 1)接口的信号电平值较高,易损坏接口电路的芯片,又因为与TTL 电平不兼容故需使用电平转换电路方能与TTL 电路连接。 2)传输速率较低,在异步传输时,波特率为20Kbps 。 3)接口使用一根信号线和一根信号返回线而构成共地的传输形式,容易产生共模干扰,所以抗噪声干扰性弱。 4)传输距离有限,最大传输距离标准值为50英尺,实际上也只能用在50米左右。 针对RS232接口的不足,于是就不断出现了一些新的接口标准,RS-485就是其中之一,它具有以下特点: 1)RS-485的电气特性:逻辑“1”以两线间的电压差为+(2-6)V 表示;逻辑“0”以两线间的电压差为-(2-6)V 表示。接口信号电平比RS-232降低了,就不易损坏接口电路的芯片,且该电平与TTL 电平兼容,可方便与TTL 电路连接。2)RS-485的数据最高传输速率为10Mbps 。 3)RS-485接口是采用平衡驱动器和差分接收器的组合,抗共模干能力增强,即抗噪声干扰性好。 4)RS-485接口的最大传输距离标准值为4000英尺,实际上可达3000米,另外RS-232接口在总线上只允许连接1个收发器,即单站能力。而RS-485接口在总线上是允许连接多达128个收发器。即具有多站能力,这样用户可以利用单一的RS-485接口方便地建立起设备网络。 四、USB 设计电路 1.定义与运用

用C编写的RS232串口通信程序

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

单片机串口通信实验报告

信息工程学院实验报告 课程名称:单片机原理及接口 实验项目名称:串口通信实验实验时间:2017、5 一、实验目得: 1.了解什么就是串口,串口得作用等。 2、了解串口通信得相关概念 3、利用keil软件,熟悉并掌握中串口通信得使用 4、通过实验,熟悉串口通信程序得格式,串口通信得应用等 二、实验原理 1、串口通信概念: 单片机应用与数据采集或工业控制时,往往作为前端机安装在工业现场,远离主机,现场数据采用串行通信方式发往主机进行处理,以降低通信成本,提高通信可靠性。如下图所示。 2、串口数据通信方式及特点 ★数据通信方式有两种:并行通信与串行通信 ★并行通信: 所传送数据得各位同时发送或接收, ?数据有多少位就需要多少根数据线。 特点: 速度快,成本高,适合近距离传输 如计算机并口,打印机,8255 。 ★串行通信:所传送数据得各位按顺序一位一位 地发送或接收。 只需一根数据,一根地线,共2 根 特点:成本低,硬件方便,适合远距离通信, 传输速度低。 串行通信与并行通信示意图如下: 成绩: 指导老师(签名):

3、串行通信基本格式 ①单工通信:数据只能单向传送。 ②半双工通信:通信就是双向得,但每一时刻,数据流通得方向就是单向得。 ③全双工通信:允许数据同时在两个方向流动,即通信双方得数据发送与接收就是同时进行得。 4、异步串行通信/同步串行通信 ①异步串行通信: 异步串行通信采用如下得帧结构: 起始位+ 8位数据位+ 停止位或起始位+ 9位数据位+停止位 其中:起始位为低电平,停止位为高电平。 优点:硬件结构简单 缺点:传输速度慢 ②同步串行通信: 在同步通信中,发送方在数据或字符开始处就用同步字符(常约定1~2个字节)指示一帧得开始,由时钟来实现发送端与接收端同步,接收方一旦检测到与规定得同步字符符合,下面就连续按顺序传送若干个数据,最后发校验字节。见下图: 5、串行通信过程与UART 基本得计算机异步串行通信系统中,两台计算机之间通过三根信号线TxD、RxD与GND连接起来,TxD与GND构成发送线路,RxD与GND构成接收线路。一台计算机得TxD、RxD线分别与另一台计算机得RxD、TxD线相连。 由于在串行通信过程中得并串转换、串并转换、线路检测、采样判决、组帧、 拆帧、发送与接收等操作需消耗CPU大量时间,以至CPU无法处理其它工 作,因而开发出专用于处理异步串行通信发送与接收工作得芯片UART(通用 异步串行通信接收发送器)。 CPU只需将要发送得一个字节数据交给UART,其它发送工作由UART自动完成,当UART将一帧数据发送完毕,会通知CPU 已发送完,可提交下一个字节。 UART自动监测线路状态并完成数据接收工作,当接收到一个字节数据后,UART会通知CPU来读取。采用UART 后,CPU得负担大大减轻了。

c语言串口通信范例

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; ?

串口通信linux c语言实现

/*write*/ #include #include #include #include #include #include #define MAX_SIZE 30 void set_speed(int,int); int main(int argc,char **argv) { int fd; int flag; int write_num=0; struct termios term; speed_t baud_rate_i; speed_t baud_rate_o; char buff[MAX_SIZE]="hello,beautiful day!"; fd=open(argv[1],O_RDWR|O_NONBLOCK); if(fd<0) printf("open the COM1 error!\n"); else printf("open COM1 ok!\n"); flag=tcgetattr(fd,&term); baud_rate_i=cfgetispeed(&term); baud_rate_o=cfgetospeed(&term); printf("%d,%d\n",baud_rate_i,baud_rate_o); set_speed(fd,9600); flag=tcgetattr(fd,&term); baud_rate_i=cfgetispeed(&term); baud_rate_o=cfgetospeed(&term); printf("%d,%d\n",baud_rate_i,baud_rate_o); while(1) { buff[29]='\n'; write_num=write(fd,buff,sizeof(buff));

C语言实现串口通信

摘要: 本文说明了异步串行通信(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语言串口通信范例

c语言串口通信范例 SANY GROUP system office room 【SANYUA16H-

一个c语言的串口通信程序范例 分类:技术笔记 标签: c语言 串口通信 通信程序 it 最近接触一个项目,用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); 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);

相关主题