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

目录

1.前言

2.windows  串口通信API

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

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

一、前言

&ensp ;写这个博客主要是因为自己想用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 配置串口通信

上一篇:python学习笔记(§ 1.1)转自CSDN,知乎


下一篇:windows bat 批处理如何添加 IE 浏览器的信任站点