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);
- }