文章目录

  • 一、写串口函数
    • 1.源函数
    • 2.API 函数详解
      • (1)ClearCommError()函数——读取串行端口现在的状态
      • (2)PurgeComm()函数——清空缓冲区
      • (3)WriteFile()函数——写入串行端口数据
      • (4)GetOverlappedResult()函数——返回重叠操作结果
  • 二、编辑框发送
    • 1.源函数
  • 三.固定发送
    • 1.源函数
  • 四.重复发送
    • 1.源函数
    • 2.API函数详解
      • (1)atoi()函数 —— 把字符串转换成整型数
      • (2)SetTimer()函数——创建定时器
      • (3)KillTimer()函数——结束定时器
  • 五.补充——字符、字符串转换为16进制数据函数
  • 总结

一、写串口函数

1.源函数

.h文件

自定义函数
public:int WriteBlock(char* abOut, int MaxLength);          //写串口

.cpp文件

//写串口
int C***Dlg::WriteBlock(char *abOut, int MaxLength)
{BOOL JudgeWrite;//写入串行端口数据操作的返回值COMSTAT ComStat;//通信状态缓冲区的指针DWORD dwErrorFlags, dwLength, lentest;//接收错误代码变量的指针,要写的字节数,被写入的字节数的变量地址m_osWrite.Offset = 0;ClearCommError(m_hCom, &dwErrorFlags, &ComStat);//清除串行端口错误或读取串行端口现在的状态==>//串口句柄,接收错误代码变量的指针,通信状态缓冲区的指针if(dwErrorFlags > 0) //如果接收到错误代码{AfxMessageBox("写串口错!请检查参数设置。");PurgeComm(m_hCom, PURGE_TXABORT|PURGE_TXCLEAR); //清空缓冲区==>return 0;}dwLength = MaxLength;//要写的字节数lentest = 0;//实际字节数的指针置0JudgeWrite = WriteFile(m_hCom, abOut, dwLength, &lentest, &m_osWrite); //写入串行端口数据==>//句柄,预发送的数据,写入的字节数,被写入的字节数的变量地址,OVERLAPPED结构体指针(不使用异步传输设为null)if(!JudgeWrite)//写失败{if(GetLastError() == ERROR_IO_PENDING) //重叠 I/O 操作在进行中。{GetOverlappedResult(m_hCom, &m_osWrite, &lentest, TRUE);//返回重叠操作结果==>//句柄;重叠结构的指针;实际字节数的指针;TRUE,那么只有当操作完成才会返回}elselentest = 0;//实际字节数的指针置0}return lentest;//返回字节数的指针
}

2.API 函数详解

(1)ClearCommError()函数——读取串行端口现在的状态

  清除串行端口错误或读取串行端口现在的状态时,可用函数ClearCommError。Windows系统利用此函数清除硬件的通讯错误以及获取通讯设备的当前状态

ClearCommError()函数原型:

BOOL ClearCommError(HANDLE hFile,   //通信设备的句柄LPDWORD lpErrors,//接收错误代码变量的指针LPCOMSTAT lpStat  //通信状态缓冲区的指针
);

learCommError()函数参数说明:

hFile: 串行端冂的Handle值,此值即为使用CreateFile函数后所返回的值。

lpError: 返回错误数值,错误常数如下:
  CE_BREAK:检测到中断信号。
  CE_DNS:Windows95专用,未被选择的并行端口。
  CE_FRAME:硬件检到框架错误
  CE_IOE:通信设备发生输入/输出綹误,
  CE_MODE:设置模式错误,或是hFile值错误。
  CE_OOP:Wmdows95专用,并行端口发生缺纸错误。
  CE_OVERRUN:缓冲区容量不足,数据将遗失。
  CE_PTO:Windows95专用,并行端口发生超时错误。
  CE_RXOVER:接收区满溢或在文件结尾被接收到后仍有数据发送过来。
  CE_RXPARITY:硬件检测到校验位检查错误。
  CE_TXFULL:发送缓存区已满后,应用程序仍要发送数据。

