⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 用c的api函数写的串口通讯程序 .txt

📁 用TC的API函数写的串口通讯程序。 对串口的访问 。
💻 TXT
字号:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if (hComm!=INVALID_HANDLE_VALUE) CloseHandle(hComm);
  exit(EXIT_SUCCESS);
}
//------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char *ComNo;
  DCB dcb;
  String Temp;
  //取得要打开的通信端口
  Temp = "COM"+IntToStr(rdCOM->ItemIndex +1);
  //转换至指针类型Char
  ComNo = Temp.c_str();
  hComm = CreateFile(ComNo,GENERIC_READ | GENERIC_WRITE,
       0, NULL, OPEN_EXISTING, 0, 0);
  if (hComm == INVALID_HANDLE_VALUE) // 如果通信端口未打开
  {
    MessageBox(0, "打开通信端口错误!!","Comm Error",MB_OK);
    return;
   }
  //将dcb地址传入,以取得通信参数
  GetCommState(hComm,&dcb);                         // 得知目前通信端口的状态
  dcb.BaudRate = CBR_9600;                          // 设置波特率为9600
  dcb.ByteSize = 8;                                  // 字节为 8 bit
  dcb.Parity = NOPARITY;                            // Parity 为 None
  dcb.StopBits = ONESTOPBIT;                       // 1 个Stop bit
  //通信端口设置
  if (!SetCommState(hComm, &dcb)) {       // 设置通信端口的状态
    MessageBox (0, "通信端口设置错误!!!","Set Error",MB_OK);
    CloseHandle(hComm);
    return;
   }
}
//------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  String Temp;
  char *SendData;
  int  ln;
  unsigned long lrc,BS;
  if (hComm==0) return; //检查Handle值
  Temp = mSend->Text;//取得发送的字符串
  SendData = Temp.c_str(); //字符串转换
  //取得发送的字符串数
  BS = Temp.Length();
  //BS = StrLen(SendData);  //也可以使用此种方式取得字符串长度
  //实际的发送动作
  WriteFile(hComm,SendData,BS, &lrc,NULL); // 送出数据

}
//------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
  String Temp;
  char inbuff[1024];
  DWORD nBytesRead, dwEvent, dwError;
  COMSTAT cs;
    //取得状态
   ClearCommError(hComm,&dwError,&cs);
   // 数据是否大于我们所准备的缓冲区
   if (cs.cbInQue > sizeof(inbuff))
   {
     PurgeComm(hComm, PURGE_RXCLEAR);  // 清除通信端口数据
     return;
    }
   ReadFile(hComm, inbuff,cs.cbInQue,&nBytesRead,NULL); // 接收通信端口的数据
   //数组中的字符串结尾处补上零字符
   inbuff[cs.cbInQue]= '\0';
   // 将数据显示于Memo1 上
   mReceive->Text = inbuff;

}
//------------------------------------------------------------------

  
 
Top  
 
 回复人: YFY(天易.重新定位,重新开始学习.) ( ) 信誉:100  2005-3-21 21:50:03  得分: 0  
 
 
   
一、设置串口相关工作 

#define MAXBLOCK 2048 
#define XON 0x11 
#define XOFF 0x13 
BOOL SetCom(HANDLE &m_hCom, const char *m_sPort, int BaudRate, int Databit, CString parity, CString stopbit) 
{ 
COMMTIMEOUTS TimeOuts; ///串口输出时间 超时设置 
DCB dcb; ///与端口匹配的设备 
m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, 
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
NULL); // 以重叠方式打开串口 
if(m_hCom==INVALID_HANDLE_VALUE) 
{ 
AfxMessageBox("设置串口部分,串口打开失败"); /////重叠方式 异步通信(INVALID_HANDLE_VALUE)函数失败。 
return FALSE; 
} 
SetupComm(m_hCom,MAXBLOCK,MAXBLOCK); //设置缓冲区 
memset(&TimeOuts,0,sizeof(TimeOuts)); 
TimeOuts.ReadIntervalTimeout=MAXDWORD; // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作 
TimeOuts.ReadTotalTimeoutMultiplier=0; //读时间系数 
TimeOuts.ReadTotalTimeoutConstant=0; //读时间常量 
TimeOuts.WriteTotalTimeoutMultiplier=50; //总超时=时间系数*要求读/写的字符数+时间常量 
TimeOuts.WriteTotalTimeoutConstant=2000; //设置写超时以指定WriteComm成员函数中的 
SetCommTimeouts(m_hCom, &TimeOuts); //GetOverlappedResult函数的等待时间*/ 
if(!GetCommState(m_hCom, &dcb)) ////串口打开方式、端口、波特率 与端口匹配的设备 
{ 
AfxMessageBox("GetCommState Failed"); 
return FALSE; 
} 

