SetCommState函数失败原因

原文链接:https://blog.csdn.net/sunxiao061015/article/details/8052080

SetCommState设置串口失败原因

bool OpenPort(UINT portNo)
{
    char szPort[50];
    sprintf_s(szPort, "COM%d", portNo);

    hCom = CreateFile(szPort,         
           GENERIC_READ | GENERIC_WRITE,  
           0,                             
           NULL,                         
           OPEN_EXISTING,  //0,
           FILE_ATTRIBUTE_NORMAL, // FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,          
	       NULL);

    if (hCom == INVALID_HANDLE_VALUE){
        if (GetLastError() == ERROR_FILE_NOT_FOUND){
            //printf("ERROR: Handle was not attached. Reason: %s not available\n", 
              szPort);
        }else{
            printf("[%s]ERROR!!!\r\n",__FUNCTION__);
        }

		CloseHandle(hCom);
        return false;
    }

    return true;

}

bool PortInit(void)
{
	DCB poartDCB;
    COMMTIMEOUTS  CommTimeouts;

	//设置缓冲区大小
	SetupComm(hCom, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024

	//设置超时
	CommTimeouts.ReadIntervalTimeout = 1000;        //1000ms//读间隔超时
	CommTimeouts.ReadTotalTimeoutMultiplier = 1;  //500ms//读时间系数
	CommTimeouts.ReadTotalTimeoutConstant = 100;   //5000ms//读时间常量
	CommTimeouts.WriteTotalTimeoutMultiplier = 10; //500ms// 写时间系数
	CommTimeouts.WriteTotalTimeoutConstant = 200;  //2000ms//写时间常量
	
    if(!SetCommTimeouts(hCom, &CommTimeouts)){
		 printf("[%s]failed to set come time outs parameters\n", __FUNCTION__);
		 return false;
	}

    //设置波特率、停止位、奇偶校验、数据位
    if (!GetCommState(hCom, &poartDCB)){
        printf("[%s]failed to get current serial parameters\n", __FUNCTION__);
        return false;
    }else{

		printf("poartDCB.BaudRate : %ld\n",poartDCB.BaudRate);
		printf("poartDCB.Parity : %x\n",poartDCB.Parity);
		printf("poartDCB.ByteSize : %x\n",poartDCB.ByteSize);
		printf("poartDCB.StopBits : %x\n",poartDCB.StopBits);
	
		poartDCB.BaudRate = 115200;    //波特率           
		poartDCB.Parity   = 0;         //奇偶校验    
		poartDCB.ByteSize = 8;         //数据位   
		poartDCB.StopBits = 1;         //停止位
        //myDCB.fDtrControl = DTR_CONTROL_ENABLE;

        if (!SetCommState(hCom, &poartDCB)){
            printf("[%s]could not set Serial port parameters\n", __FUNCTION__);
            return false;
        }else{
            PurgeComm(hCom, PURGE_RXCLEAR | PURGE_TXCLEAR);
			Delay_us(1000);
        }
    }

    return true;
}

原因为:

poartDCB.StopBits= 0,1,2对应的是1bit,1.5bits,2bits.

poartDCB.ByteSize=6,7,8时   dcb.StopBits不能为1

poartDCB.ByteSize=5时   dcb.StopBits不能为2
————————————————
 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CSerialPort First Version by Remon Spekreijse on 2000-02-08 http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm Second Version by mrlong on 2007-12-25 https://code.google.com/p/mycom/ 增加 ClosePort 增加 WriteToPort 两个方法 增加 SendData 与 RecvData 方法 by liquanhai on 2011-11-04 http://blog.csdn.net/liquanhai/article/details/4955253 增加 ClosePort 中交出控制权,防止死锁问题 by liquanhai on 2011-11-06 http://blog.csdn.net/liquanhai/article/details/6941574 增加 ReceiveChar 中防止线程死锁 by viruscamp on 2013-12-04 https://github.com/viruscamp/CSerialPort 增加 IsOpen 判断是否打开 修正 InitPort 中 parity Odd Even 参数取值错误 修改 InitPort 中 portnr 取值范围,portnr>9 时特殊处理 取消对 MFC 的依赖,使用 HWND 替代 CWnd,使用 win32 thread 函数而不是 MFC 的 增加用户消息编号自定义,方法来自 CnComm by itas109 on 2014-01-10 http://blog.csdn.net/itas109/article/details/18358297 解决COM10以上端口无法显示的问题 扩展可选择端口,最大值MaxSerialPortNum可以自定义 添加QueryKey()和Hkey2ComboBox两个方法,用于自动查询当前有效的串口号。 by liquanhai on 2014-12-18 增加一些处理措施,主要是对减少CPU占用率 by itas109 on 2016-05-07 http://blog.csdn.net/itas109 修复每次打开串口发送一次,当串口无应答时,需要关闭再打开或者接收完数据才能发送的问题。 解决办法:在m_hEventArray中调整m_hWriteEvent的优先级高于读的优先级。CommThread(LPVOID pParam)函数中读写的位置也调换。 参考:http://zhidao.baidu.com/link?url=RSrbPcfTZRULFFd2ziHZPBwnoXv1iCSu_Nmycb_yEw1mklT8gkoNZAkWpl3UDhk8L35DtRPo5VV5kEGpOx-Gea 修复停止位在头文件中定义成1导致SetCommState报错的问题,应为1对应的停止位是1.5。UINT stopsbits = ONESTOPBIT switch(stopbits)和switch(parity)增加默认情况,增强程序健壮性 by itas109 on 2016-06-22 http://blog.csdn.net/itas109 增加ReceiveStr方法,用于接收字符串(接收缓冲区有多少字符就接收多少字符)。 解决ReceiveChar只能接收单个字符的问题。 by itas109 on 2016-06-29 http://blog.csdn.net/itas109 解决RestartMonitoring方法和StopMonitoring方法命令不准确引起的歧义,根据实际作用。 将RestartMonitoring更改为ResumeMonitoring,将StopMonitoring更改为SuspendMonitoring。 增加IsThreadSuspend方法,用于判断线程是否挂起。 改进ClosePort方法,增加线程挂起判断,解决由于线程挂起导致串口关闭死锁的问题。 增加IsReceiveString宏定义,用于接收时采用单字节接收还是多字节接收 by itas109 on 2016-08-02 http://blog.csdn.net/itas109 https://github.com/itas109 改进IsOpen方法,m_hComm增加INVALID_HANDLE_VALUE的情况,因为CreateFile方法失败返回的是INVALID_HANDLE_VALUE,不是NULL 改进ClosePort方法:增加串口句柄无效的判断(防止关闭死锁);m_hWriteEvent不使用CloseHandle关闭 改进CommThread、ReceiveChar、ReceiveStr和WriteChar方法中异常处理的判断,增加三种判断:串口打开失败(error code:ERROR_INVALID_HANDLE)、连接过程中非法断开(error code:ERROR_BAD_COMMAND)和拒绝访问(error code:ERROR_ACCESS_DENIED) 采用安全函数sprintf_s和strcpy_s函数替换掉sprintf和strcpy 改进QueryKey方法,用于查询注册表的可用串口值,可以搜索到任意的可用串口 改进InitPort方法,串口打开失败,增加提示信息:串口不存在(error code:ERROR_FILE_NOT_FOUND)和串口拒绝访问(error code:ERROR_ACCESS_DENIED) 加入viruscamp 取消对 MFC 的依赖 改进InitPort方法,如果上次串口是打开,再次调用InitPort方法,关闭串口需要做一定的延时,否则有几率导致ERROR_ACCESS_DENIED拒绝访问,也就是串口占用问题 初始化默认波特率修改为9600 修复一些释放的BUG 规范了一些错误信息,参考winerror.h -- error code definitions for the Win32 API functions 删除SendData和RecvData方法 by itas109 on 2016-08-10 http://blog.csdn.net/itas109 https://github.com/itas109 改进ReceiveStr方法,comstat.cbInQue = 0xcccccccc的情况(如串口异常断开),会导致RXBuff初始化失败 by itas109 on 2017-02-14 http://blog.csdn.net/itas109 https://github.com/itas109 兼容ASCII和UNICODE编码 ReceiveStr函数中发送函数SendMessage的第二个参数采用结构体形式,包括portNr串口号和bytesRead读取的字节数,可以处理16进制的时候0x00截断问题 精简不必要的函数SendData和RecvData 尽量的取消对 MFC 的依赖,Hkey2ComboBox函数暂时保留 其他小问题修改 博客:blog.csdn.net/itas109 Email:itas109@qq.com
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
可以使用Windows API中提供的串口函数来读取16位数据,并使用C++中的文件操作函数将数据转换为16进制字符串并保存到文件中。 以下是一个示例代码: ```c++ #include <Windows.h> #include <cstdio> #include <fstream> #include <iomanip> int main() { HANDLE hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hSerial == INVALID_HANDLE_VALUE) { printf("Failed to open serial port!\n"); return 1; } DCB dcbSerialParams = { 0 }; dcbSerialParams.DCBlength = sizeof(dcbSerialParams); if (!GetCommState(hSerial, &dcbSerialParams)) { printf("Failed to get serial port parameters!\n"); CloseHandle(hSerial); return 1; } dcbSerialParams.BaudRate = CBR_115200; dcbSerialParams.ByteSize = 8; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.Parity = NOPARITY; if (!SetCommState(hSerial, &dcbSerialParams)) { printf("Failed to set serial port parameters!\n"); CloseHandle(hSerial); return 1; } char buf[2]; DWORD bytesRead; if (!ReadFile(hSerial, buf, sizeof(buf), &bytesRead, NULL)) { printf("Failed to read from serial port!\n"); CloseHandle(hSerial); return 1; } unsigned short data = ((unsigned char)buf[1] << 8) | (unsigned char)buf[0]; std::ofstream file("data.txt"); if (file.is_open()) { file << std::hex << std::setw(4) << std::setfill('0') << data; file.close(); } else { printf("Failed to open file for writing!\n"); CloseHandle(hSerial); return 1; } CloseHandle(hSerial); return 0; } ``` 这个程序会打开COM1串口,读取两个字节的数据,将它们组合成一个16位整数,并使用文件输出流将其转换为16进制字符串并保存到文件"data.txt"中。你可以根据自己的需要修改串口参数和读取数据的方式。如果文件打开失败,程序会输出一条错误消息并退出。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值