lpStat: 指向通信端口状态的结构变量。此结构的原始声明如下:

typedef struct _COMSTAT {  //cstDWORD fCtsHold : 1;  //Tx正在等待CTS信号  DWORD fDsrHold : 1;  //Tx正在等待DSR信号DWORD fRlsdHold : 1; //Tx正在等待RLSD信号DWORD fXoffHold : 1;  //Tx由于接收XOFF字符而在等待DWORD fXoffSent : 1;   //Tx由于发送XOFF字符而在等待DWORD fEof : 1;      //发送EOF字符DWORD fTxim : 1;     //字符在等待TxDWORD fReserved : 25;   //保留DWORD cbInQue;    //输入缓冲区中的字节数DWORD cbOutQue;     //输出缓冲区中的字节数
}COMSTAT, *LPCOMSTAT;

此结构屮有关参数说明如下:
  fCtsHold:是否正在等待CTS信号。占一个位的位置。
  fDsrHold:是否正在等待DSR信号。占一个位的位置。
  fRlsdHoId:是否正在等待RLSD信号。占一个位的位置。
  fXoftHoId:是否因收到xoff字符而在等待。占一个位的位置。
  fXoffHold:是否因送出xoff字符而使得发送的动作在等待。占一个位置
  cbInQue:在输入缓冲区尚未被ReadFile函数读取的数据字节数。这个参数经常被用来进行状态检查。
  cbOutQue:在发送缓冲区而尚未被发送的据字节数。

(2)PurgeComm()函数——清空缓冲区

PurgeComm()函数原型:

BOOL PurgeComm( HANDLE hFile, DWORD dwFlags )

PurgeComm()函数函数参数说明:

hFile: 串口句柄
dwFlags: 需要完成的操作

参数dwFlags指定要完成的操作,可以是下列值的组合:

PURGE_TXABORT:终止所有正在进行的字符输出操作,完成一个正处于等待状态的重叠i/o操作,他将产生一个事件,指明完成了写操作

PURGE_RXABORT:终止所有正在进行的字符输入操作,完成一个正在进行中的重叠I/O操作,并带有已设置得适当事件

PURGE_TXCLEAR:这个命令指导设备驱动程序 清除输出缓冲区,经常与PURGE_TXABORT命令标志一起使用

PURGE_RXCLEAR:这个命令用于设备驱动程序 清除输入缓冲区,经常与PURGE_RXABORT命令标志一起使用

(3)WriteFile()函数——写入串行端口数据

  WriteFile函数,可以将数据写入一个文件或者I/O设备。该函数比fwrite函数要灵活的多,也可将这个函数应用于对通信设备、管道、套接字以及邮槽的处理。

  windows将串行端口当成文件来使用,因此写入串行端口数据的函数也是WriteFile。

WriteFile()函数原型:

BOOL WriteFile(HANDLE  hFile,                    //文件句柄LPCVOID lpBuffer,             //数据缓存区指针DWORD   nNumberOfBytesToWrite, //要写的字节数LPDWORD lpNumberOfBytesWritten, //用于保存实际写入字节数的存储区域的指针LPOVERLAPPED lpOverlapped      //OVERLAPPED结构体指针
);

WriteFile()函数参数说明:

hFile: 串行端口的Handle值,句柄
lpBuffer: 指向欲发送的数据
nNumberOfBytesToWrite: 写入的字节数
lpNumberOfBytesWritten: 指向被写入的字节数的变量地址
lpOverlapped: 指向overlapped I/O的结构地址,通常用来作背景工作时同步检查用,在串行通信中若不使用异步传输,则可不使用,设成NULL即可。

(4)GetOverlappedResult()函数——返回重叠操作结果

GetOverlappedResult()函数原型:

BOOL GetOverlappedResult (HANDLE hFile,  //文件、管道或通信设备的句柄LPOVERLAPPED lpOverlapped, //指向重叠结构的指针LPDWORD lpNumberOfBytesTransferred, //指向实际字节数的指针BOOL bWait     //等待标志
);

GetOverlappedResult()函数参数说明:

hFile: 串行端口的Handle值,句柄

lpOverlapped: LPOVERLAPPED 结构体的指针,用于说明重叠操作是否开始,该参数和readfile函数或writefile函数中的LPOVERLAPPED 结构体的even参数相匹配;

lpNumberOfBytesTransferred: 一个指向字节数的指针,该字节数是读操作或写操作的实际传输字节数。

bWait: 当LPOVERLAPPED 结构体的内部参数为STATUS_PENDING,且该参数为TRUE,那么只有当操作完成才会返回。当该参数为FALSE,且操作正在等待,则返回FALSE,用GetLastError 函数会返回ERROR_IO_INCOMPLETE。

二、编辑框发送

1.源函数

.h文件

绑定按钮与复选框变量
public:afx_msg void OnBnClickedButtonSent();                    //发送编辑框数据CButton        m_cHexSend;                 //复选框:十六进制发送

.cpp文件

//按钮事件
void C***Dlg::OnBnClickedButtonSent()
{char abOut[MAXBLOCK];int OutNum, length;if (!m_bConnected){AfxMessageBox(_T("串口未打开!"));return;}memset(abOut, 0, MAXBLOCK);//读文本框内容CString str;GetDlgItem(IDC_EDIT_TXDATA)->GetWindowText(str);char SendOut[MAXBLOCK];int len = str.GetLength();for (int i = 0; i < len; i++)abOut[i] = str.GetAt(i);if (m_cHexSend.GetCheck()) //十六进制发送复选框选中时{CString StrHexData;abOut[len] = NULL;StrHexData = CString(abOut);len = String2Hex(StrHexData, SendOut);length = WriteBlock(SendOut, len);}else   //按字符发送length = WriteBlock(abOut, len);m_txlen += length;DisplayStatus();return;
}

三.固定发送

1.源函数

.h文件

public:afx_msg void OnBnClickedButtonDefaultsend();          //发送默认数据

.cpp文件

void C***Dlg::OnBnClickedButtonDefaultsend()// TODO: 在此添加控件通知处理程序代码vector<CString> str_vec;str_vec.push_back("EB");  //帧头str_vec.push_back("90");str_vec.push_back("00");    //长度str_vec.push_back("02");str_vec.push_back("11");    //数据str_vec.push_back("01");str_vec.push_back("00");    //校验码str_vec.push_back("12");str_vec.push_back("09");   //帧尾str_vec.push_back("D7");//写串口for (int i = 0; i < str_vec.size(); i++){char abOut[MAXBLOCK];int length;if (!m_bConnected){AfxMessageBox("串口未打开!");return;}memset(abOut, 0, MAXBLOCK);CString str;str = str_vec[i];char SendOut[MAXBLOCK];int len = str.GetLength();for (int j = 0; j < len; j++)abOut[j] = str.GetAt(j);//十六进制发送CString StrHexData;abOut[len] = NULL;StrHexData = CString(abOut);len = String2Hex(StrHexData, SendOut);length = WriteBlock(SendOut, len);m_txlen += length;DisplayStatus();} return;
}

四.重复发送

1.源函数

.h文件

public://复选框函数afx_msg void OnCheckAutoEncoder();         //自动加密afx_msg void OnTimer(UINT nIDEvent);      //自动发送时间间隔

.cpp文件

//定时器
void C***Dlg::OnCheckAutoEncoder()
{CString str;GetDlgItem(IDC_EDIT_CYCLE)->GetWindowText(str);if(m_Btn_Loop.GetCheck())SetTimer(1, atoi(str.GetBuffer(str.GetLength())), NULL);elseKillTimer(1);
}
//自动发送时间间隔
void C***Dlg::OnTimer(UINT nIDEvent)
{if(nIDEvent == 1)==重复事件==CDialog::OnTimer(nIDEvent);
}
}

⚠️ 注意:
  最重要的,建立定时器消息映射。没有以下语句,则即便定时器被成功创建,也不会执行OnTimer函数