dcb.fParity=TRUE; //允许奇偶校验 
dcb.fBinary=TRUE; 
if(parity=="NONE") 
dcb.Parity=NOPARITY; 
if(parity=="ODD") 
dcb.Parity=ODDPARITY; 
if(parity=="EVEN") 
dcb.Parity=EVENPARITY; 
if(stopbit=="1")//设置波特率 
dcb.StopBits=ONESTOPBIT; 
//if(stopbit=="0")//设置波特率 
// dcb.StopBits=NONESTOPBIT; 
if(stopbit=="2")//设置波特率 
dcb.StopBits=TWOSTOPBITS; 
BOOL m_bEcho=FALSE; /// 
int m_nFlowCtrl=0; 
BOOL m_bNewLine=FALSE; /// 
dcb.BaudRate=BaudRate; // 波特率 
dcb.ByteSize=Databit; // 每字节位数 
// 硬件流控制设置 
dcb.fOutxCtsFlow=m_nFlowCtrl==1; 
dcb.fRtsControl=m_nFlowCtrl==1 ?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE; 
// XON/XOFF流控制设置(软件流控制!) 
dcb.fInX=dcb.fOutX=m_nFlowCtrl==2; 
dcb.XonChar=XON; 
dcb.XoffChar=XOFF; 
dcb.XonLim=50; 
dcb.XoffLim=50; 
if(SetCommState(m_hCom, &dcb)) 
return TRUE; ////com的通讯口设置 
else 
{ 
AfxMessageBox("串口已打开,设置失败"); 
return FALSE; 
} 
} 

二、读串口操作: 

int ReadCom(HANDLE hComm, BYTE inbuff[], DWORD &nBytesRead, int ReadTime) 
{ 
DWORD lrc; ///纵向冗余校验 
DWORD endtime; /////////jiesuo 
static OVERLAPPED ol; 
int ReadNumber=0; 
int numCount=0 ; //控制读取的数目 
DWORD dwErrorMask,nToRead; 
COMSTAT comstat; 
ol.Offset=0; ///相对文件开始的字节偏移量 
ol.OffsetHigh=0; ///开始传送数据的字节偏移量的高位字,管道和通信时调用进程可忽略。 
ol.hEvent=NULL; ///标识事件,数据传送完成时设为信号状态 
ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
endtime=GetTickCount()+ReadTime;//GetTickCount()取回系统开始至此所用的时间(毫秒) 
for(int i=0;i<2000;i++) 
inbuff[i]=0; 
Sleep(ReadTime); 
ClearCommError(hComm,&dwErrorMask,&comstat); 
nToRead=min(2000,comstat.cbInQue); 
if(int(nToRead)<2) 
goto Loop; 
if(!ReadFile(hComm,inbuff,nToRead,&nBytesRead,&ol)) 
{ 
if((lrc=GetLastError())==ERROR_IO_PENDING) 
{ 
/////////////////// 
endtime=GetTickCount()+ReadTime;//GetTickCount()取回系统开始至此所用的时间(毫秒) 
while(!GetOverlappedResult(hComm,&ol,&nBytesRead,FALSE))//该函数取回重叠操作的结果 
{ 
if(GetTickCount()>endtime) 
break; 
} 
} 
} 
return 1; 
Loop: return 0; 
} 

