多线程 MODEN 串口编程
// ModemDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "Modem.h"
#include "ModemDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CModemDlg 对话框
CModemDlg::CModemDlg(CWnd* pParent /*=NULL*/)
: CDialog(CModemDlg::IDD, pParent)
, m_show(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CModemDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_show);
}
BEGIN_MESSAGE_MAP(CModemDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDOK, OnBnClickedOk)
ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
// CModemDlg 消息处理程序
BOOL CModemDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将/“关于.../”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO:在此添加额外的初始化代码
threadHandle=AfxBeginThread(RUNTIME_CLASS(CmyThread));
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CModemDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CModemDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CModemDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CModemDlg::OnBnClickedOk()
{
TerminateThread(threadHandle,0);
OnOK();
}
void CModemDlg::OnEnChangeEdit1()
{
UpdateData(true);
AfxMessageBox(m_show);
}
BOOL CModemDlg::OnEraseBkgnd(CDC* pDC)
{
CBrush brush;
brush.CreateSolidBrush(RGB(255,255,255));
CBrush *oldBrush=pDC->SelectObject(&brush);
CRect rc;
GetClientRect(&rc);
pDC->Rectangle(&rc);
pDC->SelectObject(oldBrush);
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
}
// myThread.cpp : 实现文件
//
#include "stdafx.h"
#include "Modem.h"
#include "myThread.h"
#include <assert.h>
// CmyThread
IMPLEMENT_DYNCREATE(CmyThread, CWinThread)
CmyThread::CmyThread()
{
m_receive="";
}
CmyThread::~CmyThread()
{
}
BOOL CmyThread::InitInstance()
{
//m_bEvtChar=EVENTCHAR;
//m_fBinary=1;
//m_bFlowCtrl = FC_XONXOFF ;
//m_fXonXoff = FALSE;
m_edit=(CEdit *)GetMainWnd()->GetDlgItem(IDC_EDIT1);
readOver.Offset=0;
readOver.OffsetHigh=0;
readOver.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
assert(readOver.hEvent);
writeOver.Offset=0;
writeOver.OffsetHigh=0;
writeOver.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
assert(writeOver.hEvent);
m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL);
if(m_hCom==INVALID_HANDLE_VALUE)
{
AfxMessageBox("打开串口失败!!");
return FALSE;
}
// SetCommMask(m_hCom,EV_RXCHAR);
SetupComm(m_hCom,4096,4096);
PurgeComm(m_hCom,PURGE_RXABORT|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_TXCLEAR);
time.ReadIntervalTimeout=0XFFFFFFFF;
time.ReadTotalTimeoutConstant=1000;
time.ReadTotalTimeoutMultiplier=0;
time.WriteTotalTimeoutConstant=1000;
time.WriteTotalTimeoutMultiplier=0;
SetCommTimeouts(m_hCom,&time);
dcb.DCBlength=sizeof(DCB);
GetCommState(m_hCom,&dcb);
dcb.ByteSize=8;
dcb.StopBits=ONESTOPBIT;
dcb.Parity=NOPARITY;
dcb.BaudRate=9600;
// dcb.EvtChar=EVENTCHAR;
dcb.fOutxDsrFlow=FALSE;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.fOutxCtsFlow=FALSE;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fInX=TRUE;
dcb.fOutX=TRUE;
dcb.XonChar=0x11;
dcb.XoffChar=0x13;
dcb.XonLim=100;
dcb.XoffLim=100;
dcb.fBinary=TRUE;
dcb.fParity=TRUE;
SetCommState(m_hCom,&dcb);
EscapeCommFunction(m_hCom,SETDTR);
BOOL fWriteStat;
DWORD dwBytesWritten;
DWORD dwErrorFlags;
DWORD dwError;
DWORD dwBytesSent=0;
char szError[128];
fWriteStat=WriteFile(m_hCom,"AT+VCID=1+FCLASS=8/r",40,&dwBytesWritten,&writeOver);
if (!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult(m_hCom,&writeOver,&dwBytesWritten,TRUE))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
dwBytesSent += dwBytesWritten;
continue;
}
else
{
wsprintf( szError, "<CE-%u>", dwError ) ;
ClearCommError(m_hCom, &dwErrorFlags, &ComStat ) ;
break;
}
}
dwBytesSent += dwBytesWritten;
if( dwBytesSent != 40 )
wsprintf(szError,"/nProbable Write Timeout: Total of %ld bytes sent", dwBytesSent);
else
wsprintf(szError,"/n%ld bytes written", dwBytesSent);
OutputDebugString(szError);
}
else
{
ClearCommError(m_hCom, &dwErrorFlags, &ComStat ) ;
return FALSE;
}
}
PurgeComm(m_hCom,PURGE_RXCLEAR|PURGE_TXCLEAR);
return TRUE;
}
int CmyThread::Run()
{
char buffer[1024];
memset(buffer,0,sizeof(buffer));
buffer[0]='/0';
while(1)
{
BOOL fReadStat ;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
char szError[10];
ClearCommError(m_hCom, &dwErrorFlags, &ComStat) ;
dwLength =ComStat.cbInQue;
if (dwLength > 0)
{
fReadStat = ReadFile(m_hCom,buffer,dwLength, &dwLength,&readOver) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("/n/rIO Pending");
while(!GetOverlappedResult(m_hCom,&readOver,&dwLength, TRUE ))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
continue;
else
{
wsprintf( szError, "<CE-%u>", dwError ) ;
ClearCommError(m_hCom , &dwErrorFlags, &ComStat ) ;
break;
}
}
}
else
{
dwLength = 0 ;
ClearCommError(m_hCom , &dwErrorFlags, &ComStat ) ;
}
}
}
if(dwLength!=0)
{
CString temp,temp2;
temp.Format("%s",buffer);
temp2=temp.GetAt(1);
m_receive+=temp2;
ShowNumber(m_receive);
}
}
}
void CmyThread::ShowNumber(CString &str)
{
CString result;
int begin=str.Find("RD");
int end=str.Find("C");
int count=end-begin-2;
if(begin!=-1 && end!=-1)
{
result=str.Mid(begin+2,count);
m_edit->SetWindowText(result);
str="";
}
}
int CmyThread::ExitInstance()
{
SetCommMask(m_hCom,0);
EscapeCommFunction(m_hCom,CLRDTR);
PurgeComm(m_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
CloseHandle(m_hCom);
m_hCom = NULL;
CloseHandle(readOver.hEvent);
CloseHandle(writeOver.hEvent);
return CWinThread::ExitInstance();
}
BEGIN_MESSAGE_MAP(CmyThread, CWinThread)
END_MESSAGE_MAP()
// CmyThread 消息处理程序
多线程 MODEN 串口编程相关推荐
- C——Linux下的串口编程
原 C--Linux下的串口编程 2017年06月06日 19:30:50 C_Aya 阅读数:11537 <span class="tags-box artic-tag-box&qu ...
- CSerialPort多线程串口编程工具详解
1.前言 既然有了MSComm这种简单粗暴的控件,为什么还需要CSerialPort类?这是因为与前者相比,这个类在程序的发布上不需要加入其他的文件,而且CSerialPort提供给我们的函数都是开放 ...
- linux 多线程串口编程总结
最近在玩DJI M100,调用API获取GPS位置时发现高程定位完全是错的(负的几百多米),查了一下文档说高程数据是由气压计得到的,而飞行控制时又需要比较可靠的高度信息,于是乎决定用上我们实验室的搭载 ...
- Qt 多线程串口编程
一.问题 以前串口编程使用第三方的CnComm.h编程,CnComm作者博客链接,使用起来还蛮好的,不过既然用qt了就想着用qt自带的QSerialPort,移植性更好一些,结果折腾了好几天,主要遇到 ...
- 基于MFC串口编程和曲线图绘制(visual studio2008,Teechart绘图控件)的程序总结
前言 今年刚进入公司按经理的要求为底盘测控机写了一个小小的console.这也是第一次教认真的完成整个程序的编写.程序不大,所用技术比较基础也不前卫,属于初级程序员的练手程序(知识的整理和搬运).虽然 ...
- Win32 API串口编程
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...
- 深入浅出VC++串口编程--第三方类
串口类 从本系列文章连载三.四可以看出,与通过WIN32 API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出On ...
- 多线程的串口通信-1
多线程的串口通信 1 下位机STM32发送的数据格式与串口参数 1.1下位机上传的数据格式: 1.2串口参数 2 上位机程序 2.1Future: ~~2.2串口参数同上~~ 3 QT程序设计 QT走 ...
- 【C++】多线程与异步编程【四】
文章目录 [C++]多线程与异步编程[四] 0.三问 1.什么是异步编程? 1.1同步与异步 1.2 **阻塞与非阻塞** 2.如何使用异步编程 2.1 使用全局变量与条件变量传递结果 实例1: 2. ...
最新文章
- SSL证书如何工作?
- 互联网1分钟 | 0110 腾讯联手拳头游戏成立腾竞体育;百度智能云发布中国首款智能边缘计算产品BIE...
- 插入和shell排序
- fillstyle属性_html设置或返回用于填充绘画的颜色渐变或模式的属性fillStyle
- C4C Product Price List的模型中和有效期相关的两个字段
- 使用iperf进行设备吞吐量测试
- java调用go接口_go语言调用API实线分词
- spring—第一个spring程序
- tickcount()修改成小时分钟_银行核心系统24小时机制实现总结
- 音视频开发(22)---基于RTMP推送实时AAC+H264流(三)
- 【学习笔记】函数高级使用技巧:建立函数队列
- 拜托,面试别再问我基数排序了!!!
- 杰里之AC897N_AD697N_earphone_release_ V2.0.1 开立体声左右声道数据对调【篇】
- 常见服务器故障有哪些?如何预防服务器发生故障?服务器故障后如何恢复数据?
- window 10 局域网同步时间(解决错误:This scheduler instance is still active but was recovered by another instanc)
- mysql的组内排序生成序号_sql 分组查询,组内排序, 组内添加序号 (SQL Server 排序函数 ROW_NUMBER和RANK 用法总结)...
- XUL 用户界面语言介绍
- 交互组件滚动条,搜索框,上传组件,翻页的微创新
- bottom sheets_使用Sheetson建立由Google Sheets支持的免费电子邮件列表
- Centos Stream 9安装docker-ce
热门文章
- GhostXP_SP2电脑公司特别版_v7.8[修正版]
- 高级软件工程课程总结报告
- “中国90后系列研究:社交浪潮中的90后”.pdf
- 中国的手机号码格式化/分类工具
- 欧姆龙CP1H如何进行PLC远程编程及数据采集
- 从Excel到Smartbi,国内头部企业的报表是这样进阶的!
- OJB中的多表查询和更新
- JAVA实现Freemarker生成动态数据的Word文档下载到浏览器
- 中国自主研发的USB2.0 HUB芯片,即将发布CH334 和CH335工业级
- 怎么用显卡计算_显卡性能的软件 3dmark怎么用