BEGIN_MESSAGE_MAP(CTestTimerDlg, CDialog)...ON_WM_TIMER()
END_MESSAGE_MAP()

  当然也可以自动覆写OnTimer函数,方法是,在类视图中,对CTestTimer类右键,属性,在属性页中,点击消息,找到WM_TIMER,点击添加OnTimer

  之后系统会自动生成OnTimer函数,并且建立消息映射,我们只需要在OnTimer函数中写入相关代码就可以了

2.API函数详解

(1)atoi()函数 —— 把字符串转换成整型数

atoi()函数原型:

int atoi(const char* str)

  参数str是要转换的字符串,返回值是转换后的整数。

(2)SetTimer()函数——创建定时器

SetTimer()函数原型:

UINT_PTR SetTimer(HWND           hWnd,       // 窗口句柄。在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了UINT_PTR       nIDEvent,   // 定时器ID,多个定时器时,可以通过该ID判断是哪个定时器UINT           uElapse,    // 时间间隔,单位为毫秒TIMERPROC  lpTimerFunc // 回调函数
);

SetTimer()函数返回值:

  类型: UINT_PTR
  如果函数成功,hWnd参数为0,则返回新建立的时钟编号,可以把这个时钟编号传递给KillTimer来销毁时钟.
  如果函数成功,hWnd参数为非0,则返回一个非零的整数,可以把这个非零的整数传递给KillTimer来销毁时钟.
  如果函数失败,返回值是零.若想获得更多的错误信息,调用GetLastError函数.

SetTimer()函数示例

SetTimer(1,1000,NULL);

参数含义
  1:   计时器的名称;
  1000: 时间间隔,单位是毫秒;
  NULL: 使用OnTimer函数。当不需要计时器的时候调用KillTimer(nIDEvent);

(3)KillTimer()函数——结束定时器

KillTimer()函数原型:

BOOL KillTimer(UINT_PTR nIDEvent); //nIDEvent —— 传递给 SetTimer的计时器事件的值。

SetTimer()函数返回值:
  如果事件已终止,则值为非零值。
  如果 KillTimer 成员函数找不到指定的计时器事件,则为0。

五.补充——字符、字符串转换为16进制数据函数

.h文件

public://自定义函数char Char2Hex(char ch);                                    //字符转换为16进制数据int String2Hex(CString str, char* SendOut);                //字符串转换为16进制数据

.cpp文件

//字符转换为16进制数据
char CSprDlg::Char2Hex(char ch)
{if ((ch >= '0') && (ch <= '9'))return ch - 0x30;if ((ch >= 'A') && (ch <= 'F'))return ch - 'A' + 10;if ((ch >= 'a') && (ch <= 'f'))return ch - 'a' + 10;elsereturn(-1);
}//字符串转换为16进制数据
int CSprDlg::String2Hex(CString str, char* SendOut)
{int hexdata, lowhexdata;int hexdatalen = 0;int len = str.GetLength();for (int i = 0; i < len;){char lstr, hstr = str[i];if (hstr == ' ' || hstr == '\r' || hstr == '\n'){i++;continue;}i++;if (i >= len)break;lstr = str[i];hexdata = Char2Hex(hstr);lowhexdata = Char2Hex(lstr);if ((hexdata == 16) || (lowhexdata == 16))break;elsehexdata = hexdata * 16 + lowhexdata;i++;SendOut[hexdatalen] = (char)hexdata;hexdatalen++;}return hexdatalen;}

总结

以上就是今天要讲的内容。