三、写串口命令 

int WriteCom(HANDLE hComm, BYTE Outbuff[], int size, int bWrite[]) 
{ 
DWORD nBytesWrite,endtime,lrc; 
static OVERLAPPED ol; 
DWORD dwErrorMask,dwError; 
COMSTAT comstat; 
ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
ol.Offset=0; 
ol.OffsetHigh=0; 
ol.hEvent=NULL; ///标识事件,数据传送完成时,将它设为信号状态 
ClearCommError(hComm,&dwErrorMask,&comstat); 
if(!WriteFile(hComm,Outbuff,size,&nBytesWrite,&ol)) 
{ 
if((lrc=GetLastError())==ERROR_IO_PENDING) 
{ 
endtime=GetTickCount()+1000; 
while(!GetOverlappedResult(hComm,&ol,&nBytesWrite,FALSE)) 
{ 
dwError=GetLastError(); 
if(GetTickCount()>endtime) 
{ 
AfxMessageBox("写串口时间过长,目前串口发送缓冲区中的数据数目为空"); 
break; 
} 
if(dwError=ERROR_IO_INCOMPLETE) 
continue; //未完全读完时的正常返回结果 
else 
{ 
// 发生错误,尝试恢复! 
ClearCommError(hComm,&dwError,&comstat); 
break; 
} 
} 
} 
} 
FlushFileBuffers(hComm); 
PurgeComm(hComm,PURGE_TXCLEAR); 
bWrite=0; 
return 1; 
} 

四、调用方法很简单,只需要将你的串口参数进行简单的设置就可以了。比如: 

BOOL Main_OpenCom()//设置COM 
{ 
int Boundrate=9600;//波特率 
CString StopBits="1";//停止位 
int DataBits=8;//数据位 
CString Parity="ODD";//奇偶校验 
CString m_Port="COM1"; 
return SetCom(m_hCom1,m_Port,Boundrate,DataBits,Parity,StopBits); 
} 

void Main() 
{ 
int SIZE; 
DWORD BytestoRead=52*Count+6;//要11个字节 
int BWRITE[2]; 
int ReadTime=2000; 
BYTE Outbuff[12]={0xff,0x00,0xea,0xff,0xea,0xff,0,0,0,0,0,0}; 
SIZE=sizeof(Outbuff); 
WriteCom(m_hCom,Outbuff,SIZE,BWRITE); 
ReadCom(m_hCom,m_Inbuff,BytestoRead,ReadTime); 
//进行相应的解包处理 
} 


  
 
Top  
 
 回复人: YFY(天易.重新定位,重新开始学习.) ( ) 信誉:100  2005-3-21 21:51:39  得分: 0  
 
 
   
改一改CString就可以了吧。

  
 
Top  
 
 回复人: llmsn(若虚) ( ) 信誉:100  2005-3-22 12:21:25  得分: 0  
 
 
   
我邮箱:llmsn@yahoo.com.cn

  
 
Top  
 
 回复人: JQinHan(大漢千秋,長樂未央) ( ) 信誉:100  2005-3-22 18:54:53  得分: 0  
 
 
   
unsigned int GetAuxBlock(unsigned char *buffer, unsigned int buffsize, unsigned int waitsec)
  {
   unsigned int result=0;
   __ASM {
     push di
     les  di, buffer
     mov  cx, buffsize
     mov  bx, waitsec
     mov  ah, _BlkGetAux
     int   _CP_BIOS_INT
     jc   End
     mov  result, ax
     pop  di
   }
   End:
   return(result);
  }

  unsigned int PutAuxBlock(unsigned char *buffer, unsigned int buffsize)
  {
   unsigned int result=0;
   __ASM {
     push di
     les  di, buffer
     mov  cx, buffsize
     mov  ah, _BlkPutAux
     int   _CP_BIOS_INT
     pop  di
     mov  result, ax
   }
   return(result);
  }

  
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -