aaaVC串口通信编程实例
vc串口编程实例 -回复
vc串口编程实例-回复“VC串口编程实例”——探索电脑与外部设备的通信利器在现代科技发展的浪潮中,电脑作为人们生活和工作中必不可少的工具之一,其与外部设备的通信越来越重要。
为了实现电脑与外部设备之间的数据传输和互联互通,VC串口编程成为一种不可或缺的技术。
本文将以“VC串口编程实例”为主题,为读者详细介绍如何通过VC编程实现电脑与外部设备的串口通信。
第一步:了解串口通信的基本原理和常用控制器在开始VC串口编程之前,我们首先要了解串口通信的基本原理和常用的串口控制器。
串行接口(Serial Interface)是一种将数据位连续地在单条数据线上传输的通信方式,它可以用于将电脑与外部设备(例如打印机、传感器等)进行连接。
而串口控制器则负责电脑与外部设备之间的数据传输,常见的串口控制器包括UART(通用异步收发传输器)、USART(通用同步异步收发传输器)等。
对于VC串口编程来说,我们主要会使用到UART。
第二步:准备开发环境和工具在进行VC串口编程之前,我们需要准备好相应的开发环境和工具。
首先,我们需要安装Visual Studio并编写C/C++程序。
其次,我们需要下载安装串口调试助手等串口调试工具,用于调试和测试串口通信过程。
另外,我们还需要准备一台电脑和一款外部设备(例如Arduino开发板),作为我们的实验对象。
第三步:打开串口和配置串口参数在VC编程中,我们可以通过调用Windows API函数来打开串口和配置串口参数。
首先,我们需要通过CreateFile函数打开串口,获取到串口的句柄。
然后,我们可以通过SetCommState函数配置串口的波特率、数据位、校验位等参数。
配置好串口参数后,我们可以使用WriteFile函数向串口发送数据,使用ReadFile函数从串口接收数据。
第四步:实现数据的发送和接收一旦打开并配置好串口,我们就可以开始实现数据的发送和接收了。
在VC编程中,我们可以通过WriteFile函数向串口发送数据。
vc串口编程实例 -回复
vc串口编程实例-回复VC串口编程实例,是指使用VC(Visual C++)进行串口编程的实例。
串口编程是指通过串口(在计算机中又称通信端口)与外部设备进行数据的收发和通信。
串口编程在很多应用中都非常常见,例如与嵌入式设备、传感器、单片机等进行通信。
本文将以串口编程为主题,详细介绍如何在VC中进行串口编程的步骤和相关实例。
第一步,准备工作。
在进行串口编程之前,需要准备好一些必要的工作和工具。
首先,我们需要一台计算机和一个可用的串口接口。
然后,我们需要安装一个适合的集成开发环境(IDE)。
在本例中,我们选择使用VC进行编程。
确保已经安装好VC及其相关的开发工具和库。
第二步,创建工程。
在VC中创建一个新的工程。
在创建工程的界面中,选择“Windows桌面应用程序”作为项目类型。
输入一个项目名称,选择工作空间的目录。
点击“确定”按钮创建工程。
第三步,设置串口参数。
在VC中进行串口编程,首先需要设置串口的参数,包括波特率、数据位、停止位和校验位等。
通过设置这些参数,我们可以控制串口的通信速度和数据的可靠性。
在VC的代码中使用DCB 结构体来设置这些参数。
下面是一个示例代码段:c++DCB dcbSerialParams = { 0 };dcbSerialParams.DCBlength = sizeof(dcbSerialParams); GetCommState(hSerial, &dcbSerialParams); 获取串口配置参数dcbSerialParams.BaudRate = 9600; 设置波特率dcbSerialParams.ByteSize = 8; 设置数据位dcbSerialParams.StopBits = ONESTOPBIT; 设置停止位dcbSerialParams.Parity = NOPARITY; 设置校验位SetCommState(hSerial, &dcbSerialParams); 设置串口配置参数在上述代码中,首先定义一个DCB结构体变量dcbSerialParams,用于保存串口参数。
VC++串口通信编程
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。
串口通信方便易行,应用广泛。
一般情况下,工控机和各智能仪表通过RS485总线进行通信。
RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络上的各智能控制单元子节点。
每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。
在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序简单,但欠灵活。
其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。
本文我们只介绍API串口通信部分。
串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。
同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。
无论那种操作方式,一般都通过四个步骤来完成:(1)打开串口(2)配置串口(3)读写串口(4)关闭串口(1)打开串口Win32系统把文件的概念进行了扩展。
无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。
该函数的原型为:HANDLE CreateFile( LPCTSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile);•lpFileName:将要打开的串口逻辑名,如“COM1”;•dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列;•dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;•lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;•dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING;•dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;•hTemplateFile:对串口而言该参数必须置为NULL;同步I/O方式打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom=CreateFile("COM1",//COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建0, //同步方式NULL);if(hCom==(HANDLE)-1){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;重叠I/O打开串口的示例代码:HANDLE hCom; //全局变量,串口句柄hCom =CreateFile("COM1", //COM1口GENERIC_READ|GENERIC_WRITE, //允许读和写0, //独占方式NULL,OPEN_EXISTING, //打开而不是创建FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式NULL);if(hCom ==INVALID_HANDLE_VALUE){AfxMessageBox("打开COM失败!");return FALSE;}return TRUE;(2)、配置串口在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。
串口通信之用C语言编写串口程序
串口通信之用C语言编写串口程序在当今,流行的编程软件种类繁多,它们编程方便、易于维护,但是在与硬件直接打交道和编制系统软件时却束手无策,于是C语言就有了用武之地。
C语言作为汇编语言与高级语言之间的一种过渡语言,兼有汇编语言的高效和高级语言的方便。
在通讯中,为了保证行运安全可靠,标准的串行口必须具有许多握手信号和状态信息。
这是因为通讯的各个计算机CPU速度不一样(这会导致“错帧”)以及发送机发送数据速度比接收机接收速度快(这会导致“过冲”)。
为解决这个问题,我们采用一个简单的握手信号,即发送机每次仅发送半个字节(低4位)的数据,而另外半个字节(高4位)则用来传送信息。
我们可以对信息位(高4位)进行如下简单的编码:0H:发送的是新的半个字节数据1H:重新发送上次传送错误的数据2H:文件名结束3H:文件结束这样,每当发送机发送一个字节以后,就等待接受机发回送信号,这回送信号就是发送机发送过来的那个字节。
发送机接收到回送信号后,把它与刚发送的字节相比较,如果相同,就发送新的半个字节,否则就重新发送。
新数据与旧数据通过信息位来区分。
下面就是用C 语言编写控制串行口的程序。
#include "dos.h"#include "stdlib.h"#include "stdio.h"#define PORT 0void SendFile(char *fname); /* 发送文件*/void Send(int s); /*发送一个字节*/void SendFileName(char *fname); /*发送文件名*/void ReceiveFile(); /*接收文件*/void GetFileName(char *f); /*接收文件名*/void InitPort(int port,unsigned char para); /*初始化端口*/ void SendPort(int port,char c); /*端口发送*/int ReadPort(int port); /*读端口字节*/int CheckState(int port); /*检查端口状态*/int Receive(int port,int *G); /*接收一个字节*/main(int argc,char *argv[]){if(argc<2){printf("Please input R(receive) or S(sent) parametre:"); exit(1);}InitPort(PORT,231);if(*argv[1]==''''S'''') /*检查选择的有效性*/SendFile(argv[2]);else if(*argv[1]==''''R'''')ReceiveFile();else{printf("Error parament.Please input again.");exit(1);}}void SendFile(char *fname){FILE *fp;int ch,s;if((fp=fopen(fname,"rb"))==NULL){printf("Can''''t open the file.\n");exit(1);}SendFileName(fname);do{ch=(int)getc(fp);if(ferror(fp)){printf("Error reading file.\n");break;}s=ch%16; /*取文件中一个字节的低4位*/ Send(s);s=ch/16; /*取文件中一个字节的高4位*/ Send(s);}while(!feof(fp));s=46; /*发送文件结束信息*/Send(s);Send(s);fclose(fp);}void Send(s)int s;{int G;SendPort(PORT,s);G=ReadPort(PORT); /*等待握手信号*/ if(s!=G)s=s+16;do{SendPort(PORT,s);G=ReadPort(PORT);/*等待握手信号*/}while(s!=G);}void SendFileName(fname)char *fname;{int s,ch;printf("Now transmit the file.Please wait..."); while(*fname){ch=(int)fname++;s=ch%16; /*取文件名中一个字节的低4位*/ Send(s);s=ch/16;Send(s); /*取文件名中一个字节的低4位*/}s=32; /*发送文件名结束标志*/Send(s);Send(s);}void ReceiveFile(){FILE *fp;char ch;int G1,G2,G3;char fname[15];GetFileName(fname);printf("Receiving file %s.\n",fname); remove(fname);if((fp=fopen(fname,"wb"))==NULL){printf("Can''''t open output file.\n");exit(1);}/*循环为检测每次接受的数据是否为新数据,如果不是,*//*则用此次接收的数据覆盖上次接收的数据*/G1=ReadPort(PORT);G2=Receive(PORT,&G1);do{G3=Receive(PORT,&G2);ch=(char)(G1%16+G2*16);/*恢复分开的数据,组合高4位和低4位*/putc(ch,fp);if(ferror(fp)){printf("\nError writing file.");exit(1);}G2=Receive(PORT,&G3);G1=G3;}while(G1/16!=48);printf("\nTransmit finished.");fclose(fp);}int Receive(port,G)int port,*G;{int GM;SendPort(port,*G);GM=ReadPort(port);if(GM/16==0)return GM;else if(GM/16==1){do{*G=GM;SendPort(port,GM);GM=ReadPort(port);}while(GM/16==1);}return GM;}void GetFileName(char *f){int G1,G2,G3;char ch;G1=ReadPort(PORT);G2=ReadPort(PORT);do{G3=Receive(PORT,&G3);ch=(char)(G1%16+G2/16);*f=ch;*f++;G2=Receive(PORT,&G3);G1=G3;}while(G1/16!=32);printf("File name transmit finished.\n"); }void InitPort(port,para)int port;unsigned char para;{union REGS reg;reg.x.dx=port;reg.h.ah=0;reg.h.al=para;int86(0x14,?,?);}void SendPort(port,c)int port;char c;{union REGS reg;reg.x.dx=port;reg.h.al=c;reg.h.ah=1;int86(0x14,?,?);if(reg.h.ah&128){printf("\nSend mistakes!");exit(1);}}int ReadPort(port)int port;{union REGS reg;while(!(CheckState(port)&256)){if(kbhit()){/*如端口长期无数据可人为终止等待*/ printf("Press any key to exit.");getch();exit(1);}}reg.x.dx=port;reg.h.ah=2;int86(0x14,?,?);if(reg.h.ah&128){printf("\nRead mistake!");exit(1);}return reg.h.al;}int CheckState(port)int port;{union REGS reg;reg.x.dx=port;reg.h.ah=3;int86(0x14,?,?);return reg.x.ax;}在当今,流行的编程软件种类繁多,它们编程方便、易于维护,但是在与硬件直接打交道和编制系统软件时却束手无策,于是C语言就有了用武之地。
3 串口发送实例(VC)
15
pCmbComStopbits->ResetContent(); pCmbComStopbits->AddString(L"1"); pCmbComStopbits->AddString(L"1.5"); pCmbComStopbits->AddString(L"2"); pCmbComStopbits->SetCurSel(0); //1
“已安装的 SDK”中,选择我们要使用的 SDK,将它添加到右侧的列表框中,如图这 里是 ce50_2440a_test,选中它,然后下一步。
3
“应用程序类型”选择基于对话框,选择“在静态库中使用 MFC”。如果选择“在共享 DLL 中使用 MFC”的话,生成的可执行程序在目标机中运行时,可能会因为找不到相应 DLL 而出错。
pCmbComBaud->GetWindowTextW(strTmp);
m_portNo = pCmbComNo->GetCurSel() + 1;
//串口号
m_baud = _wtoi(strTmp);
//波特率
m_parity = pCmbComParity->GetCurSel();
IDC_BTN_DISC
数据发送
IDC_BTN_SEND
程序退出
IDC_BTN_EXIT
然 后 添 加 一 个 静 态 文 本 框 , 内 容 为 “ 发 送 数 据 ”。 添 加 一 个 编 辑 框 , ID 为
IDC_EDT_SEND。将 MultiLine,Auto VScroll 设置为 TRUE,将 Auto Hscroll 设置为 FALSE。
用vc的串口通信实验报告
高级Internet编程实验报告实验题目: 串口通信班级:学号:姓名:日期: 2015-6-8一、实验要求把两台计算机的串口通过串口线连在一起, 通过串口实现两台计算机通讯。
可以利用高级语言、C语言编程实现, 要求程序界面友好, 有发送和接收功能, 其接收和发送内容可在屏幕上显示。
二、实验原理串口通讯把数据的字节分解成单个的二进制比特流依次传输, 其结构简单,连接线少, 应用非常广泛。
实现串口通信的方法很多。
如: 利用标准通信函数实现串口通信、利用API实现串口通信和利用ActiveX控件实现。
本文主要采用ActiveX控件Microsoft CommunicationsControl(MSComm)编程, Windows平台先进的ActiveX技术使得对串口编程不再需要处理烦琐的细节。
利用已有的AxtiveX控件, 只需要编写少量的代码, 就可以轻松高效地完成任务。
以下对ActiveX控件属性进行简单介绍, 在ClassWizard中为新创建的通信控件定义成员对象(CMSComm m_comm), 通过该对象便可以对串口属性进行设置, MSComm控件共有27个属性, 这里只介绍其中几个常用属性:CommPort: 设置并回通讯端口号, 缺省为COMl。
Settings: 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
PortOpen:设置并返回通讯端口的状态, 也可以打开和关闭端口。
Input: 从接收缓冲区返回和删除字符。
Output: 向发送缓冲区写一个字符串。
InputLen:设置每次Input读入的字符个数, 缺省值为0, 表明读取接收缓冲区中的全部内容。
InBufferCount: 返回接收缓冲区中已接收到的字符数, 将其置0可以清除接收缓冲区。
InputMode: 定义Input属性获取数据的方式(为0: 文本方式;为1: 二进制方式)。
RThreshold和SThreshold:表示在OnComm事件发生之前, 接收缓冲区或发送缓冲区中可以接收的字符数。
c语言串口编程实例
c语言串口编程实例摘要:1.串口编程基础2.C 语言串口编程步骤3.C 语言串口编程实例4.实例详解5.总结正文:一、串口编程基础串口编程是指通过计算机串行接口进行数据通信的编程方式。
串口(Serial Port)是一种计算机硬件接口,可以通过串行通信传输数据。
与并行通信相比,串行通信只需一条数据线,传输速度较慢,但具有线路简单、成本低的优点。
因此,串口编程在电子设备、计算机外设、通信设备等领域有广泛的应用。
二、C 语言串口编程步骤1.包含头文件:在使用C 语言进行串口编程时,首先需要包含头文件`<reg52.h>`或`<intrins.h>`。
2.配置串口:配置串口包括设置波特率、数据位、停止位、奇偶校验等参数。
3.初始化串口:初始化串口主要是初始化串口硬件,如配置UART(通用异步收发器)等。
4.打开串口:打开串口是指使能串口通信功能,以便数据传输。
5.读写串口:通过`in`和`out`语句实现数据的输入输出。
6.关闭串口:在数据传输完成后,需要关闭串口以节省资源。
7.串口通信:通过循环寄存器、缓存寄存器或FIFO(先进先出)等方法实现数据的收发。
三、C 语言串口编程实例以下是一个简单的C 语言串口编程实例,该实例通过串口发送数据“Hello, World!”:```c#include <reg52.h>#include <intrins.h>sbit UART_TXD = P3^1; // 配置UART TXD 引脚void init_uart(); // 初始化UART 函数void send_data(unsigned char dat); // 发送数据函数void main(){init_uart(); // 初始化UARTsend_data("H"); // 发送字符"H"send_data("e"); // 发送字符"e"send_data("l"); // 发送字符"l"send_data("l"); // 发送字符"o"send_data(" "); // 发送空格send_data("W"); // 发送字符"W"send_data("o"); // 发送字符"r"send_data("r"); // 发送字符"l"send_data("d"); // 发送字符"d"while(1); // 循环等待}void init_uart() // 初始化UART 函数{TMOD = 0x20; // 设置定时器1 为工作状态TH1 = 0xfd; // 设置定时器1 的计数值TL1 = 0xfd; // 设置定时器1 的计数值TR1 = 1; // 使能定时器1SCON = 0x40; // 设置串口工作状态ES = 0; // 开总中断EA = 1; // 开总中断允许}void send_data(unsigned char dat) // 发送数据函数{SBUF = dat; // 将数据存入缓存寄存器while(!TI); // 等待发送缓存清空TI = 0; // 清空发送缓存}```四、实例详解1.配置串口:通过设置UART TXD 引脚为P3.1,确定波特率、数据位、停止位和奇偶校验等参数。
串口通信vc实例
Vc 程序串口通信实例#include "stdafx.h"#include"resource.h"#include"stdio.h"#include<stdlib.h>#include"malloc.h"#include <signal.h>#include<afxdlgs.h>#include"MAPIGUID.H"HINSTANCE g_hInstance = 0;HWND hwnd=0;HANDLE hCom=0;double W=0,H=0;int Tnum=0,Pnum=0,Anum=0,Jt=0,Mnum=0;int OnTimer(HWND hWnd);unsigned char buf[8]={0};void Oncreate(HWND hWnd,WPARAM wParam){char sztext[10]={0};CreateWindowEx(0,"STATIC","#108",SS_ICON|WS_CHILD|WS_VISIBLE,30*W,5*H,20, 20,hWnd,(HMENU)1137,g_hInstance,NULL);HWND butt=CreateWindowEx(0,"Button","确定发送",WS_CHILD|WS_VISIBLE,1250*W,1*H,100*W,40*H,hWnd,(HMENU)1003,g_hInstance,NU LL);HWNDsim=CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","Simple",WS_CHILD|CBS_DR OPDOWN|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_AUTOVS CROLL|WS_VSCROLL,280*W,100*H,200*W,200,hWnd,(HMENU)1001,g_hInstance,NULL);HWNDdro=CreateWindowEx(0,"COMBOBOX","DropDown",WS_CHILD|WS_VISIBLE|CBS_DROP DOWN|WS_VSCROLL,870*W,100*H,200*W,200,hWnd,(HMENU)1002,g_hInstance,NULL);HWNDsim1=CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","Simple",WS_CHILD|CBS_DROPDOWN|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_AUTOV SCROLL|WS_VSCROLL,280*W,200*H,200*W,200,hWnd,(HMENU)1005,g_hInstance,NULL);HWNDdro1=CreateWindowEx(0,"COMBOBOX","DropDown",WS_CHILD|WS_VISIBLE|CBS_DROP DOWN|WS_VSCROLL,870*W,200*H,200*W,200,hWnd,(HMENU)1004,g_hInstance,NULL);HWNDdro2=CreateWindowEx(0,"COMBOBOX","DropDown",WS_CHILD|WS_VISIBLE|CBS_DROP DOWN|WS_VSCROLL,280*W,300*H,200*W,200,hWnd,(HMENU)1006,g_hInstance,NULL);HFONThFont=CreateFont(30*W,0,0,0,1000*H,FALSE,FALSE,FALSE,GB2312_CHARSET,0,0,0,0,"黑体");SendMessage(sim,WM_SETFONT,(WPARAM)hFont,1);SendMessage(dro,WM_SETFONT,(WPARAM)hFont,1);SendMessage(sim1,WM_SETFONT,(WPARAM)hFont,1);SendMessage(dro1,WM_SETFONT,(WPARAM)hFont,1);SendMessage(dro2,WM_SETFONT,(WPARAM)hFont,1);HWND simple=GetDlgItem(hWnd,1001);HWND simple1=GetDlgItem(hWnd,1002);HWND simple3=GetDlgItem(hWnd,1005);HWND simple2=GetDlgItem(hWnd,1004);HWND simple4=GetDlgItem(hWnd,1006);sprintf(sztext,"%s","50");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple,CB_SETCURSEL,1,0);sprintf(sztext,"%s","100");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple,CB_SETCURSEL,1,0);sprintf(sztext,"%s","150");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple,CB_SETCURSEL,1,0);sprintf(sztext,"%s","200");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple,CB_SETCURSEL,1,0);sprintf(sztext,"%s","50");SendMessage(simple3,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple3,CB_SETCURSEL,1,0);sprintf(sztext,"%s","100");SendMessage(simple3,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple3,CB_SETCURSEL,1,0);sprintf(sztext,"%s","150");SendMessage(simple3,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple3,CB_SETCURSEL,1,0);sprintf(sztext,"%s","200");SendMessage(simple3,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple3,CB_SETCURSEL,1,0);sprintf(sztext,"%s","1000");SendMessage(simple2,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple2,CB_SETCURSEL,1,0);sprintf(sztext,"%s","1100");SendMessage(simple2,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple2,CB_SETCURSEL,1,0);sprintf(sztext,"%s","1200");SendMessage(simple2,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple2,CB_SETCURSEL,1,0);sprintf(sztext,"%s","2");SendMessage(simple1,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple1,CB_SETCURSEL,1,0);sprintf(sztext,"%s","3");SendMessage(simple1,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple1,CB_SETCURSEL,1,0);sprintf(sztext,"%s","3000");SendMessage(simple4,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple4,CB_SETCURSEL,1,0);sprintf(sztext,"%s","5000");SendMessage(simple4,CB_ADDSTRING,0,(LPARAM)sztext);SendMessage(simple4,CB_SETCURSEL,1,0);//SendMessage(simple1,CB_SETCURSEL,1,0)//SendMessage(red50,WM_SETFONT,(WPARAM)hFont,1);DeleteObject(hFont);}void Onpaint(HWND hWnd){char szText[]="限制车速";char szText2[]="Km/h";char szText1[]="恢复车速";char satext[]="怠速时发动机转速";char satext1[]="发动机转速参数";char satext3[]="转/min";char satext2[]="串口通信限速器功能设定界面";char szText3[]="脉冲变量";char szText4[]="脉冲/Km";PAINTSTRUCT ps={0};HDC hdc=BeginPaint(hWnd,&ps);SetTextColor(hdc,RGB(200,150,0));SetBkColor(hdc, RGB(240,240,240));//SetBkMode(hdc,RGB(0,0,255));HFONThFont=CreateFont(50*H,0,0,0,500*W,FALSE,FALSE,FALSE,GB2312_CHARSET,0,0,0,0,"黑体");HGDIOBJ oldfont=SelectObject(hdc,hFont);TextOut(hdc,80*W,305*H,szText,strlen(szText));TextOut(hdc,850*W,305*H,szText1,strlen(szText1));TextOut(hdc,20*W,455*H,satext,strlen(satext));TextOut(hdc,870*W,455*H,satext1,strlen(satext1));TextOut(hdc,80*W,605*H,szText3,strlen(szText3));SelectObject(hdc,oldfont);SetTextColor(hdc,RGB(100,220,150));oldfont=SelectObject(hdc,hFont);TextOut(hdc,670*W,305*H,szText2,strlen(szText2));TextOut(hdc,1450*W,305*H,szText2,strlen(szText2));TextOut(hdc,700*W,455*H,satext3,strlen(satext3));TextOut(hdc,670*W,605*H,szText4,strlen(szText4));SetTextColor(hdc,RGB(200,150,0));SelectObject(hdc,oldfont);hFont=CreateFont(80*H,0,0,0,500*W,FALSE,FALSE,FALSE,GB2312_CHARSET,0,0,0,0,"黑体");oldfont=SelectObject(hdc,hFont);TextOut(hdc,280*W,80*H,satext2,strlen(satext2));SelectObject(hdc,oldfont);// InvalidateRect( hWnd, NULL, FALSE );}void OnRButtonUp(HWND hWnd,LPARAM lParam){HMENU hPopup=CreatePopupMenu();AppendMenu(hPopup,MF_STRING,2001,"关于");AppendMenu(hPopup,MF_SEPARATOR,0,"");AppendMenu(hPopup,MF_STRING,2005,"说明");AppendMenu(hPopup,MF_SEPARATOR,0,"");AppendMenu(hPopup,MF_STRING,2004,"串口链接");AppendMenu(hPopup,MF_SEPARATOR,0,"");AppendMenu(hPopup,MF_STRING,2007,"串口断开");AppendMenu(hPopup,MF_SEPARATOR,0,"");AppendMenu(hPopup,MF_STRING,2002,"退出界面");POINT pt={0};pt.x=LOWORD(lParam);pt.y=HIWORD(lParam);ClientToScreen(hWnd,&pt);TrackPopupMenu(hPopup,TPM_VCENTERALIGN|TPM_CENTERALIGN,pt.x,pt.y,0,hWn d,NULL);}void OnCollect(HWND hWnd){char szText[10]={0};char stext1[256]={0};GetDlgItemText(hWnd,1001,szText,10);Tnum=atoi(szText);GetDlgItemText(hWnd,1005,szText,10);Pnum=atoi(szText);GetDlgItemText(hWnd,1004,szText,10);Anum=atoi(szText);GetDlgItemText(hWnd,1002,szText,10);Jt=atoi(szText);GetDlgItemText(hWnd,1006,szText,10);Mnum=atoi(szText);// sprintf(stext1,"%d%s%d%s%d%s%d",Tnum,"--",Pnum,"--",Anum,"--",Jt);// MessageBox(NULL,stext1,"",MB_OK);// OnTimer(hWnd);}void InItDIAlog(HWND hDlg,WPARAM wParam){HWNDsim1=CreateWindowEx(WS_EX_CLIENTEDGE,"COMBOBOX","Simple",WS_CHILD|CBS_D ROPDOWN|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL|ES_MULTILINE|ES_AUTOV SCROLL|WS_HSCROLL|WS_VSCROLL,90,35,200,100,hDlg,(HMENU)2004,g_hInstance,NU LL);HWNDdro1=CreateWindowEx(0,"COMBOBOX","DropDown",WS_CHILD|WS_VISIBLE|CBS_DROP DOWN|WS_VSCROLL,90,85,200,100,hDlg,(HMENU)2005,g_hInstance,NULL);HFONThFont1=CreateFont(30,0,0,0,1500,FALSE,FALSE,FALSE,GB2312_CHARSET,0,0,0,0,"黑体");SendMessage(sim1,WM_SETFONT,(WPARAM)hFont1,1);SendMessage(dro1,WM_SETFONT,(WPARAM)hFont1,1);}void Dlgcom1(HWND hDlg){char stext1[]="1200 HZ";char stext2[]="2400 HZ";char stext3[]="4800 HZ";char stext4[]="9600 HZ";char stext5[]="14400 HZ";char stext6[]="19200 HZ";char stext7[]="28800 HZ";char stext8[]="38400 HZ";char stext9[]="57600 HZ";char stext10[]="115200 HZ";HWND simple=GetDlgItem(hDlg,2005);//LRESULT nSe=SendMessage(simple,CB_GETCURSEL,0,0);//GetDlgItemText(hWnd,1001,szText,256);// a1=atof(szText);// sprintf(stext,"%g%s",a1," V");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext1);// SendMessage(simple,CB_SETCURSEL,1,0);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext2);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext3);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext4);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext5);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext6);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext7);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext8);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext9);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext10);//SendMessage(simple,CB_SETCURSEL,1,0);//SetDlgItemText(hDlg,2004,stext1);}void Dlgcom(HWND hDlg){char stext1[]="COM1";char stext2[]="COM2";char stext3[]="COM3";char stext4[]="COM4";char stext5[]="COM5";char stext6[]="COM6";char stext7[]="COM7";char stext8[]="COM8";HWND simple=GetDlgItem(hDlg,2004);//LRESULT nSe=SendMessage(simple,CB_GETCURSEL,0,0);//GetDlgItemText(hWnd,1001,szText,256);// a1=atof(szText);// sprintf(stext,"%g%s",a1," V");SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext1); // SendMessage(simple,CB_SETCURSEL,1,0);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext2);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext3);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext4);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext5);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext6);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext7);SendMessage(simple,CB_ADDSTRING,0,(LPARAM)stext8);//SendMessage(simple,CB_SETCURSEL,1,0);//SetDlgItemText(hDlg,2004,stext1);}int Cmpa(char* str){if(strcmp(str,"COM1")==0)return 1;if(strcmp(str,"COM2")==0)return 2;if(strcmp(str,"COM3")==0)return 3;if(strcmp(str,"COM4")==0)return 4;if(strcmp(str,"COM5")==0)return 5;if(strcmp(str,"COM6")==0)return 6;if(strcmp(str,"COM7")==0)return 7;if(strcmp(str,"COM8")==0)return 8;}UINT MyControllingFunction( LPVOID pParam ){char buf2[70]={0};unsigned char buf1[8]={0};DWORD dwBytesRead=8;COMSTAT ComStat;DWORD dwErrorFlags;OVERLAPPED m_osRead;// MessageBox(NULL,buf,"",MB_OK);// sprintf(buf1,"%d%s%d%s%d%s%d",buf[0],"--",buf[1],"--",buf[2],"--",buf[3]); // MessageBox(NULL,buf1,"",MB_OK);memset(&m_osRead,0,sizeof(OVERLAPPED));m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);//ClearCommError(hCom,&dwErrorFlags,&ComStat);dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue);if(!dwBytesRead)return FALSE;BOOL bReadStatus;//Sleep(100);bReadStatus=ReadFile(hCom,buf1,dwBytesRead,&dwBytesRead,&m_osRead);/* char ttt[10]={0};sprintf(ttt,"%d",bReadStatus);MessageBox(NULL,ttt,"",MB_OK);*/if(!bReadStatus) //如果ReadFile函数返回FALSE{if(GetLastError()==ERROR_IO_PENDING)//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作{WaitForSingleObject(m_osRead.hEvent,500);//使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟//当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);if(buf[0]==buf1[0]&&buf[1]==buf1[1]&&buf[2]==buf1[2]&&buf[3]==buf1[3]&&buf[4]== buf1[4]&&buf[5]==buf1[5]&&buf[6]==buf1[6]&&buf[7]==buf1[7]){sprintf(buf2,"%s%d%s%d%s%d%s%d%s%d%s","发动机转速:",buf1[0]*256+buf1[1],"转/min;转速参数:",buf1[2],";限制车速:",buf1[3],"Km/h;恢复车速:",buf1[4],";脉冲/km:",buf1[5]*256+buf1[6]," 成功!");MessageBox(hwnd,buf2,"Ifon",MB_OK);}else{MessageBox(hwnd,"设置失败!请查看串口是否连接好。
c串口编程实例
c串口编程实例C串口编程实例C串口编程是指使用C语言进行串口通信的编程方法。
串口通信是指通过串行接口进行数据传输的方式,常用于计算机与外部设备之间的数据交互。
C串口编程可以实现计算机与外部设备的数据传输和控制,具有广泛的应用场景。
一、串口基础知识在进行C串口编程之前,首先需要了解一些串口的基础知识。
串口通信一般使用RS232C标准,其通信原理是通过发送和接收数据位来实现数据传输。
串口通信有多种参数需要设置,包括波特率、数据位、停止位、奇偶校验等。
在C串口编程中,需要根据具体的串口配置参数来进行编程。
二、C串口编程步骤1. 打开串口在C串口编程中,首先需要打开串口。
通过调用相关的函数,可以打开指定的串口,并获取串口的文件描述符。
2. 配置串口参数打开串口后,需要进行串口参数的配置。
通过调用相关的函数,可以设置串口的波特率、数据位、停止位、奇偶校验等参数。
3. 读取串口数据配置好串口参数后,就可以通过读取串口数据的方式来获取外部设备发送的数据。
通过调用相关的函数,可以从串口缓冲区中读取数据,并存储到指定的变量中。
4. 发送串口数据除了读取串口数据,C串口编程还可以实现发送数据到外部设备的功能。
通过调用相关的函数,可以将指定的数据发送到串口缓冲区,并通过串口发送给外部设备。
5. 关闭串口在C串口编程结束后,需要关闭串口。
通过调用相关的函数,可以关闭指定的串口,并释放相关资源。
三、C串口编程实例下面是一个简单的C串口编程实例,实现了从串口读取数据并将数据打印出来的功能:```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>int main(){int fd;char buffer[255];// 打开串口fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1){perror("打开串口失败");exit(EXIT_FAILURE);}// 配置串口参数struct termios options;tcgetattr(fd, &options);cfsetispeed(&options, B9600);cfsetospeed(&options, B9600);options.c_cflag |= (CLOCAL | CREAD);options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;options.c_cflag &= ~CSIZE;options.c_cflag |= CS8;tcsetattr(fd, TCSANOW, &options);// 读取串口数据并打印while (1){int count = read(fd, buffer, sizeof(buffer));if (count > 0){buffer[count] = '\0';printf("收到数据:%s\n", buffer);}}// 关闭串口close(fd);return 0;}```以上代码通过打开串口、配置串口参数、读取串口数据和关闭串口的方式实现了简单的C串口编程。
VC串口通讯实例
在VC++中有两种方法可以进行串口通讯。
一种是利用Microsoft公司提供的ActiveX 控件Microsoft Communications Control。
另一种是直接用VC++访问串口。
下面将简述这两种方法。
一、Microsoft Communications ControlMicrosoft公司在WINDOWS中提供了一个串口通讯控件,用它,我们可以很简单的利用串口进行通讯。
在使用它之前,应将控件加在应用程序的对话框上。
然后再用ClassWizard 生成相应的对象。
现在我们可以使用它了。
该控件有很多自己的属性,你可以通过它的属性窗口来设置,也可以用程序设置。
我推荐用程序设置,这样更灵活。
SetCommPort:指定使用的串口。
GetCommPort:得到当前使用的串口。
SetSettings:指定串口的参数。
一般设为默认参数"9600,N,8,1"。
这样方便与其他串口进行通讯。
GetSettings:取得串口参数。
SetPortOpen:打开或关闭串口,当一个程序打开串口时,另外的程序将无法使用该串口。
GetPortOpen:取得串口状态。
GetInBufferCount:输入缓冲区中接受到的字符数。
SetInPutLen:一次读取输入缓冲区的字符数。
设置为0时,程序将读取缓冲区的全部字符。
GetInPut:读取输入缓冲区。
GetOutBufferCount:输出缓冲区中待发送的字符数。
SetOutPut:写入输出缓冲区。
一般而言,使用上述函数和属性就可以进行串口通讯了。
以下是一个范例。
#define MESSAGELENGTH 100class CMyDialog : public CDialog{protected:VARIANT InBuffer;VARIANT OutBuffer;CMSComm m_Com;public:......}BOOL CMyDiaLog::OnInitDialog(){CDialog::OnInitDialog();m_Com.SetCommPort(1);if (!m_Com.GetPortOpen()) {m_Com.SetSettings("57600,N,8,1");m_Com.SetPortOpen(true);m_Com.SetInBufferCount(0);SetTimer(1,10,NULL);InBuffer.bstrVal=new unsigned short[MESSAGELENGTH]; OutBuffer.bstrVal=new unsigned short[MESSAGELENGTH]; OutBuffer.vt=VT_BSTR;}return true;}void CMyDiaLog::OnTimer(UINT nIDEvent){if (m_Com.GetInBufferCount()>=MESSAGELENGTH) { InBuffer=m_Com.GetInput();// handle the InBuffer.// Fill the OutBuffer.m_Com.SetOutput(OutBuffer);}CDialog::OnTimer(nIDEvent);}用该控件传输的数据是UNICODE格式。
vc++_串口上位机编程实例 附vc串口通信(接收)
VC++串口上位机简单例程(源码及详细步骤)VC++编写简单串口上位机程序串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC 转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC进行数值转换后在窗口里显示。
(见文章末尾图)3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。
程序的编写:1、打开VC++6.0建立基于对话框的MFC应用程序Test,2、在项目中插入MSComm控件:工程->增加到工程->Components and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。
基于VC的串行通信技术应用实例
如果所规定的待读取数据的数目nWantRead较大且设定的超时时间也较长,而接收缓冲区中数据较少,则可能引起线程阻塞。解决这一问题的方法是检查COMSTAT结构的cbInQue成员,该成员的大小即为接收缓冲区中处于等待状态的数据的实际个数。如果令nWantRead的值等于COMSTAT.cbInQue,就能较好地防止线程阻塞。
通信程序在CreateFile处指定串口设备及相关的操作属性,再返回一个句柄,该句柄将被用于后续的通信操作,并贯穿整个通信过程。串口打开后,其属性被设置为默认值,根据具体需要,通过调用GetCommState(hComm,&&dcb)读取当前串口设备控制块DCB设置,修改后通过SetCommState(hComm,&&dcb)将其写入。运用ReadFile()与WriteFile()这两个API函数实现串口读写操作,若为异步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,调用GetLastError()函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用WaitForSingleObject()来等待结束信号并设置最长等待时间,举例如下:
3.异步方式
异步方式中,利用Windows的多线程结构,可以让串口的读写操作在后台进行,而应用程序的其他部分在前台执行。例如:
OVERLAPPED wrOverlapped;
COMMTIMEOUTS timeOver;
memset(&&timeOver.0.sizeof(timeOver));
基于VC的串行通信技术应用实例
作者:李湘江 时间:01-27 来源:中国计算机报 字体:【大 中 小】 第1页第2页
c语言怎么写串口通信编程
c语言怎么写串口通信编程串口通信是一种广泛应用于嵌入式系统和电子设备之间的通信方式。
无论是嵌入式开发还是电子设备控制,串口通信都是常见的需求。
在C语言中,实现串口通信需要通过操作串口的硬件寄存器和使用相应的通信协议来实现数据的发送和接收。
本文将一步一步介绍如何使用C语言编写串口通信程序。
第一步:打开串口要开始串口通信,首先需要打开串口。
在C语言中,可以使用文件操作函数来打开串口设备。
通常,串口设备被命名为/dev/ttyS0,/dev/ttyS1等,具体名称取决于系统。
下面是一个打开串口设备的示例代码:cinclude <stdio.h>include <fcntl.h>include <termios.h>int open_serial_port(const char *port) {int fd = open(port, O_RDWR O_NOCTTYO_NDELAY);if (fd == -1) {perror("open_serial_port");return -1;}设置串口属性struct termios options;tcgetattr(fd, &options);cfmakeraw(&options);cfsetspeed(&options, B9600);tcsetattr(fd, TCSANOW, &options);return fd;}int main() {const char *port = "/dev/ttyS0";int fd = open_serial_port(port);if (fd == -1) {打开串口失败,处理错误return -1;}串口已打开,可以进行数据的读写操作return 0;}在上面的代码中,open_serial_port函数用于打开指定的串口设备并进行一些必要的设置。
visualbasic串口通信及编程实例
visualbasic串口通信及编程实例Visual Basic串口通信及编程实例在实际的工业控制、机器人控制、智能家居等领域中,使用串口通信是一种非常广泛的方式。
Visual Basic (VB) 是一种微软公司开发的高级编程语言,它不仅易于学习,而且拥有丰富的图形界面设计和数据处理功能。
在本篇文章中,我们将深入介绍如何使用VB实现串口通信。
1. 建立串口通信首先,我们需要在VB中创建一个新的窗口(Form),然后打开工具箱,从中拖拽出一个SerialPort(串口)控件。
在控件属性中,我们需要为其指定相关的参数,例如串口名称、波特率、数据位、停止位、校验位等。
通常情况下,这些参数需要根据硬件设备的配置来进行调整。
在VB中实现串口通信的核心部分是对于SerialPort控件的事件监控。
具体来讲,当SerialPort收到一个数据包时,它会触发一个DataReceived事件。
对于这个事件,我们可以在程序中编写回调函数进行处理。
例如:Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e AsSystem.IO.Ports.SerialDataReceivedEventArgs) HandlesSerialPort1.DataReceived'在这里实现对于数据包的解析和处理End Sub2. 数据读取和发送在SerialPort控件中,有几种方法可以实现数据的读取和发送。
下面我们将介绍其中两种方法:(1) ReadExisting这个方法可以从串口中读取所有现有的数据,例如:Dim data As String = SerialPort1.ReadExisting()(2) Write这个方法可以向串口发送数据,例如:SerialPort1.Write("Hello World")注意,这个函数只能发送字符串数据。
vc串口通信编程详解
vc串口通信编程详解
串口通信简介
串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。
一般完成这种功能的电路,我们称为串行接口电路。
串口通信结构
串口通信是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。
这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。
串口是计算机上一种非常通用的设备通信协议。
大多数计算机(不包括笔记本电脑)包含两个基于RS-232的串口。
串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。
同时,串口通信协议也可以用于获取远程采集设备的数据。
RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。
可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接。
vc串口编程实例
我了,今天就总结这么多,下一篇打算说说vc++在绘图方面的使用。
博客园 用户登录 代码改变世界 密码登录 短信登录 忘记登录用户名 忘记密码 记住我 登录 第三方登录/注册 没有账户, 立即注册
vc串 口 编 程 实 例
今天总结一下使用vc++操作串口的程序,使用vc++编写的串口程序,大致分为一下几种 1.使用Win32 API函数编写串口程序; 2.使用VC++自带的控件MScomm控件; 3.网上有许多程序爱好者自己编写了串口通信类,我们可以下下来使用;
vc串口通信程序
CComPort::ReceiveMode CComPort::GetReceiveMode() { return this->m_RecvMode; } DWORD CComPort::GetInBufferCount() { if(this->IsOverlapped()) { ::AfxMessageBox("this methord is only used for ManualQueryMode!"); return 0; } COMSTAT stat; ::ZeroMemory(&stat,sizeof(stat)); this->m_pPort->GetStatus(stat); return stat.cbInQue; } DWORD CComPort::GetInput(void* pBuf,DWORD Count,DWORD dwMilliseconds) { //不能在自动模式下getinput if(this->GetReceiveMode()==CComPort::AutoReceiveByBreak|| this->GetReceiveMode()==CComPort::AutoReceiveBySignal)
// ComPort.cpp : 实现文件 // #include "stdafx.h" #include "ComPort.h" namespace LsComm{ // CComPort CComPort::CComPort() : m_bIsOpen(false) { this->m_pfnOnReceiveData = NULL; this->m_pfnOnComBreak =NULL; this->m_pPort = NULL; this->m_pReadThread = NULL; ::ZeroMemory(&this->m_WriteOverlapped,sizeof(this->m_WriteOverlapped)); this->m_hWriteEvent = NULL; this->m_bIsOpen = false; } CComPort::~CComPort() { if(this->m_pPort) { if(this->m_pPort->IsOpen()) { this->Close(); } } if(this->m_pPort) { delete this->m_pPort; this->m_pPort = NULL; } } // CComPort 成员函数 // //当前串口是否打开 bool CComPort::IsOpen(void) { return this->m_bIsOpen; } bool CComPort::Open(int nPort,ReceiveMode mode, DWORD dwBaud, Parity parity, BYTE DataBi ts, StopBits stopbits,FlowControl fc) { //1.新建串口 if(this->m_pPx("Can't use GetInput methord in this mode!"); return 0; } if(this->IsOverlapped()) { ASSERT(this->m_pReadThread); DWORD dwBytes = this->m_pReadThread->ReadInput(pBuf,Count,dwMilliseconds); this->m_pPort->TerminateOutstandingReads(); return dwBytes; } else return this->m_pPort->Read(pBuf,Count); } DWORD CComPort::Output(void* pBuf,DWORD Count) { DWORD dwWriteBytes=0; if(this->IsOverlapped())//异步模式 { this->m_pPort->Write(pBuf,Count,this->m_WriteOverlapped); if(WaitForSingleObject(this->m_WriteOverlapped.hEvent,INFINITE)==WAIT_OBJECT_0) { this->m_pPort->GetOverlappedResult(this->m_WriteOverlapped,dwWriteBytes,fals e); } } else { /*for(DWORD i=0;i<Count;i++) { dwWriteBytes+= this->m_pPort->Write(pBuf,1); } //for use in win98 */ dwWriteBytes = this->m_pPort->Write(pBuf,Count); } return dwWriteBytes; } CSerialPort* CComPort::GetSerialPort() { ASSERT(m_pPort); return m_pPort; } HANDLE CComPort::GetCloseHandle() { ASSERT(this->m_hCloseEvent); return this->m_hCloseEvent; } //CReadComThread CReadComThread::CReadComThread() {
windows串口通信vc++编程实例
串口通信在嵌入式系统、物联网设备等领域中广泛应用,其中在Windows平台上使用C++编程实现串口通信是一种常见的需求。
以下是一个简单的Windows串口通信的VC++编程实例,涵盖串口的打开、配置、发送和接收数据的基本操作。
**1. 创建一个VC++项目:**打开Visual Studio,创建一个新的Win32控制台应用程序项目。
选择C++语言。
**2. 引入头文件:**在项目中引入Windows API的头文件和一些必要的库文件。
```cpp#include <windows.h>#include <tchar.h>#include <iostream>```**3. 定义串口句柄:**在全局范围内定义串口句柄,用于后续的串口操作。
```cppHANDLE hSerial;```**4. 初始化串口:**创建一个初始化串口的函数,用于打开并配置串口。
```cppbool InitSerialPort(const TCHAR* portName, DWORD baudRate) {hSerial = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hSerial == INVALID_HANDLE_VALUE) {std::cerr << "Error opening serial port!" << std::endl;return false;}DCB dcbSerialParams = { 0 };dcbSerialParams.DCBlength = sizeof(dcbSerialParams);if (!GetCommState(hSerial, &dcbSerialParams)) {std::cerr << "Error getting serial port state!" << std::endl;CloseHandle(hSerial);return false;}dcbSerialParams.BaudRate = baudRate;dcbSerialParams.ByteSize = 8;dcbSerialParams.StopBits = ONESTOPBIT;dcbSerialParams.Parity = NOPARITY;if (!SetCommState(hSerial, &dcbSerialParams)) {std::cerr << "Error setting serial port state!" << std::endl;CloseHandle(hSerial);return false;}return true;}```**5. 发送数据:**创建一个发送数据的函数,用于向串口发送数据。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
串口编程的一个实例为了让您更好地理解串口编程,下面我们分别编写两个例程(见附带的源码部分),这两个例程都实现了工控机与百特显示仪表通过RS485接口进行的串口通信。
其中第一个例程采用同步串口操作,第二个例程采用异步串口操作。
我们只介绍软件部分,RS485接口接线方法不作介绍,感兴趣的读者可以查阅相关资料。
例程1打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。
在RS485CommDlg.cpp文件中添加全局变量:HANDLE hCom; //全局变量,串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码:// TODO: Add extra initialization here hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式 NULL, OPEN_EXISTING, //打开而不是创建 0, //同步方式 NULL);if(hCom==(HANDLE)-1) { AfxMessageBox("打开COM失败!"); return FALSE; } SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是1024 COMMTIMEOUTS TimeOuts; //设定读超时TimeOuts.ReadIntervalTimeout=MAXDWORD;TimeOuts.ReadTotalTimeoutMultiplier=0;TimeOuts.ReadTotalTimeoutConstant=0; //在读一次输入缓冲区的内容后读操作就立即返回, //而不管是否读入了要求的字符。
//设定写超时TimeOuts.WriteTotalTimeoutMultiplier=100;TimeOuts.WriteTotalTimeoutConstant=500;SetCommTimeouts(hCom,&TimeOuts); //设置超时 DCB dcb;GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位dcb.StopBits=TWOSTOPBITS; //两个停止位 SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数:void CRS485CommDlg::OnSend() { // TODO: Add your control notification handler code here // 在此需要简单介绍百特公司XMA5000的通讯协议: //该仪表RS485通讯采用主机广播方式通讯。
//串行半双工,帧11位,1个起始位(0),8个数据位,2个停止位(1) //如:读仪表显示的瞬时值,主机发送:DC1 AAA BB ETX //其中:DC1是标准ASCII码的一个控制符号,码值为11H(十进制的17) //在XMA5000的通讯协议中,DC1表示读瞬时值 //AAA是从机地址码,也就是XMA5000显示仪表的通讯地址 //BB为通道号,读瞬时值时该值为01//ETX也是标准ASCII码的一个控制符号,码值为03H //在XMA5000的通讯协议中,ETX表示主机结束符 char lpOutBuffer[7];memset(lpOutBuffer,''\0'',7); //前7个字节先清零lpOutBuffer[0]=''\x11''; //发送缓冲区的第1个字节为DC1lpOutBuffer[1]=''0''; //第2个字节为字符0(30H) lpOutBuffer[2]=''0'';//第3个字节为字符0(30H) lpOutBuffer[3]=''1''; // 第4个字节为字符1(31H) lpOutBuffer[4]=''0''; //第5个字节为字符0(30H)lpOutBuffer[5]=''1''; //第6个字节为字符1(31H) lpOutBuffer[6]=''\x03'';//第7个字节为字符ETX //从该段代码可以看出,仪表的通讯地址为001 DWORDdwBytesWrite=7; COMSTAT ComStat; DWORD dwErrorFlags; BOOL bWriteStat; ClearCommError(hCom,&dwErrorFlags,&ComStat);bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,&dwBytesWrite,NULL); if(!bWriteStat) { AfxMessageBox("写串口失败!"); } } 您可以观察返回的字符串,其中有和仪表显示值相同的部分,您可以进行相应的字符串操作取出仪表的显示值。
打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数:void CRS485CommDlg::OnClose() { // TODO: Add your message handler codehere and/or call default CloseHandle(hCom); //程序退出时关闭串口CDialog::OnClose(); }程序的相应部分已经在代码内部作了详细介绍。
连接好硬件部分,编译运行程序,细心体会串口同步操作部分。
例程2打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。
在RS485CommDlg.cpp文件中添加全局变量:HANDLE hCom; //全局变量,串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码:hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式 NULL, OPEN_EXISTING, //打开而不是创建FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式 NULL);if(hCom==(HANDLE)-1) { AfxMessageBox("打开COM失败!"); return FALSE; }SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是100COMMTIMEOUTS TimeOuts; //设定读超时TimeOuts.ReadIntervalTimeout=MAXDWORD;TimeOuts.ReadTotalTimeoutMultiplier=0;TimeOuts.ReadTotalTimeoutConstant=0; //在读一次输入缓冲区的内容后读操作就立即返回, //而不管是否读入了要求的字符。
//设定写超时TimeOuts.WriteTotalTimeoutMultiplier=100;TimeOuts.WriteTotalTimeoutConstant=500;SetCommTimeouts(hCom,&TimeOuts); //设置超时 DCB dcb;GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位dcb.StopBits=TWOSTOPBITS; //两个停止位 SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);分别双击IDC_SEND按钮和IDC_RECEIVE按钮,添加两个按钮的响应函数:void CRS485CommDlg::OnSend() { // TODO: Add your control notification handler code here OVERLAPPED m_osWrite;memset(&m_osWrite,0,sizeof(OVERLAPPED));m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); charlpOutBuffer[7]; memset(lpOutBuffer,''\0'',7); lpOutBuffer[0]=''\x11''; lpOutBuffer[1]=''0''; lpOutBuffer[2]=''0''; lpOutBuffer[3]=''1''; lpOutBuffer[4]=''0''; lpOutBuffer[5]=''1''; lpOutBuffer[6]=''\x03''; DWORD dwBytesWrite=7; COMSTAT ComStat; DWORD dwErrorFlags; BOOL bWriteStat; ClearCommError(hCom,&dwErrorFlags,&ComStat);bWriteStat=WriteFile(hCom,lpOutBuffer, dwBytesWrite,&dwBytesWrite,&m_osWrite); if(!bWriteStat){ if(GetLastError()==ERROR_IO_PENDING){ WaitForSingleObject(m_osWrite.hEvent,1000); } } } voidCRS485CommDlg::OnReceive() { // TODO: Add your control notification handler code here OVERLAPPED m_osRead;memset(&m_osRead,0,sizeof(OVERLAPPED));m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); COMSTAT ComStat; DWORD dwErrorFlags; char str[100]; memset(str,''\0'',100); DWORD dwBytesRead=100;//读取的字节数 BOOL bReadStat;ClearCommError(hCom,&dwErrorFlags,&ComStat);dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);bReadStat=ReadFile(hCom,str, dwBytesRead,&dwBytesRead,&m_osRead);if(!bReadStat) { if(GetLastError()==ERROR_IO_PENDING) //GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作{ WaitForSingleObject(m_osRead.hEvent,2000); //使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟 //当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号 } } PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); m_disp=str;UpdateData(FALSE); }打开ClassWizard,为静态文本框IDC_DISP添加CString类型变量m_disp,同时添加WM_CLOSE的相应函数:void CRS485CommDlg::OnClose() { // TODO: Add your message handler code here and/or call default CloseHandle(hCom); //程序退出时关闭串口CDialog::OnClose(); }。