c++学习 | MFC —— 串口通信(四)发送数据相关推荐

  1. 4、Proteus仿真STM32串口通信,发送数据控制LED流水灯的启动和停止

    一.实验说明 本次实验建立在第三个实验基础上,稍加修改,通过串口调试助手发送数据到Proteus来实现对流水灯的启动和停止,所以实验采用2个通信串口,实验原理非常简单,只要熟悉第三次实验的过程,就非常 ...

  2. MFC串口通信(二)——使用MSComm控件实现串口通信

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/kangshuaibing/articl ...

  3. vivado学习第二 串口通信之奇偶校验位

    vivado学习第二 串口通信之奇偶校验位 奇偶校验位  奇偶校验位分为奇数校验位和偶数校验位,奇数和偶数的判断标准是依据发送一串或者一帧数据中"1"的个数.  奇数校验:发送的数 ...

  4. C#解决串口通信中接收数据时延迟处理与缓存处理的方法

    转载连接: http://blog.csdn.net/yaoliang11/article/details/6885768 C#解决串口通信中接收数据时延迟处理与缓存处理的方法 时间:2011-1-2 ...

  5. STC89C52串口向电脑发送数据

    先说一下,我写的原因:跟b站up主(江科大自化协)学51单片机,在 8-2节"串口向电脑发送数据"时遇到问题,串口助手一直发送"00",csdn上没有找到答案. ...

  6. 单片机: 串口向电脑发送数据

    题目概述: 串口向电脑发送数据. 编程: #include<REG52.h> unsigned char Sec; void UART_Init() { PCON &= 0x7F; ...

  7. MFC串口通信设置及发送、中断接收程序

    前一段做了个串口通信小软件,就是现实利用上位机软件通过串口通信对下位机(单片机)通信,校时LED点阵万年历,省去按键调节的麻烦,方便校时,省时省力. 为右击 串口通信控件,添加关联控件变量CMSCom ...

  8. 蓝桥杯模块学习10——串口通信(深夜学习——单片机)

    一.什么是串口通信? 51单片机--串口通信详解(STC89C51为例)_佛科院深夜学习的博客-CSDN博客 二.IAP15F2K60S2与STC89系列的区别: 1.16位自动重装载模式下波特率的计 ...

  9. 51单片机串口向电脑发送数据

    声明:本人跟随b站江科大学习,我的所有文章仅记录我的学习总结,以防我以后忘了,有地方回忆,况且江科大的资料都是开源的.我也希望大家多多去看江科大的视频,讲的是真的好,我的文章仅限看过视频学习过的,过段 ...

最新文章

  1. 如何下载python软件-python如何下载
  2. MIMIC 以太坊医疗项目开发(3)nodejs安装
  3. html请求接口_前端工程师吐后端工程师(第八讲)——接口的开发
  4. 前端趋势榜:上周最热门的 10 大前端项目 - 210327
  5. Win10,Win7,WinServer2012,WinServer2008内存最大支持
  6. 爬虫笔记1-Requests库的基本方法
  7. 代码片段---重定向
  8. LAMP架构部署论坛
  9. 金句: 對比MBA學位,我們更需要PSD學位的人! Poor, Smart and Deep Desire to… | consilient_lollapalooza on Xanga...
  10. 地球的3D模型制作教程【3DsMax】
  11. 计算机组成原理 好学吗,计算机组成原理太难了(计算机编程解释)
  12. Element select表单必填验证
  13. 一个光子的能量是多少?
  14. linux电子词典项目流程,毕业设计_linux下电子词典的设计与实现.doc
  15. java 模板转 PDF
  16. 事业上如何运用“长尾理论”?
  17. 全球及中国植物甾醇羟基硬脂酸酯行业发展应用与投资潜力分析报告2022版
  18. Qt5实现飞机大战1.0(上)
  19. 单片机4x4矩阵键盘c语言,求一个单片机4X4矩阵键盘扫描程序,C语言的。
  20. Zynaptiq​UNCHIRP低品质MP3音质优化插件促销

热门文章

  1. 《C语言程序教程》课后编程题
  2. JavaWeb web.xml配置详解
  3. python两个等于号是代表什么_python两个等于号是什么意思_等于号表示什么意思...
  4. 软件许可证管理应该怎么做?
  5. 安装win7和Ubuntu双系统后,win7耳机没声音,外放有声音
  6. flashback的用法
  7. [统计学理论基础] 中心极限定理与大数定律的区别
  8. 5473. 【NOIP2017提高组正式赛】小凯的疑惑
  9. centos 7使用gcc编译c语言,CentOS 7编译安装gcc 4.9.4
  10. 如何看到laravel的版本号