S 串口编程 详解4 串口发送数据
串口发送数据包括:
十六进制发送数据
手动发送数据
自动发送数据
手动发送数据的代码如下:
//手动发送
long TX_count=0;
void CSCOMMDlg::OnButtonManualsend()
{
if(m_Port.m_hComm==NULL)//发送数据时要检查串口是否被打开
{
m_ctrlAutoSend.SetCheck(0);
AfxMessageBox("串口没有打开,请打开串口");
return ;
}
else
{
UpdateData(TRUE);
if(m_ctrlHexSend.GetCheck())//发送十六进制数
{
char data[512];
int len=Str2Hex(m_strSendData,data);//将一个字符串转换为十六进制数 发送
m_Port.WriteToPort(data,len);
//for(int i=0;i<len;i++) 测试用
// OnCommunication(data[i],1);
TX_count+=(long)((m_strSendData.GetLength()+1)/3);//?????????????
}
else//发送ASCII文本
{
m_Port.WriteToPort((LPCTSTR)m_strSendData);//发送数据
char data[512];
strcpy(data,m_strSendData);
int len=m_strSendData.GetLength();
for(int i=0;i<len;i++)
OnCommunication(data[i],1);
TX_count+=m_strSendData.GetLength();
}
CString strTemp;
strTemp.Format("TX: %d",TX_count);
m_ctrlTXCount.SetWindowText(strTemp);//显示计数
// WPARAM ch='a'; //测试用
// OnCommunication(ch,1);
}
CFile m_rFile;
//LPCSTR是Win32和VC++所使用的一种字符串数据类型。LPCSTR被定义成是一个指向以NULL(‘\0’)结尾的常量字符的指针。
LPCSTR lpszPath=m_StrCurPath;// "C:\\comdata"
SetCurrentDirectory(lpszPath);
}
代码分析:
发送数据是很简单的,只用了 m_Port.WriteToPort(data,len);就够啦。
这里也涉及到是否是十六进制发送数据,如果是 则先把十六进制转换为字符再进行发送,转换得调用Str2Hex( )函数。 其实这个函数名为HexToStr( )更合适
//将一个字符串作为十六进制串转化为一个字节数组,字节间可用空格分隔
//返回转换后的字节数组长度,同时字节数组长度自动设置
//将 一串十六进制数转换为字符串(原理:两个十六进制数转化为一个字符 )
int CSCOMMDlg::Str2Hex(CString str, char *data)
{
int t,t1;
int rlen=0,len=str.GetLength();
for (int i=0;i<len;)
{
char l,h=str[i];//高位
if(h==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
l=str[i];//低位
t=HexChar(h);
t1=HexChar(l);
if((t==16)||(t1==16))
break;
else
t=t*16+t1; //把两位的十六进制数转换为一个字符
i++;
data[rlen]=(char)t;
rlen++;
}
return rlen;
}
char CSCOMMDlg::HexChar(char c)
{
if((c>='0')&&(c<='9'))
return c-0x30;
else if((c>='A')&&(c<='F'))
return c-'A'+10;
else if((c>'a')&&(c<'f'))
return c-'a'+10;
else
return 0x10;
}
如果选择了自动发送,则应该使用定时器来实现自动周期性地发送的功能,代码如下
选择自动发送按钮的代码,为IDC_CHECK_AUTOSEND添加处理函数如下
void CSCOMMDlg::OnCheckAutosend()
{
m_bAutoSend=!m_bAutoSend;
if(m_bAutoSend)
{
if(m_Port.m_hComm==NULL)
{
m_bAutoSend=!m_bAutoSend;
m_ctrlAutoSend.SetCheck(0);
AfxMessageBox("串口没打开,请打开串口");
return ;
}
else
SetTimer(1,m_nCycleTime,NULL);
}
else
{
KillTimer(1);//杀掉定时器1
}
}
定时器代码
void CSCOMMDlg::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1: //定时器ID==1为自动发送时间
OnButtonManualsend(); //周期到后自动发送
break;
default:
break;
}
CDialog::OnTimer(nIDEvent);
}
当然也要考虑,当发送输入的编辑框中的内容改变时,应及时将串口发送的内容改变,因此应为编辑框IDC_EDIT_SEND添加EN_CHANCE相应函数。这个我是想不全的。
void CSCOMMDlg::OnChangeEditSend()
{
UpdateData(TRUE);
}
与此同时,如果发送周期改变时,应该重新用设置定时时间
void CSCOMMDlg::OnChangeEditCycletime()
{
CEdit* pEdit=(CEdit*)GetDlgItem(IDC_EDIT_CYCLETIME);
CString strText;
pEdit->GetWindowText(strText);
m_nCycleTime=atoi(strText);
}
以上的代码理解和使用应该都不是些什么问题
2444





