首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

求教,怎么设置串口通信中的定时发送

2013-03-01 
求教,怎样设置串口通信中的定时发送做一个wince设备与单片机串口通信程序,写了两个线程SendThread 和ReadT

求教,怎样设置串口通信中的定时发送
做一个wince设备与单片机串口通信程序,写了两个线程SendThread 和ReadThread,单击发送按钮发送线程发送一组命令数据到单片机,单片机再返回一组数据,读线程把数据显示在编辑框里。求解怎么才能设置单击一次按钮,实现比如1分钟内发送600次数据,接收600次呢。


LONG OnSendComm(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{
return TRUE;
}
  BYTE ConvertHexChar(BYTE ch)
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
return ch-'A'+10;
else if((ch>='a')&&(ch<='f'))
return ch-'a'+10;
else
return -1;}


DWORD WINAPI SendThread (PVOID pArg) {
HWND  hwndSText;
DWORD cBytes;
WCHAR szText[TEXTSIZE];
WCHAR szText1[TEXTSIZE];
WCHAR szText2[TEXTSIZE];
WCHAR szTextt[TEXTSIZE];
WCHAR szTexto[TEXTSIZE];
char szAnsi[TEXTSIZE];
size_t siz;
BYTE tmpByte=0x00;
int strLen=sizeof(szAnsi)-1;
BYTE cmd[TEXTSIZE];
byte cmd1,cmd2;

memset(cmd,'\0',sizeof(cmd));

hwndSText = GetDlgItem (hwnd, ID_SENDTEXT);
for(int i=0;i<599;i++){    //发送600次 每次间隔100ms
Sleep(100);
if(WaitForSingleObject(g_hSendEvent,-1)==WAIT_OBJECT_0)
{



// 获得发送内容并转换成asci码
GetWindowText (hwndSText, szText, dim(szText));
swscanf(szText,L"%[^ ]",szText1);
swscanf(szText,L"%*s%s",szText2);
                        byte cmd1=wcstol(szText1,NULL,16);
                        limit=wcstol(szText2,NULL,10);
                        byte cmd2=0x68+0xA1+0x04+cmd1;
                        wsprintf(szTexto,L"%02X",cmd2);
                        wsprintf(szTextt,L"68 a1 04 %s %s",szText1,szTexto);
wcstombs_s (&siz, szAnsi, sizeof (szAnsi), szTextt, _TRUNCATE);
for(int i=0,j=0;i<64,j<strLen;i++,j++)
{
if(szAnsi[j]==' ')
++j;
tmpByte=szAnsi[j];
cmd[i]=ConvertHexChar(tmpByte)<<4;
if(szAnsi[++j]==' ')
++j;
tmpByte=szAnsi[j];
cmd[i]=cmd[i]+(ConvertHexChar(tmpByte)&0xF);
}

// 写入到串口
                             rc = WriteFile(hComPort,cmd,5,&cBytes,0);
if (!rc) {
// 如果写入失败,提示错误信息
wsprintf (szText, TEXT ("Send failed rc=%d\r\n"), 
GetLastError());
DWORD dwErr = 0;
COMSTAT Stat;

if (ClearCommError (hComPort, &dwErr, &Stat)) {
MessageBox(NULL,szText,TEXT("message"),0);
}
}
} else break;

}
SetEvent (g_hSendEvent);
return 0;
}

DWORD WINAPI ReadThread (PVOID pArg) {
HWND hWnd;
DWORD cBytes, i;
int rc;


WCHAR szText[TEXTSIZE];
char szAnsi[TEXTSIZE];
size_t siz;
BYTE cmd[TEXTSIZE];
int wData1,wData2;
float wData3,wData4;
char Data3[TEXTSIZE];
char Data4[TEXTSIZE];
HWND hlist=GetDlgItem(hwnd,IDC_LIST1);
for(int i=0;i<599;i++){
Sleep(100);
if(WaitForSingleObject(g_hSendEvent,-1)==WAIT_OBJECT_0)
{


for(i=0;i<9;i++){
while (!ReadFile (hComPort, &cmd[i], 1, &cBytes, 0))
if (hComPort == INVALID_HANDLE_VALUE)
return 0;
while((cmd[0]==0x68)&(cmd[1]==0xA2)&(cmd[2]==0x05))
if(cmd[8]!=cmd[0]+cmd[1]+cmd[2]+cmd[3]+cmd[4]+cmd[5]+cmd[6]+cmd[7]){
break;
}
int wData1=MAKEWORD(cmd[5],cmd[4]);
int wData2=MAKEWORD(cmd[7],cmd[6]);
sprintf(Data3,"%d",wData1);
float wData3=atoi(Data3);
 wData3=wData3/16;
sprintf(Data4,"%d",wData2);
float wData4=atoi(Data4);
wData4=((wData4-5000)*limit)/20;

if((limit>0)&(limit<10)){
sprintf(szAnsi,"%.1f %.fMM",wData3,wData4);}
if((limit>9)&(limit<91)){
sprintf(szAnsi,"%.1f %.1fCM",wData3,wData4);}

if (szAnsi[i] == '\n')
{
szAnsi[i+1] == '\0';
break;
}}


mbstowcs_s (&siz, szText, dim (szText), szAnsi, _TRUNCATE);

/*SetWindowText(hwnd,szText);*/
ListBox_AddString(hlist,szText);
/*ListBox_InsertString(hlist,0,szText);*/

}}
SetEvent (g_hSendEvent);


return 0;
}




只是我还是只能按一次按钮得到一个数据,不是设想的600个数据,想了两天了,无解,求助。
[解决办法]
这代码毛病太多了。没法改。

1. g_hSendEvent可能导致接受线程总是无法执行。如果确实需要多线程,
   老实按照教材上教你的生产制消费者模型设置互斥和同步

2. Sleep(100)无法精确保证延时,因为没有考虑发送和接受所花费的时间
3. 下面代码直接终止循环,可能导致发送线程无限等待:


    if(cmd[8]!=cmd[0]+cmd[1]+cmd[2]+cmd[3]+cmd[4]+cmd[5]+cmd[6]+cmd[7]){
        break;
    }


[解决办法]
相当于15毫秒发送一次,因此不要在定时器里做,免得象死机一样,在线机一样,在线程里用多媒体定时器进行查询发送,就是不断读取多媒体定时的值,当单差大于等于15毫秒就发送一次,直到达到600次就中止发送

热点排行