java c 串口通信_基于C语言的java串口通信程序

目录

1.前言

2.windows  串口通信API

3.JAVA-JNI  java程序调用C++程序

4.C/C++封装  动态运行库

一、前言

写这个博客主要是因为自己想用java写一个小小的后端服务器,其中要处理由51单片机传送来的一些数据。单片机的数据由USB转串口发送至上位机,要处理这些数据,就会用到windows提供一些API(Application Programming Interface,应用程序接口)。java在安装了相关的包后,比如JNative.jar,可以直接用该包提供的接口来进行调用windowsAPI。但是我才接触java。而且整个作业,我仅仅只要一部分来处理这个数据。安装一个java包,实在是大可不必,所以就用C/C++来写一个的终端,封装一下放在java程序里面。

二、windows串口通信API

2.1   工具:VC++6.0

2.2   概述:windows操作系统的设备无关性将所有的外设都当做文件来操作,那么我们写串口通信就直接将串口当做文件来读写。那么我们打开串口后一定要记得关闭,这个很重要

2.3   串口通信程序概述

2.3.1 打开/关闭串口

HANDLE WINAPI CreateFileW(

LPCWSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode, //共享模式

LPSECURITY_ATTRIBUTES lpSecurityAttributes, //安全属性

DWORD dwCreationDisposition, //指定文件的动作

DWORD dwFlagsAndAttributes, //文件属性---不指定就默认为同步IO

HANDLE hTemplateFile //模板文件

);

BOOL WINAPI CloseHandle(

HANDLE hObject

);

返回值:一个串口的句柄。

参数解释:

lpFileName——串口名字。 当为COM1~COM9的时候可以直接写入但是大于10会有另外的写法。以COM10为例:\.\COM10。

lpFileName——打开方式。 简单来说这个就是打开文件是读还是写。GENERIC_READ(读)|GENERIC_WRITE(写)。还有其它的两个值,详细请在编辑器中直接按下F12看看他们的定义。

如果我们要定义一个同步IO的话,我们的打开方式必须要有读动作。

dwShareMode指定该端口的共享属性。 对于不能共享的串口,它必须设置为0。这就是文件与通信设备之间的主要差异之一。如果在当前的应用程序调用CreateFile()时,另一个应用程序已经打开了串口,该函数就会返回错误代码,原因是两个应用程序不能共享一个端口。然而,同一个应用程序的多个线程可以共享由CreateFile()返回的端口句柄,并且根据安全性属性设置,该句柄可以被打开端口的应用程序的子程序所继承。

dwCreationDisposition指定文件的动作。 指定如果CreateFile()正在被已有的文件调用时应采取的动作。因为串口总是存在,fdwCreate必须设置成OPEN_EXISTING。该标志告诉Windows不用企图创建新端口,而是打开已经存在的端口。

调用该函数后,如果没有穿件成功将会返回INVALID_HANDLE_VALUE。

2.3.2 配置串口通信

(1) 当我们设置同步IO通信的时候,需要设置一下通信超时。一般情况下,我们用GetCommTimeouts来获得COMMTIMEOUTS结构体,再利用SetCommTimeouts来写入。

BOOL WINAPI GetCommTimeouts(

HANDLE hFile,

LPCOMMTIMEOUTS lpCommTimeouts

);

BOOL WINAPI SetCommTimeouts(

HANDLE hFile,

LPCOMMTIMEOUTS lpCommTimeouts

);

COMMTIMEOUTS:

typedef struct _COMMTIMEOUTS {

DWORD ReadIntervalTimeout; /* 设置两个字符之前的最大读取时间 */

DWORD ReadTotalTimeoutMultiplier; /* 设置每个字符的读取时间 */

DWORD ReadTotalTimeoutConstant; /* 设置所有字符读取的最大时间 */

DWORD WriteTotalTimeoutMultiplier; /* 设置每个字符的写入时间 */

DWORD WriteTotalTimeoutConstant; /* 设置所有字符的写入时间 */

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

(2) 设置波特率等相关参数

仍然先用GetCommState得到DCB结构,修改其中的某些参数后再用SetCommState写入DCB结构。

BOOL WINAPI GetCommState(

HANDLE hFile,

LPDCB lpDCB

);

BOOL WINAPI SetCommState(

HANDLE hFile,

LPDCB lpDCB

);

DCB数据结构我们初级学者需要关注:波特率、校验位、停止位、发送数据位数。

(3) 设置缓冲区大小,根据程序要接收/发送的数据大小来决定。

BOOL WINAPI SetupComm(

HANDLE hFile,

DWORD dwInQueue,

DWORD dwOutQueue

);

(4) 读取/写入数据

BOOL WINAPI ReadFile(

HANDLE hFile,

LPVOID lpBuffer, //存放数据的缓冲区

DWORD nNumberOfBytesToRead, //一次想要读入的数据长度

LPDWORD lpNumberOfBytesRead, //实际读入的数据长度

LPOVERLAPPED lpOverlapped

);

BOOL WINAPI WriteFile(

HANDLE hFile,

LPCVOID lpBuffer,

DWORD nNumberOfBytesToWrite,

LPDWORD lpNumberOfBytesWritten,

LPOVERLAPPED lpOverlapped

);

2.3.3 串口缓冲区配置

在程序运行的时候,应该保证设置的缓冲区是“干净”的。所以在读数据或者写数据之前,可以先清空一下缓冲区。

//清空缓冲区

BOOL WINAPI PurgeComm(

HANDLE hFile,

DWORD dwFlags

);

//清除错误

BOOL WINAPI ClearCommError(

HANDLE hFile,

LPDWORD lpErrors,

LPCOMSTAT lpStat

);

2.4完整的读串口代码

#include `

#include

int Comm(int nBaud,int parity,int bytesize,int stopbits,int accdatalength,char rBuf[])

{//缓冲区

DWORD rSize = 0;

DWORD dwError;//清除错误

COMSTAT cs;

COMMTIMEOUTS timeouts;//超时数据结构

DCB dcb;//串口通信配置文件---用LPDCB类型会报错

HANDLE hCom;//串口的句柄(实例)| the instance of com

hCom = CreateFile("COM3",//串口的名字

GENERIC_READ | GE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值