剛開始接觸WIN32串口通信。實作類似串口助手的功能時照著例程做出來的例子,讀到的資料一直顯示為零讀到的資料量一直在變化。如圖
。在其他串口助手上應該接受到的是數字5.求大神指點
uj5u.com熱心網友回復:
UINT CommThread(LPVOID pParam)//實參this傳給形參pParam,型別為LPVOID{
BOOL bResult = TRUE;
DWORD dwComEventMask, dwCommOvTrans;
DWORD dwError = 0;
DWORD length = 0;
CAPIComTestDlg* pDlg = (CAPIComTestDlg*)pParam;//將LPVOID型別強制轉換為主對話框型別
//獲得本對話框類的指標且型別與本軟體定義相同
while (1)
{//進入無限回圈,對串口事件進行監測
//dwComEventMask = 0;
//WaitCommEvent等待一個事件發生在指定的通信設備
//如果成功則回傳非零;如果失敗則回傳零
bResult = WaitCommEvent(pDlg->m_hComm, &dwComEventMask, &pDlg->m_ovCom);
if (!bResult) //WaitCommEvent無立即探得事件的入口
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
//無線等待Overlpped操作結構
GetOverlappedResult(pDlg->m_hComm, &pDlg->m_ovCom, &dwCommOvTrans, TRUE);
//第四個引數為TRUE則無線等待,直到有串口事件發生為止
if (dwComEventMask==EV_RXCHAR)
{
//發送訊息(注意軟體必須手工建立串口機制)
::PostMessage(pDlg->m_pOwner, WM_COMM_RXCHAR, EV_RXCHAR, length);
}
else
{
if (closeStatus)
{
closeStatus = FALSE;
CloseHandle(pDlg->m_hComm);
pDlg->m_hComm = NULL;
AfxEndThread(Thread_exitCode);//停止并洗掉執行緒
}
}
break;
}
case 87:
{
break;
}
default:
{
break;
}
}
}
else//由WaitCommEvent立即探得事件的入口
{
if (dwComEventMask==EV_RXCHAR)
{
::PostMessage(pDlg->m_pOwner, WM_COMM_RXCHAR, EV_RXCHAR, length);
}
}
}//回圈體尾
return 0;
}
uj5u.com熱心網友回復:
LRESULT CAPIComTestDlg::OnComm(WPARAM evenMask, LPARAM charlenth){
LONG len, k;
CString str;
CFile createFile;
createFile.Open(strCreatePath,CFile::modeReadWrite);
if (evenMask == EV_RXCHAR)
{
//串口資料讀取,函式回傳時m_readlengt為實際讀取的位元組數
ReadCommData(m_hComm, readBuff, &m_readlength);
if (m_readlength == 0)
{
return 0;
}
len = m_readlength;
//strtemp = "RX:" + strtemp;
strtemp.Format("%d", RX_count += len);//接收位元組計數器累加
strtemp = "RX:" + strtemp;
//createFile.Write(&readBuff, RX_count += len);
register BYTE bt;//為提高速度,用暫存器變數
//CString str;
for (k = 0; k < len; k++)
{
createFile.Write(readBuff, RX_count);
//將位元組型陣列轉換為CString型別
bt = *(char*)(readBuff + k);
str.Format("%d", bt);
str += bt;
}
m_ctrlReceiveData.ReplaceSel(str);//顯示接收資料
m_ctrlRXCount.SetWindowText(strtemp);//顯示接收計數的累加值
}
return 0;
}
uj5u.com熱心網友回復:
BOOL CAPIComTestDlg::ReadCommData(HANDLE hCommPort, char *readBuffer, DWORD *readlength){
DWORD dwRead;
DWORD dwErrorFlags;
BOOL fWaitingOnRead = FALSE;//TRUE表示正在讀取的資料
DWORD charlength = 0;
//獲得最新的串口接收資料位元組數(簡稱接收位元組數)
//如果接收位元組數為0,表示接受緩沖區為空,無須進行讀取操作,立即回傳(即函式執行結束)
//如果接收位元組數不為0,表示串口接識訓沖區中有資料,則呼叫ReadFile函式讀取接收資料。
//由于采用Overlapped執行方式,ReadFile函式回傳有兩種情況:一:讀完資料的回傳情況,而是未讀完資料的回傳情況
ClearCommError(m_hComm, &dwErrorFlags, &CommStat);
charlength = CommStat.cbInQue;
if (charlength == 0)
return false;
//ReadFile(hCommPort, readBuff, charlength, readlength, &m_ovread);
//return TRUE;
if (!fWaitingOnRead) //表示正在讀取資料
{
//一般情況下ReadFile函式回傳TRUE表示資料讀完資料,則結束ReadCommData函式。
//這時ReadCommData函式的回傳值為真,且接收資料已存入readBuffer陣列中。
//而實際讀取接收資料的長度來源于ReadFile函式的倒數第二個引數。
//否則表示表示未讀取完資料
//hCommPort:檔案句柄;readBuff:用于保存讀入資料的一個緩沖區
//charlength:要讀入的位元組數;readlength:指向實際讀取位元組數的指標
if (!ReadFile(hCommPort, readBuff, 1, readlength, &m_ovread))
{
if (GetLastError() != ERROR_IO_PENDING)//立即回傳
{//報告前面的操作ReadFile出錯
AfxMessageBox("讀取串口資料出錯101");
return FALSE;
}
else
{
fWaitingOnRead = TRUE;//設定正在讀取串口資料狀態標志
}
}
else
{
return TRUE;
}
}
DWORD dwResult;
if (fWaitingOnRead)
{ //無限等待重疊操作結果
//呼叫WaitForSingleObject函式等待讀串口接識訓沖區操作結束,一旦操作結束,WaitForSingleObject函式退出等待
//并回傳一個等待結果資訊碼存與dwResult變數中,如果等待結果資訊碼不為WAIT_OBJECT_0,則讀串口操作錯誤,接收ReadCommData函式
dwResult = WaitForSingleObject(m_ovread.hEvent, INFINITE);
//引數INFINITE決定無限等待
switch (dwResult)
{
//如果等待資訊碼為WAIT_OBJECT_0,則呼叫GetOverlappedResult函式進一步確認讀串口操作是否正確,
//如果GetOverlappedResult函式回傳值為TRUE,則表示讀操作正確,結束ReadCommData
//如果GetOverlappedResult函式回傳值為FALSE,則表示讀操作錯誤
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hCommPort, &m_ovread, &dwRead, FALSE))
//引數FALSE決定立即回傳
{
AfxMessageBox("讀取串口操作出錯102");
return FALSE;
}
else
{
//成功完成讀串口接識訓沖區
fWaitingOnRead = FALSE;//還原標志狀態
return TRUE;
}
break;
case WAIT_TIMEOUT:
//超時,但讀操作還未完成
AfxMessageBox("WAIT_TIMEOUT");//超時資訊提示
break;
default:
//WaitForSingObject函式的最終結果錯誤。
//即讀操作失敗,或OVERLAPPED操作處理出錯
AfxMessageBox("WaitForSingObject,Error");
break;
}
}
return TRUE;
}
uj5u.com熱心網友回復:
僅供參考://回圈向a函式每次發送200個位元組長度(這個是固定的)的buffer,
//a函式中需要將回圈傳進來的buffer,組成240位元組(也是固定的)的新buffer進行處理,
//在處理的時候每次從新buffer中取兩個位元組列印
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
#include <windows.h>
#include <process.h>
#include <io.h>
#define MYVOID void
#define vsnprintf _vsnprintf
#else
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#define CRITICAL_SECTION pthread_mutex_t
#define MYVOID void *
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef _MSC_VER
void Lock(CRITICAL_SECTION *l) {
EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
LeaveCriticalSection(l);
}
void sleep_ms(int ms) {
Sleep(ms);
}
#else
void Lock(CRITICAL_SECTION *l) {
pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
pthread_mutex_unlock(l);
}
void sleep_ms(int ms) {
usleep(ms*1000);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
struct tm *now;
struct timeb tb;
if (NULL==pszFmt||0==pszFmt[0]) return;
vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
ftime(&tb);
now=localtime(&tb.time);
sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
sprintf(timestr,"%02d:%02d:%02d",now->tm_hour ,now->tm_min ,now->tm_sec );
sprintf(mss,"%03d",tb.millitm);
printf("%s %s.%s %s",datestr,timestr,mss,logstr);
flog=fopen(logfilename1,"a");
if (NULL!=flog) {
fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
if (ftell(flog)>MAXLOGSIZE) {
fclose(flog);
if (rename(logfilename1,logfilename2)) {
remove(logfilename2);
rename(logfilename1,logfilename2);
}
} else {
fclose(flog);
}
}
}
void Log(const char *pszFmt,...) {
va_list argp;
Lock(&cs_log);
va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
Unlock(&cs_log);
}
//Log}
#define ASIZE 200
#define BSIZE 240
#define CSIZE 2
char Abuf[ASIZE];
char Cbuf[CSIZE];
CRITICAL_SECTION cs_HEX;
CRITICAL_SECTION cs_BBB;
struct FIFO_BUFFER {
int head;
int tail;
int size;
char data[BSIZE];
} BBB;
int No_Loop=0;
void HexDump(int cn,char *buf,int len) {
int i,j,k;
char binstr[80];
Lock(&cs_HEX);
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%03d %04x -",cn,i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
Log("%s\n",binstr);
}
Unlock(&cs_HEX);
}
int GetFromRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
lent=0;
Lock(cs);
if (fbuf->size>=len) {
lent=len;
if (fbuf->head+lent>BSIZE) {
len1=BSIZE-fbuf->head;
memcpy(buf ,fbuf->data+fbuf->head,len1);
len2=lent-len1;
memcpy(buf+len1,fbuf->data ,len2);
fbuf->head=len2;
} else {
memcpy(buf ,fbuf->data+fbuf->head,lent);
fbuf->head+=lent;
}
fbuf->size-=lent;
}
Unlock(cs);
return lent;
}
MYVOID thdB(void *pcn) {
char *recv_buf;
int recv_nbytes;
int cn;
int wc;
int pb;
cn=(int)pcn;
Log("%03d thdB thread begin...\n",cn);
while (1) {
sleep_ms(10);
recv_buf=(char *)Cbuf;
recv_nbytes=CSIZE;
wc=0;
while (1) {
pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);
if (pb) {
Log("%03d recv %d bytes\n",cn,pb);
HexDump(cn,recv_buf,pb);
sleep_ms(1);
} else {
sleep_ms(1000);
}
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef _MSC_VER
pthread_exit(NULL);
#endif
}
int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct FIFO_BUFFER *fbuf,char *buf,int len) {
int lent,len1,len2;
Lock(cs);
lent=len;
if (fbuf->size+lent>BSIZE) {
lent=BSIZE-fbuf->size;
}
if (fbuf->tail+lent>BSIZE) {
len1=BSIZE-fbuf->tail;
memcpy(fbuf->data+fbuf->tail,buf ,len1);
len2=lent-len1;
memcpy(fbuf->data ,buf+len1,len2);
fbuf->tail=len2;
} else {
memcpy(fbuf->data+fbuf->tail,buf ,lent);
fbuf->tail+=lent;
}
fbuf->size+=lent;
Unlock(cs);
return lent;
}
MYVOID thdA(void *pcn) {
char *send_buf;
int send_nbytes;
int cn;
int wc;
int a;
int pa;
cn=(int)pcn;
Log("%03d thdA thread begin...\n",cn);
a=0;
while (1) {
sleep_ms(100);
memset(Abuf,a,ASIZE);
a=(a+1)%256;
if (16==a) {No_Loop=1;break;}//去掉這句可以讓程式一直回圈直到按Ctrl+C或Ctrl+Break或當前目錄下存在檔案No_Loop
send_buf=(char *)Abuf;
send_nbytes=ASIZE;
Log("%03d sending %d bytes\n",cn,send_nbytes);
HexDump(cn,send_buf,send_nbytes);
wc=0;
while (1) {
pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);
Log("%03d sent %d bytes\n",cn,pa);
HexDump(cn,send_buf,pa);
send_buf+=pa;
send_nbytes-=pa;
if (send_nbytes<=0) break;//
sleep_ms(1000);
if (No_Loop) break;//
wc++;
if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);
}
if (No_Loop) break;//
}
#ifndef _MSC_VER
pthread_exit(NULL);
#endif
}
int main() {
#ifdef _MSC_VER
InitializeCriticalSection(&cs_log);
InitializeCriticalSection(&cs_HEX);
InitializeCriticalSection(&cs_BBB);
#else
pthread_t threads[2];
int threadsN;
int rc;
pthread_mutex_init(&cs_log,NULL);
pthread_mutex_init(&cs_HEX,NULL);
pthread_mutex_init(&cs_BBB,NULL);
#endif
Log("Start===========================================================\n");
BBB.head=0;
BBB.tail=0;
BBB.size=0;
#ifdef _MSC_VER
_beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);
_beginthread((void(__cdecl *)(void *))thdB,0,(void *)2);
#else
threadsN=0;
rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);
#endif
if (!access("No_Loop",0)) {
remove("No_Loop");
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
while (1) {
sleep_ms(1000);
if (No_Loop) break;//
if (!access("No_Loop",0)) {
No_Loop=1;
}
}
sleep_ms(3000);
Log("End=============================================================\n");
#ifdef _MSC_VER
DeleteCriticalSection(&cs_BBB);
DeleteCriticalSection(&cs_HEX);
DeleteCriticalSection(&cs_log);
#else
pthread_mutex_destroy(&cs_BBB);
pthread_mutex_destroy(&cs_HEX);
pthread_mutex_destroy(&cs_log);
#endif
return 0;
}
uj5u.com熱心網友回復:
不熟悉就用同步的方式操作打開串口,readfile 會阻塞直到讀超時uj5u.com熱心網友回復:
設定斷點 單步除錯,1 看ReadFile 讀到什么資料, 如果不正確, 是否是波特率/位數等引數設定有誤?
2 看轉換是否有什么問題
uj5u.com熱心網友回復:
單步除錯的時候發現ReadFile讀資料讀出來的時候都是0uj5u.com熱心網友回復:
你這段代碼,仔細檢查,你if(!readFile)讀取成功就直接return true了,后面所有的代碼怎么都不會被執行。
uj5u.com熱心網友回復:
讀資料分為幾種情況:一是:如果有資料并且讀完了,直接讀取;二是:表示資料正在讀,此時又分為讀完則回傳,沒有讀完就繼續等待uj5u.com熱心網友回復:
你好,請問當資料沒有讀完時繼續等待這塊你是怎么寫的?怎么等待,用一個陳述句嘛?麻煩指導下轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/48600.html
上一篇:bin檔案
