怎样在WINDOWS下用C语言编写串口接收数据程序

怎样在WINDOWS下用C语言编写串口接收数据程序,第1张

#include

#include

int

main(void)

{

FILE

*fp

char

temp

char

buf[100]

if((fp

=

fopen("com3","r"))

==

NULL)

puts("this

way

doesn't

work!\n")

else

puts("this

way

works!\n")

while(1)

{

temp

=

0

fscanf(fp,"%c",&temp)

if(temp

!=

0)

putchar(temp)

else

Sleep(100)

}

fclose(fp)

return

0

}

以前弄的,好久没看了,不知到对不对。

还有下面这段:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

#include

#include

HANDLE

hCom

int

main(void)

{

hCom=CreateFile(TEXT("COM3"),//COM1口

GENERIC_READ|GENERIC_WRITE,

//允许读和写

0,

//独滚链占方式

NULL,

OPEN_EXISTING,

//打开而不是创建

0,

//同步方式

NULL)

if(hCom==(HANDLE)-1)

{

printf("打开COM失败!\n")

return

FALSE

}

else

{

printf("COM打开成功!\n")

}

SetupComm(hCom,1024,1024)

//输入缓冲区和输出缓冲区的大小都是1024

COMMTIMEOUTS

TimeOuts

//设定读超时

TimeOuts.ReadIntervalTimeout=1000

TimeOuts.ReadTotalTimeoutMultiplier=500

TimeOuts.ReadTotalTimeoutConstant=5000

//设定写超时

TimeOuts.WriteTotalTimeoutMultiplier=500

TimeOuts.WriteTotalTimeoutConstant=2000

SetCommTimeouts(hCom,&TimeOuts)

//设置超大悔孙时

DCB

dcb

GetCommState(hCom,&dcb)

dcb.BaudRate=9600

//波特率为9600

dcb.ByteSize=8

//每个字节有8位

dcb.Parity=NOPARITY

//无奇偶校验位

dcb.StopBits=ONE5STOPBITS

//两个停止位

SetCommState(hCom,&dcb)

DWORD

wCount//读取的字节数

BOOL

bReadStat

while(1)

{

PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR)

//清空缓冲区

char

str[9]={0}

printf("%s\n",str)

bReadStat=ReadFile(hCom,str,9,&wCount,NULL)

if(!bReadStat)

{

printf("读串口失败!")

return

FALSE

}

else

{

str[8]='\0'

printf("%s\n",str)

}

Sleep(100)

}

}

以上两段前闹代码是一年前弄的,我记得可以用,你试试。

用API函数实现Windows下的串行通讯

冯华亮 2002年4月 四川·电子科大

以往的DOS系统是通过DOS中断和BIOS中断向用户提供串行接口的通讯能力。在Windows环境下,C++的开发工具既没有提供象DOS和BIOS

中那样专门的串行通讯控制方法,也不允许用户直接控制串口的中断。

为了保证资源共享,Windows系统完全接管了各种硬件资源,使用中断来控制端口将破坏系统的多任务性,使系统的稳定性受到影响。

但Windows同时也提供了功能强大的API函数使用户能间接的控制串行通讯。

1、实现串行通讯的相关API函数

API函数不仅提供了打开和读写通讯端口的 *** 作方法,还提供了名目繁多的函数以支持对串行通讯的各种 *** 作。常用函数及作用如表厅塌5-1所示。

表5-1 常用串行通讯API函数及其作用

函数名 作用

CreateFile 打开串口

GetCommState 检测串口设置

SetCommState 设置串口

BuilderCommDCB 用字符串中的值来填充设备控制块

GetCommTimeouts 检测通信超时设置

SetCommTimeouts 设置通信超时参数

SetCommMask 设定被监控事件

WaitCommEvent 等待被监控事件发生

WaitForMultipleObjects 等待多个被监测对象的结果

WriteFile 发送数据

ReadFile 接收数据

GetOverlappedResult 返回最后重叠(异步) *** 作结果

PurgeComm 清空串口缓冲区,退出所有相关 *** 作

ClearCommError 更新串口状态结构体,并清除所有串口硬件错误

CloseHandle 关闭串行口

2、打开串口

函数CreateFile原本用于打开文件,但它同样可用于打开一个通信端口。与系统中其他对象一样,通信端口也是用句柄来标识的。

CreateFile函数返回被 *** 作的通信端口句柄,其调用方法如下:

HANDLE CreateFile (

LPCTSTR lpFileName, //指向文件名字符串的指针

DWORD dwDesireAccess, // *** 作模式

DWORD dwShareMode,  //共享方式

LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针

DWORD dwCreationDistribution, //文件建立方式

DWORD dwFlagsAndAttributes //文件属性

HANDLE hTemplateFile //模板文件句柄

)

lpFileName:指向一个以NULL结束的字符串,该串指定了要创建、打开或截断的文件、管道、通信源、磁盘设备或控制台的名字。

当用CreateFile打开串口时,这个参数可用“COM1”指定串口1,用“COM2”指定串口2,依此类推。

dwDesireAccess: 指定对文件访问的类型,该参数可以为GENERIC_READ(指定竖并对该文件的读访问权)

或ENERIC_WRITE(指定该文件的写访问权)两个值之一或同时为为这两个值。用ENERIC_READ|GENERIC_WRITE则指定可对串口进行读写

dwShareMode:指定此文件可以怎样被共享。因为串行口不支持任何共享模式,所以dwShareMode必须设为0

lpSecurityAttributes定义安全属性,一般不用,可设为NULL。Win 9x下该参数被忽略;

dwCreationDistribution定义文件创建方式, 对串口必须设为OPEN_EXISTING,表示打开已经存在的文件;

dwFlagsAndAttributes为该文件指定定义文件属性和标志,这个程序中设为FILE_FLAG_OVERLAPPED,表示异步通信方式;

hTemplateFile 指向一个模板文件的句柄,串口无模板可言,设为NULL。在 Windows 9x下该参数必须为NULL。

用异步读写扮纤圆方式打开串口1的函数调用如下:

m_hComm = CreateFile(“COM1”,//打开串口1

GENERIC_READ | GENERIC_WRITE, //读写方式

0, //不能共享

NULL, //不用安全结构

OPEN_EXISTING, //打开已存在的设备

FILE_FLAG_OVERLAPPED,//异步方式

0) //无模板

串口被成功打开时,返回其句柄,否则返回INVALID_HANDLE_VALUE(0XFFFFFFFF)。

3、串口设置

第一次打开串口时,串口设置为系统默认值,函数GetCommState和SetCommState可用于检索和设定端口设置的DCB(设备控制块)结构,

该结构中BaudRate、ByteSize、StopBits和Parity字段含有串口波特率、数据位数、停止位和奇偶校验控制等信息。

程序中可先用GetCommState检索端口的当前设置,修改其中的部分字段后再用SetCommState进行端口设定。这样可不必构造一个完整的DCB结构。

下面介绍几个主要的函数和结构体:

(1)GetCommState

BOOL GetCommState( hCommDev, lpdcb);

参数hCommDev标识通信设备,应使用CreateFile返回的句柄。Lpdcb是指向DCB结构的指针,

函数调用后当前串口配置信息将被保存在这个结构内。如果函数成功返回值为TRUE;否则返回值为FALSE。

SetCommState用法与GetCommState相似,在此不再重复。DCB结构定义如下(只介绍主要的几项):

typedef struct _ DCB{

……

DWORD BardRate //波特率的设置

BYTE ByteSize; //数据位的个数

BYTE Parity//是否有奇偶校验位

BYTE StopBits //停止位的个数

……

}DCB;

(2)SetCommTimeouts

BOOL SetCommTimeouts( hCommDev, lpctmo );

Lpctmo指向包含新的超时参数的COMMTIMEOUTS结构。COMMTIMEOUTS结构定义如下:

typedef struct _ COMMTIMEOUTS{

DWORD ReadIntervalTimeout

DWORD ReadTotalTimeoutMultiplier

DWORD ReadTotalTimeoutconstant

DWORD WriteTotalTimeoutMultiplier

DWORD WriteTotalTimeoutconstant

}COMMTIMEOUTS, LPCOMMTIMEOUTS

ReadIntervalTimeout: 以毫秒为单位指定通信线上两个字符到达之间的最大时间。在ReadFile *** 作其间,

收到第一个字符时开始计算时间。若任意两个字符到达之间的间隔超过这个最大值,ReadFile *** 作完成,

返回缓冲数据。0值表示不用间隔限时。若该成员为MAXDWORD,且ReadTotalTimeoutconstant和

ReadTotalTimeoutMultiplier成员为零,则指出读 *** 作要立即返回已接收到的字符,即使未收到字符,

读 *** 作也要返回。

ReadTotalTimeoutMultiplier:以毫秒为单位指定一个乘数,该乘数用来计算读 *** 作的总限时时间。每个读 *** 作的总限时时间等于读 *** 作所需的字节数与该值的乘积。

ReadTotalTimeoutConstant:以毫秒为单位指定一个常数,用于计算读 *** 作的总限时时间。每个 *** 作的总限时时间等于ReadTotalTimeoutMultiplier成员乘以读 *** 作所需字节数再加上该值的和。ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant成员的值为0表示读 *** 作不使用限时时间。

WriteTotalTimeoutMultiplier和WriteTotalTimeoutconstant的意义和作用分别与ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant相似,不再重复。

(3)BuilderCommDCB

BOOL BuilderCommDCB(lpszDef,lpdcb)

这个函数按lpszDef字符串所指定的格式来配置串口的DCB。

LpszDef:指向一个以NULL结束的字符串,该字符串指定串口的控制信息。比如,“1200,N,8,1”指定波特率为1200,无奇偶校验位,有8个数据位和1个停止位。

lpdcb:指向被填充的DCB结构。

(4)SetCommMask

BOOL SetCommMask(hCommDev,fdwEvtMask)

fdwEvtMask指向一个32位的屏蔽码,如果指定为EV_RXCHAR | EV_CTS,表示程序监控串口的收、发事件。

下面以简单的例子说明串口设置的步骤:

m_CommTimeouts.ReadIntervalTimeout = 1000

m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000

m_CommTimeouts.ReadTotalTimeoutConstant = 1000

m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000

m_CommTimeouts.WriteTotalTimeoutConstant = 1000

if (SetCommTimeouts(m_hComm, &m_CommTimeouts))

// 串口超时参数设置

if (SetCommMask(m_hComm, dwCommEvents))

// 设置串口事件掩码

if (GetCommState(m_hComm, &m_dcb))

// 获取串口当前状态

if (BuildCommDCB(“1200,N,8,1”, &m_dcb))

// 建立串口设备控制块

if (SetCommState(m_hComm, &m_dcb))

// 设置串口参数

……

以上任何一个if语句的判断条件为假时都将调用GetLastError函数获取错误信息,进行错误处理。

4、读写串口数据


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12252909.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存