‘壹’ 用c语言读取串口数据
调用输入输出的函数,它的参数大概是端口地址和缓冲区(好像是哈,TC2.0里是有的,好像是input,其它版本的C也应该有类似的函数)——跟windows里面的deviceiocontrol()很类似的,
调用它就可以啦
当然你要先把串口设置好,比如波特率之类的
‘贰’ windows下C语言怎么对串口进行读写操作
windows下对串口的操作可以通过WindowsAPI进行,也可以通过Linux下的read什么的直接操作,但是这种情况需要了解电路结构,比较麻烦,第三种有第三方提供的库,但是大多数针对C++,所以可能比较难找到顺手的第三方库.
那么,接下来就见要介绍一下串口通信用WindowsAPI通信的方式.
我们会发现,在文件名的位置填上"comX" X表示com口号,超过十的com口号需要另外的书写方式,这里不说了,因为网上一抓一大把,接下来,我们要对串口进行一系列的明确设置,这里就用到了一个结构体DCB结构,是专门用来描述一个com口的工作方式的,由于次结构体有28个成员,非常多,而且大部分的设置都是全世界通用的,所以,我们偷个懒,在打开一个com口之后,建立DCB结构体,接下来调用一个函数GetCommState用这个函数把现在com口的数据都写到DCB里,这样,比较通用的com口设置就已经弄好了,我们一般情况下只需要改一下DCB的波特率就好了,改好后马上用SetCommState把刚改好的结构体再写回去,这样串口就设置好了,现在还有点麻烦,串口设置好了,我们要它干什么呢?废话,读写数据呗,嘟~~~~~~可不能用fwrite和fread因为这个com口句柄不是文件句柄,是内核句柄,要用ReadFile和WriteFile来进行读写,又出麻烦了,我们怎么知道单片机什么时候发数据过来,就算我们知道,计算机什么时候知道啊?所以,一般的情况下,用ReadFile一直在哪检查,又是麻烦,通常情况下,一个com口的ReadFile设置是阻塞函数,影响编程啊!!!!!!
怎么办,很简单,你不阻塞吗,打通你呗,我们再建立里一个结构体COMMTIMEOUTS这个结构体描述里一个com口的相关超时设置,我们用GetCommTimeouts把数据读回来,具体的设置方法在网上也有,但是要注意,有一个MAXDWORD用它来设置读间隔超时设置就可以使ReadFile向kbhit()函数一样完全非阻塞了.
经过一些列的设置,事实上,现在已经可以通信了,要是有人觉得缓存不舒服,用SetupComm函数来重设缓存大小,对于传输速度比较快的通信,要把缓存设置的大些.
‘叁’ windows下怎么用C语言读取串口里的数据
Windows下的语言读取串口的数据,可以通过USB的一些特定连接。
‘肆’ c语言 让计算机像单片机一样接收串口发来的数据
可以使用串口助手软件,或者自己编定软件,VB、VC的编程使用MSCOMM控件实现串口通信,但是如果是与下位机通信光有上位机软件是不行的,还要有与下位机连接的串口线,但是电脑串口线不能与下位机直接连接,因为计算机采用负逻辑,需要使用MAX232或者其他电平转换芯片转换电平后才能与下位机进行串口通信
‘伍’ 如何用C语言控制计算机串口
基本方法是使用CreateFile来建立一个串口文件,然后用overlap的方式进行读写
#define SERAIL_PORT_BUF_MAX (1024*8)
typedef HRESULT (*PFN_CMD_PARSE_DATA)(HANDLE hParseApp, LPCSTR szRspCmd, int nCmdLen);
class CUsbSrvApp// : public CWinApp
{
public:
CUsbSrvApp();
~CUsbSrvApp();
BOOL OnSendData(const char *szBuf, int nLen);// 发送数据
int ComConnect(CString strPort); // 连接COM口
HANDLE OpenComPort(CString strPort, int nBaudRate, int nDataBits, int nStopBits, int nParity, int nFlowCtrlType); // 打开串口
void Close(); // 关闭串口
HANDLE m_hCom;
BOOL m_bConnected;
OVERLAPPED m_OverlappedRead;
OVERLAPPED m_OverlappedWrite;
CWinThread *m_pThread;
PFN_CMD_PARSE_DATA m_pRspCmdFunc; // 用来处理接受数据的CALLBACK
HANDLE m_hParseApp;
};
CUsbSrvApp::CUsbSrvApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
m_bConnected = false;
m_hCom = NULL;
m_pRspCmdFunc = NULL;
}
CUsbSrvApp::~CUsbSrvApp()
{
}
//打开串口通信,并返回串口句柄
HANDLE CUsbSrvApp::OpenComPort(CString strPortName,
int nBaudRate,
int nDataBits,
int nStopBits,
int nParity,
int nFlowCtrlType)
{
DCB dcb;
COMMTIMEOUTS CommTimeOuts ;
COMMCONFIG ComConfig;
HANDLE hComPort;
CString strPort;
strPort.Format("\\\\.\\%s",strPortName); // COM口的文件名应该是 \\.\COMXX
//打开窗口其实就是创建一个文件
hComPort = CreateFile(strPort,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
if (INVALID_HANDLE_VALUE == hComPort)
return INVALID_HANDLE_VALUE;
// 设置一些COM口通讯参数和OVERLAP
CommTimeOuts.ReadIntervalTimeout = -1;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0x1388;
SetCommTimeouts( m_hCom, &CommTimeOuts ) ;
SetDefaultCommConfig(strPortName, &ComConfig, sizeof(COMMCONFIG));
GetCommState(m_hCom, &dcb ) ;
dcb.BaudRate = nBaudRate;
dcb.ByteSize = nDataBits;
dcb.StopBits = nStopBits;
dcb.fParity = (NOPARITY != nParity);
dcb.Parity = nParity;
//set the receive char
dcb.EvtChar = 0x0D;
switch(nFlowCtrlType)
{
case 0: //no flow control
break;
case 1://HARD_FLOW_CTRL:
dcb.fOutxCtsFlow = TRUE;
dcb.fOutxDsrFlow = TRUE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = TRUE;
dcb.fRtsControl = RTS_CONTROL_TOGGLE;
break;
case 2://SOFT_FLOW_CTRL:
dcb.fOutX = TRUE;
dcb.fInX = TRUE;
break;
}
BuildCommDCB(_T("baud=115200 parity=N data=8 stop=1"),&dcb);
SetCommState(hComPort, &dcb ) ;
SetCommMask(hComPort, 0);
SetCommMask(hComPort, EV_RXCHAR|EV_CTS|EV_DSR|EV_RLSD|EV_RING);
SetupComm( hComPort, SERAIL_PORT_BUF_MAX,SERAIL_PORT_BUF_MAX) ;
//clear read and write buffer
PurgeComm( hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
return hComPort;
}
void CUsbSrvApp::Close()
{
if(m_bConnected)
{
m_bConnected = false;
CloseHandle(m_hCom);
m_hCom = NULL;
}
}
// 这个线程是监视串口数据,一旦有数据则读取并调用CALLBACK通知客户端
UINT ReceiveComData(LPVOID pParam)
{
CUsbSrvApp *pUsbSrv = (CUsbSrvApp *)pParam;
HANDLE hComPort = pUsbSrv->m_hCom;
DWORD dwEvtMask=0;
DWORD dwErrorFlags;
SetCommMask( hComPort, EV_RXCHAR);
OVERLAPPED osRead;
osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
DWORD dwTransfer = 0;
while(pUsbSrv->m_bConnected)
{
if( !WaitCommEvent( hComPort, &dwEvtMask,&osRead))
{
if( GetLastError()== ERROR_IO_PENDING)
{
WaitForSingleObject(osRead.hEvent, INFINITE);
if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)
{
COMSTAT ComStat={0} ;
DWORD dwReadLen = 0;
DWORD dwBytesRead = 0;
DWORD dwTotalLen = 0;
ClearCommError(hComPort, &dwErrorFlags, &ComStat );
dwTotalLen = ComStat.cbInQue;
dwReadLen = (SERAIL_PORT_BUF_MAX > dwTotalLen)?dwTotalLen:SERAIL_PORT_BUF_MAX;
BYTE *pBuf = new BYTE[dwTotalLen+1];
memset(pBuf, 0 , dwTotalLen+1);
DWORD nReadBufLen=0;
while(dwTotalLen>0)
{
if(FALSE == ReadFile( hComPort, pBuf+nReadBufLen,dwReadLen, &dwBytesRead,&pUsbSrv->m_OverlappedRead))
{
if(GetLastError() == ERROR_IO_PENDING)
{
GetOverlappedResult(hComPort,&osRead, &dwTransfer, TRUE );
}
break;
}
nReadBufLen +=dwBytesRead;
dwTotalLen -=dwBytesRead;
dwReadLen -= dwBytesRead;
dwReadLen = (SERAIL_PORT_BUF_MAX>dwReadLen)?dwReadLen:SERAIL_PORT_BUF_MAX;
}
if(pUsbSrv->m_pRspCmdFunc!=NULL&&nReadBufLen!=0)
{
pUsbSrv->m_pRspCmdFunc(pUsbSrv->m_hParseApp, (char*)pBuf,nReadBufLen);
}
delete pBuf;
ClearCommError(hComPort, &dwErrorFlags, &ComStat );
int len =0;//= m_retList.GetSize();
}//endif if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)
}//endif if( GetLastError()== ERROR_IO_PENDING)
}//endif if( !WaitCommEvent( hComPort, &dwEvtMask,&o))
else
{
if(GetLastError() == ERROR_IO_PENDING) {
GetOverlappedResult(hComPort, &osRead, &dwTransfer, TRUE ); // sleep thread
}
}
Sleep(1);
} //endwhile while(m_bConnected)
return 0;
}
int CUsbSrvApp::ComConnect(CString strPort)
{
int nBaudRate = 115200;
int nDataBits = 8;
int nStopBits = 1;
int nParity = 0;
int nFlowCtrl = 1;
if (NULL != m_hCom || m_bConnected)
{
return 0;
}
m_hCom = OpenComPort(strPort,nBaudRate,nDataBits,nStopBits,nParity,nFlowCtrl);
if( INVALID_HANDLE_VALUE == m_hCom)
{
m_hCom = NULL;
return 0;
}
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_pThread = AfxBeginThread( ReceiveComData,(void*)this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED ,NULL );
if( NULL == m_pThread )
{
CloseHandle( m_hCom );
m_hCom = NULL;
return FALSE;
}
else
{
m_bConnected = TRUE;
m_pThread->ResumeThread( );
}
return TRUE;
}
int CUsbSrvApp::OnSendData(const char *szBuf, int nLen)
{
BOOL bWriteStat;
BOOL bWrite = TRUE;
DWORD dwBytesWrite = 0;
DWORD dwBytesWritten = 0;
int dwByteswrittenTotal = 0;
if (NULL == m_hCom)
return 0;
int nSentTimes=0;
while(dwByteswrittenTotal<nLen&&nSentTimes<10)
{
nSentTimes++;
dwBytesWrite = nLen-dwByteswrittenTotal;
bWriteStat = WriteFile( m_hCom, szBuf+dwByteswrittenTotal, dwBytesWrite, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat)
{
if ( GetLastError() == ERROR_IO_PENDING )
{
dwBytesWritten = 0;
bWrite = FALSE;
}
}
if (!bWrite)
{
bWrite = TRUE;
bWriteStat = GetOverlappedResult(m_hCom, // Handle to COMM port
&m_OverlappedWrite, // Overlapped structure
&dwBytesWritten, // Stores number of bytes sent
TRUE); // Wait flag
//deal with the error code
}
dwByteswrittenTotal += dwBytesWritten;
}
if(dwByteswrittenTotal<nLen)
return 0;
else
return 1;
}
‘陆’ c语言怎么实现串口通信
编程原理
程序1为查询通信方式接口程序,为一典型的数据采集例程。其中bioscom()函数初始化COM1(此函数实际调用BIOS
INT
14H中断0号功能)。这样在程序中就避免了具体设置波特率因子等繁琐工作,只需直接访问发送/接收寄存器(3F8H)和线路状态寄存
‘柒’ C语言变成实现串口收发数据
#include <reg51.h>
#include <intrins.h>
unsigned char key_s, key_v, tmp;
char code str[] = "welcome!www.willar.com
";
void send_str();
bit scan_key();
void proc_key();
void delayms(unsigned char ms);
void send_char(unsigned char txd);
sbit K1 = P1^4;
main()
{
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xFD; // 波特率9600
TL1 = 0xFD;
SCON = 0x50; // 设定串行口工作方式
PCON &= 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
IE = 0x0; // 禁止任何中断
while(1)
{
if(scan_key()) // 扫描按键
{
delayms(10); // 延时去抖动
if(scan_key()) // 再次扫描
{
key_v = key_s; // 保存键值
proc_key(); // 键处理
}
}
if(RI) // 是否有数据到来
{
RI = 0;
tmp = SBUF; // 暂存接收到的数据
P0 = tmp; // 数据传送到P0口
send_char(tmp); // 回传接收到的数据
}
}
}
bit scan_key()
// 扫描按键
{
key_s = 0x00;
key_s |= K1;
return(key_s ^ key_v);
}
void proc_key()
// 键处理
{
if((key_v & 0x01) == 0)
{ // K1按下
send_str(); // 传送字串"welcome!...
}
}
void send_char(unsigned char txd)
// 传送一个字符
{
SBUF = txd;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
void send_str()
// 传送字串
{
unsigned char i = 0;
while(str[i] != '