精华内容
下载资源
问答
  • 找到指定蓝牙名称的设备,进行配对,配对成功后,虚拟串口--->打开串口,收发数据,关闭串口。在蓝牙连接断开的压力测试中(需进行几百次测试),一般在大约几十次时,打开串口会失败,打开串口代码如下: ...
  • 写在前面 由于个人是个C++和windows ...申请到蓝牙虚拟串口后,后面的通信就把蓝牙当串口用了。算是完成了领导交代的任务… 1 用到的函数 1.1 BluetoothSetServiceState DWORD BluetoothSetServiceState( HANDLE hRa

    写在前面

    由于个人是个C++和windows API方面的小白,蓝牙配对这部分涉及到回调方面,实在使不上劲,快要放弃之际,开发小伙伴告诉我公司蓝牙都是直连模式,可以跳过配对这部分。无奈这下,只能先跳过配对这部分(后面再琢磨)。
    申请到蓝牙虚拟串口后,后面的通信就把蓝牙当串口用了。算是完成了领导交代的任务…

    1 用到的函数

    1.1 BluetoothSetServiceState

    DWORD BluetoothSetServiceState(
      HANDLE                      hRadio,
      const BLUETOOTH_DEVICE_INFO *pbtdi,
      const GUID                  *pGuidService,
      DWORD                       dwServiceFlags
    );
    

    2 实现

    // 申请串口服务
    		const BLUETOOTH_DEVICE_INFO *bdi = NULL;
    		bdi = &remote_bluetooth[i];
    		const GUID *guid = NULL;
    		guid = &SerialPortServiceClass_UUID;
    		BluetoothSetServiceState(hRadio, bdi, guid, BLUETOOTH_SERVICE_ENABLE);
    

    一个问题

    蓝牙虚拟串口是建立了,但是怎么能够知道哪个串口是蓝牙的?我这里用的比较笨的办法:
    1.申请蓝牙虚拟串口前扫描一次windows的所有串口,并保存串口名字
    2.申请蓝牙虚拟串口后再扫描一次windows的所有串口,与之前扫描结果对比,多出来的就是这个蓝牙串口
    要是那个小伙伴有其他方法,麻烦指教一下,请评论或私信,谢谢

    3 扫描windows蓝牙并返回串口列表

    // 获取windows所有串口列表
    int scanComServer(string comlist[]) {
    	HKEY hKey;
    	LPCTSTR data_Set = _T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\");
    	LONG ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey);
    	if (ret0 != ERROR_SUCCESS)
    	{
    		wcout << (L"错误:无法打开有关的hKEY");
    		return -1;
    	}
    
    	DWORD dwIndex = 0;
    	int count = 0;
    	while (1)
    	{
    		LONG Status;
    		CHAR Name[256] = { 0 };
    		UCHAR szPortName[80] = { 0 };
    		DWORD dwName;
    		DWORD dwSizeofPortName;
    		DWORD Type;
    		dwName = sizeof(Name);
    		dwSizeofPortName = sizeof(szPortName);
    		Status = RegEnumValue(hKey, dwIndex++, (LPWSTR)Name, &dwName, NULL, &Type,
    			szPortName, &dwSizeofPortName);
    
    		if ((Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA))
    		{
    			CString str;
    			str.Format(L"%s", szPortName);
    			comlist[count] = CT2A(str.GetBuffer());
    			count++;
    			//TRACE("\n-------%s", str);COM_SERIAL_PORT_LIST.AddString(str);    
    			/*cout << comlist[count];*/
    		}
    		else
    		{
    			break;
    		}
    	}
    	RegCloseKey(hKey);
    	return 0;
    };
    
    展开全文
  • windows蓝牙虚拟串口通信

    万次阅读 2015-11-17 15:48:44
    windows下可以通过RFCOMM虚拟串口进行通信. RFCOMM简介: RFCOMM仿真RS232串口,该仿真过程包括非数据通路状态的传输。RFCOMM不限制人工速率或步长,如果通信链路两端的设备都是负责将数据转发到其他通信介质的...

    windows下可以通过RFCOMM虚拟的串口进行通信.
    RFCOMM简介:
    RFCOMM仿真RS232串口,该仿真过程包括非数据通路状态的传输。RFCOMM不限制人工速率或步长,如果通信链路两端的设备都是负责将数据转发到其他通信介质的第二类设备,或在两端RFCOMM设备接口上进行数据传输,实际数据吞吐一般将反映波特率的设置.RFCOMM支持两个设备之间的多串口仿真,也支持多个设备多串口的仿真.
    winsock支持RFCOMM,其地址是SOCKADDR_BTH,地址族是AF_BTH.
    1.首先把蓝牙名字转换成能链接的地址。

    ULONG CBlueTooth::NameToBthAddr( const char *pszRemoteName, PSOCKADDR_BTH pRemoteBtAddr)
    {
        int             iResult = CXN_SUCCESS;
        BOOL            bContinueLookup = FALSE, bRemoteDeviceFound = FALSE;
        ULONG           ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSET);
        HANDLE          hLookup = NULL;
        PWSAQUERYSET    pWSAQuerySet = NULL;
    
        ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));
        pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            ulPQSSize);
        if ( NULL == pWSAQuerySet ) 
        {
            iResult = STATUS_NO_MEMORY;
        }
        if ( CXN_SUCCESS == iResult)
        {
            for ( int iRetryCount = 0;!bRemoteDeviceFound && (iRetryCount < CXN_MAX_INQUIRY_RETRY);iRetryCount++ )
            {   
                ulFlags = LUP_CONTAINERS;               
                ulFlags |= LUP_RETURN_NAME;             
                ulFlags |= LUP_RETURN_ADDR;
    
                if ( 0 != iRetryCount )
                {                                       
                    ulFlags |= LUP_FLUSHCACHE;                  
                    Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);
                }
    
                iResult = CXN_SUCCESS;
                hLookup = 0;
                bContinueLookup = FALSE;
                ZeroMemory(pWSAQuerySet, ulPQSSize);
                pWSAQuerySet->dwNameSpace = NS_BTH;
                pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);
                iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);
    
                if ( (NO_ERROR == iResult) && (NULL != hLookup) ) 
                {
                    bContinueLookup = TRUE;
                } else if ( 0 < iRetryCount )
                {                   
                    break;
                }
    
                while ( bContinueLookup )
                {                   
                    if ( NO_ERROR == WSALookupServiceNext(hLookup,
                        ulFlags,
                        &ulPQSSize,
                        pWSAQuerySet) )
                    {
                        if ( ( pWSAQuerySet->lpszServiceInstanceName != NULL ) &&
                            ( CXN_SUCCESS == stricmp(pWSAQuerySet->lpszServiceInstanceName, pszRemoteName) ) )
                        {                               
                            CopyMemory(pRemoteBtAddr,
                                (PSOCKADDR_BTH) pWSAQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr,
                                sizeof(*pRemoteBtAddr));
                            bRemoteDeviceFound = TRUE;
                            bContinueLookup = FALSE;
                        }
                    } else
                    {
                        iResult = WSAGetLastError();
                        if ( WSA_E_NO_MORE == iResult )
                        { 
                            bContinueLookup = FALSE;
                        }
                        else if ( WSAEFAULT == iResult )
                        {                           
                            HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
                            pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
                                HEAP_ZERO_MEMORY,
                                ulPQSSize);
                            if ( NULL == pWSAQuerySet )
                            {                               
                                iResult = STATUS_NO_MEMORY;
                                bContinueLookup = FALSE;
                            }
                        }
                        else
                        {                       
                            bContinueLookup = FALSE;
                        }
                    }
                }
    
                WSALookupServiceEnd(hLookup);
                if ( STATUS_NO_MEMORY == iResult )
                {
                    break;
                }
            }
    
        }
        if ( NULL != pWSAQuerySet )
        {
            HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
            pWSAQuerySet = NULL;
        }
        if ( bRemoteDeviceFound )
        {
            iResult = CXN_SUCCESS;
        } else
        {
            iResult = CXN_ERROR;
        }
    
        return iResult;
    }

    2.建立链接

    //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\BTHPORT\Parameters\LocalServices\{00001101-0000-1000-8000-00805f9b34fb}
    /*
    CBlueTooth:是本模块的底层通讯的类,该类为ECU类提供服务,该类把ECU要发送的类容抽象成类,通过发送和接收缓冲,保存该流的内容,而不管实际的发送或
    接收的数据的意义。
    */
    DEFINE_GUID(g_guidServiceClass,0x00001101,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5f,0x9b,0x34,0xfb);
    //RemoteBthAddr,蓝牙设备的地址
        SOCKADDR_BTH  SockAddrBthServer= RemoteBthAddr;
        SockAddrBthServer.addressFamily = AF_BTH;
        SockAddrBthServer.serviceClassId = g_guidServiceClass;
        SockAddrBthServer.port = 0;
        if (INVALID_SOCKET != LocalSocket)
        {
            closesocket(LocalSocket);
        }
        LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
        if ( INVALID_SOCKET == LocalSocket )
        {
            return status;
        }
        //建立蓝牙连接
        if ( 0 == connect(LocalSocket,
            (struct sockaddr *) &SockAddrBthServer,
            sizeof(SOCKADDR_BTH)) ) 
        {
            status=true;
        }

    3.发送数据

    ResetEvent(hSendEvent);
        int sum=0;
        while (sum < PDU.size())
        {
            int iCount=send(LocalSocket,PDU.data()+sum,PDU.size()-sum,0);
            if (iCount == SOCKET_ERROR)
            {
                bConnect = false;
            }
            sum += iCount;
        }
    4.接收数据
    
    while(1)
            {
                char buffer[100]={0};
                int count=recv(LocalSocket,buffer,sizeof(buffer),0);
                if (count < 0)
                {               
                    continue;               
                }
                CurSum +=count; 
                if (0 != count)
                {
    
                    for (int i=0;i<count;i++)
                    {
                        ReceiveBuffer.push_back(buffer[i]);
                    }
                                }
                if(ReceiveBuffer.size() >= 6 && (DestSum == 8))
                {
                    unsigned short int *p =(unsigned short int*)(ReceiveBuffer.data()+4);
                    DestSum += *p;              
                }
                if (DestSum != 0 && CurSum >= DestSum)
                {
                    break;
                }
    展开全文
  • 基于Windows蓝牙虚拟串口通信

    千次阅读 2018-11-20 17:18:32
    一、枚举本地蓝牙设备 /******************************************************************************\ 枚举本地所有蓝牙设备到 m_arrLocal,返回本地蓝牙设备数 \******************************************...

    一、枚举本地蓝牙设备

    /******************************************************************************\
    枚举本地所有蓝牙设备到 m_arrLocal,返回本地蓝牙设备数
    \******************************************************************************/
    int CBlueTooth::EnumLocalDev()
    {
        RemoveAllLocalDev();

        HANDLE                      hRadio  =   NULL;
        BLUETOOTH_FIND_RADIO_PARAMS bfrp    =   {sizeof(bfrp)};
        HBLUETOOTH_RADIO_FIND       hFind   =   BluetoothFindFirstRadio(&bfrp,&hRadio);

        if(hFind)
        {
            do{
                if(hRadio)
                {
                    m_arrLocal.Add(hRadio);
                }
            }while(BluetoothFindNextRadio(hFind,&hRadio));
            BluetoothFindRadioClose(hFind);
        }
        return (int)m_arrLocal.GetSize();
    }

    二、搜索远程蓝牙设备

    //
    // 用蓝牙 APIs 搜索附近的蓝牙设备,成功时返回设备数,否则返回-1
    //
    int CBlueTooth::Scan(HANDLE hRadio,BOOL fReturnAuthenticated,BOOL fReturnRemembered,BOOL fReturnUnknown
                        ,BOOL fReturnConnected,BOOL fIssueInquiry,UCHAR cTimeoutMultiplier)
    {
        RemoveAllRemoteDev();
        BLUETOOTH_DEVICE_INFO           bdi =   { sizeof(BLUETOOTH_DEVICE_INFO) };
        BLUETOOTH_DEVICE_SEARCH_PARAMS  bdsp;

        ZeroMemory(&bdsp, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS));
        bdsp.dwSize                 =   sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
        bdsp.hRadio                 =   hRadio;
        bdsp.fReturnAuthenticated   =   fReturnAuthenticated;
        bdsp.fReturnRemembered      =   fReturnRemembered;
        bdsp.fReturnUnknown         =   fReturnUnknown;
        bdsp.fReturnConnected       =   fReturnConnected;
        bdsp.fIssueInquiry          =   fIssueInquiry;
        bdsp.cTimeoutMultiplier     =   cTimeoutMultiplier;
        HBLUETOOTH_DEVICE_FIND  hbf =   BluetoothFindFirstDevice(&bdsp, &bdi);
        if(hbf == NULL)
        {
            return -1;
        }
        do
        {
            TRACE ( _T("%s ( %s )\n"), bdi.szName, AddrToStr(bdi.Address.rgBytes) );

            RemoteDev dev;
            dev.Address =   bdi.Address.ullLong;
            dev.sName   =   bdi.szName;
            m_arrRemote.Add(dev);
        }while(BluetoothFindNextDevice(hbf,&bdi));
        BluetoothFindDeviceClose(hbf);
        return m_arrRemote.GetSize();
    }

    三、与指定的蓝牙设备配对

            int nSelLocal   =   0;
            int nSelRemote  =   0;
            BLUETOOTH_DEVICE_INFO bdi;
            if(!GetSomeInfo(&nSelLocal,&nSelRemote,&bdi))
            {
                return;
            }
            CDlgPairSend dlg;
            dlg.m_sLocal    =   m_ListLocal. GetItemText(nSelLocal ,0) + _T(" - ") + m_ListLocal .GetItemText(nSelLocal ,1);
            dlg.m_sRemote   =   m_ListRemote.GetItemText(nSelRemote,0) + _T(" - ") + m_ListRemote.GetItemText(nSelRemote,1);
            if(dlg.DoModal() == IDOK)
            {

                int     nLenW   =   MultiByteToWideChar(CP_ACP,0,dlg.m_sPwd,dlg.m_sPwd.GetLength(),NULL,0);
                wchar_t*wzPwd   =   new wchar_t[nLenW + 1];
                MultiByteToWideChar(CP_ACP,0,dlg.m_sPwd,dlg.m_sPwd.GetLength(),wzPwd,nLenW);

                t_RemoteBthDevInfo RemoteBthDevInfo;
                RemoteBthDevInfo.Address.ullLong = bdi.Address.ullLong;
                m_BlueTooth.EnumerateInstalledServices ( RemoteBthDevInfo );

                if(BluetoothAuthenticateDevice(m_hWnd,m_BlueTooth.m_arrLocal[nSelLocal],&bdi,wzPwd,nLenW)==ERROR_SUCCESS)
                {
                    MessageBox(_T("配对成功"));

                }
                else
                {
                    MessageBox(_T("配对失败"));
                }
                delete[] wzPwd;

    四、连接蓝牙设备,枚举串口,寻找蓝牙虚拟串口,发送握手指令 ,

            HKEY hKey;
            LPCTSTR lpSubKey="HARDWARE\\DEVICEMAP\\SERIALCOMM\\";

            if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey)!= ERROR_SUCCESS)
            {
                return ;
            }

            char szValueName[NAME_LEN];
            BYTE szPortName[NAME_LEN];
            LONG status;
            DWORD dwIndex = 0;
            DWORD dwSizeValueName=100;
            DWORD dwSizeofPortName=100;
            DWORD Type;
            dwSizeValueName = NAME_LEN;
            dwSizeofPortName = NAME_LEN;
            do
            {
                status = RegEnumValue(hKey, dwIndex++, szValueName, &dwSizeValueName, NULL, &Type,
                    szPortName, &dwSizeofPortName);
                if((status == ERROR_SUCCESS))
                {
                    CString str;
                    str=(char *)szPortName;
                    m_SerialPort.SetCom(str);

                    if (m_SerialPort.OpenConnection())
                    { 
                        //发送指令,判断串口是否有回复,有回复即为蓝牙虚拟串口
                        unsigned char data[2]={0xa5,0x5a}; //握手
                        m_SerialPort.WriteComm(data,2);
                        
                        char *Buf=new char[10];
                        memset(Buf,0,10);
                        int nCount=0;
                        nCount=m_SerialPort.ReadComm(Buf,1);
                        byte bt=Buf[0];
                        if (bt==0xa5)
                        {
                            MessageBox(_T("连接成功"));
                            Start();
                            break;
                        }
                    }
                }
                dwSizeValueName = NAME_LEN;
                dwSizeofPortName = NAME_LEN;
            } while((status!= ERROR_NO_MORE_ITEMS));
            RegCloseKey(hKey);

    五、通过串口与远程蓝牙设备通信


    源码参考:https://download.csdn.net/download/qq_23565865/10789156

    展开全文
  • PPC手机上使用的蓝牙虚拟串口调试助手,类似于平常使用的串口调试精灵。
  • 本文提供了一个类 用于在wince平台使用 便于开发蓝牙 包含 搜索蓝牙设备 建立蓝牙连接 建立蓝牙虚拟串口 等 拿了直接可以使用 基于 mfc 开发
  • 那我们就可以采用蓝牙虚拟串口来通信.当然蓝牙服务程序默认也带有一些通信程序,如文件传输出、语音、网络、打印、图像传输等,如果有安装的其它插件可能更多。但是有没有灵活的操作呢,比如我们进行虚拟仪器的网络...

    假如你有两台蓝牙设备,如两能计算机并都蓝牙适配器,或PC机与多功能终端(手机,虚拟仪器等等)

    假如你安装了蓝牙的服务程序, 如IVT的程序或它程序, 它有串口服务功能. 并且开起了串口服务.

    那我们就可以采用蓝牙的虚拟串口来通信.

    当然蓝牙服务程序默认也带有一些通信程序,如文件传输出、语音、网络、打印、图像传输等,如果有安装的其它插件可能更多。但是有没有灵活的操作呢,比如我们进行虚拟仪器的网络编程。那就试着用串口吧。串口不是先进的,但是它是成熟的,平民化的,是地球人都会用。

    这里我就安装了IVT 6.4.249.

    一台电脑,本机为EeePC: 远端为yiling-PC

    另一台电脑: yiling-PC, 对于它来说,远端就是EeePC

    两台电脑都开起了串口服务;

    配对方法就不说了.

    关于串口:有两个选项,

    一是 对于本地蓝牙串口属性:

    有一个"安全连接"属性,如果是安全连接属性,则连接对方串口时,需要对方的确认才能连接.

    二是 对于远文蓝牙串口属性:

    有一个"自动连接"属性,如果是自动连接属性,则本地打开远程串口时,则蓝牙连接自动连接(可能会不成功,有时需要手动连接,一般先手动连接,自已的程序再打开串口).

    以上两点都是对同一台电脑来说的,另一台电脑最好也如同设置.

    -----------

    为了说明问题.我在yilingPC上又添加了多个蓝牙虚拟串口,如串口10.

    注意的是,在本机查看的蓝牙设备中的远端中的串口号并不是远端真正的串口号,这可能是IVT的问题.

    具体使用时,要看蓝牙正在连接的哪个串口号.

    这可以从计算机的设置管理器中查看;

    ------------------------------------------

    先说一说串口的接口:

    Serial (PC 9)

    PC端9线

    (At the Computer)

    9 PIN D-SUB MALE at the Computer.

    Pin Name Dir Description

    1 CD Carrier Detect

    2 RXD Receive Data

    3 TXD Transmit Data

    4 DTR Data Terminal Ready

    5 GND System Ground

    6 DSR Data Set Ready

    7 RTS Request to Send

    8 CTS Clear to Send

    9 RI Ring Indicator

    Note: Direction is DTE (Computer) relative DCE (Modem).

    对机线:

    其中1线不一定接,像现在用的蓝牙虚拟串口连接就不接.

    -----------------------------------------------------------------

    先说检测线电平的方法.

    计算机可控制的串口线电平的是:DTR和RTS.可检测的线电平是CD,DSR,CTS,RI.

    由上述PC-PC接线方式可知,两机可检验的信号只有6线DSR(由远机DTR控制)和8线CTS(由远机RTS控制)

    程序(在别人程序的基础上改的):

    -----------

    有全局变量:

    HANDLE hComm; //给串行端口用的Handle

    boolean DTRState,RTSState;

    ----

    打开串口

    void __fastcall TForm1::Button1Click(TObject *Sender)

    {

    char *ComNo;

    DCB dcb;

    String Temp;

    //取得要打开的通信端口

    // 取得要打开的通信端口

    if(rdCOM->ItemIndex +1>9)

    Temp = "\\\\.\\COM"+IntToStr(rdCOM->ItemIndex

    +1);

    else

    Temp = "COM"+IntToStr(rdCOM->ItemIndex +1);

    //转换至指针类型Char

    ComNo = Temp.c_str();

    hComm = CreateFile(ComNo,GENERIC_READ | GENERIC_WRITE,

    0, NULL, OPEN_EXISTING, 0, 0);

    if (hComm == INVALID_HANDLE_VALUE) // 如果COM 未打开

    {

    MessageBox(0, "打开通信端口错误!!","Comm Error",MB_OK);

    return;

    }

    //将dcb地址传入,以取得通信参数

    GetCommState(hComm,&dcb); // 得知目前COM 的状态

    dcb.BaudRate =

    CBR_9600; // 设置波特率为9600

    dcb.ByteSize =

    8; // 字节为 8 bit

    dcb.Parity =

    NOPARITY; // Parity 为 None

    dcb.StopBits =

    ONESTOPBIT; // 1 个Stop bit

    //通信端口设置

    if (!SetCommState(hComm, &dcb))

    { // 设置COM 的状态

    MessageBox

    (0, "通信端口设置错误!!!","Set Error",MB_OK);

    CloseHandle(hComm);

    return;

    }

    EscapeCommFunction( hComm, CLRDTR); //将DTR降为低电位

    EscapeCommFunction( hComm, CLRRTS); //将RTS降为低电位

    }

    -------------------------------

    其中关键的问题是,串口大于9时(1-9相同,10以上不同),打开串口的方法不同,

    ----

    关闭串口

    //------------------------------------------------------------------

    void __fastcall TForm1::Button2Click(TObject *Sender)

    {

    if (hComm!=INVALID_HANDLE_VALUE) CloseHandle(hComm);

    exit(EXIT_SUCCESS);

    }

    //------------------------------------------------------------------

    程序用用一个时钟去查询输入线的电平信息.

    void __fastcall TForm1::Timer1Timer(TObject

    *Sender)

    {

    unsigned long lStatus;

    if (hComm == INVALID_HANDLE_VALUE) return;

    if (GetCommModemStatus(hComm,&lStatus))

    {

    //检查CTS状态

    if (lStatus & MS_CTS_ON)

    spCTS->Brush->Color =clRed;

    else spCTS->Brush->Color

    =clWhite;

    //检查DSR状态

    if (lStatus & MS_DSR_ON )

    spDSR->Brush->Color =clRed;

    else spDSR->Brush->Color

    =clWhite;

    //检查RI状态

    if ( lStatus & MS_RING_ON )

    spRI->Brush->Color =clRed;

    else spRI->Brush->Color

    =clWhite;

    //检查CD状态

    if ( lStatus & MS_RLSD_ON )

    spCD->Brush->Color =clRed ;

    else spCD->Brush->Color

    =clWhite;

    }

    }

    ----------------------

    设置DTR及RTS

    //------------------------------------------------------------------

    void __fastcall TForm1::BitBtn1Click(TObject *Sender)

    {

    //若通信端口未打开,则不作动作,并跳出

    if

    (hComm==0)

    {

    MessageBox (0, "通信端口未打开!!!","Open Error",MB_OK);

    return;

    }

    //判断DTRState值,输出状态后,将原值作转态

    if

    (DTRState)

    {

    //输出DTR状态为低电位

    EscapeCommFunction( hComm, CLRDTR );

    spDTR->Brush->Color=clWhite;

    //更改信号灯的颜色

    }

    else

    {

    //输出DTR的状态为高电位

    EscapeCommFunction( hComm, SETDTR );

    spDTR->Brush->Color=clRed;

    //更改信号灯的颜色

    }

    DTRState

    =~DTRState; //将DTRState转态

    }

    //------------------------------------------------------------------

    //------------------------------------------------------------------

    void __fastcall TForm1::BitBtn2Click(TObject *Sender)

    {

    //若通信端口未打开,则不作动作,并跳出

    if

    (hComm==0)

    {

    MessageBox (0, "通信端口未打开!!!","Open Error",MB_OK);

    return;

    }

    //判断RTSState值,输出状态后,将原值作转态

    if

    (RTSState)

    {

    //输出RTS状态为低电位

    EscapeCommFunction( hComm, CLRRTS );

    spRTS->Brush->Color=clWhite;

    //更改信号灯的颜色

    }

    else

    {

    //输出RTS的状态为高电位

    EscapeCommFunction( hComm, SETRTS );

    spRTS->Brush->Color=clRed;

    //更改信号灯的颜色

    }

    RTSState

    =~RTSState; //将RTSState转态

    }

    //------------------------------------------------------------------

    使用中一定要注意自已电脑中正在连接的串口号是多少?不是从远端电脑去查看本机连接的端口号.

    在进行手动蓝牙串口连接时,如果都开起串口服务,那么从哪一方发起连接都可以,不同之处是端口号不同而已.

    主动方使用的串口号为远机中的串口号,被动方为本地机中串口号.

    如,我在EeePC上连接yilingPC上的串口.如下图.

    上图显示了在EeePC上显示的远端yilingPC上的开起的所有服务,可见开起了四个串口,分别是5.6.8,9

    下图显示了在yilingPC上查看的本地开起的服务,可邮开起的四个串口号为5,6,7,10.

    串口号不同的原因是因为,在不同电脑上的资源的编号并不相同.

    从上两个图,还可以看出,我从EeePC上打开(连接)yilingPC上的9号串口,则在yilingPC上查看,被打开的串口号是10号串口.

    因此,这个连接,在EeePC上应该打开9号串号,在yilingPC上打开10号串口.

    ---

    下图EeePC上的.

    下图yilingPC上.

    ---------------------------------------------------

    上面主要说串口号及电平检测问题.

    下面进行串口字符通信:

    程序中串口打开方式类似:

    这个程序中采用我多线程的方法,开辟一个新的线程来读取数据:

    线程头文件:

    //---------------------------------------------------------------------------

    #ifndef

    Unit2H

    #define Unit2H

    //---------------------------------------------------------------------------

    #include

    //---------------------------------------------------------------------------

    class TReadThread : public TThread

    {

    private:

    void __fastcall

    TReadThread::ReadData();

    protected:

    void __fastcall Execute();

    public:

    __fastcall TReadThread(bool CreateSuspended);

    };

    //---------------------------------------------------------------------------

    #endif

    线程单元文件:

    //---------------------------------------------------------------------------

    #include

    #pragma

    hdrstop

    #include

    "Unit2.h"

    #include "Unit1.h"

    #pragma package(smart_init)

    extern HANDLE hComm;

    //---------------------------------------------------------------------------

    // Important: Methods and properties of objects in VCL can only

    be

    // used in a method called

    using Synchronize, for example:

    //

    // Synchronize(UpdateCaption);

    //

    // where UpdateCaption could

    look like:

    //

    // void __fastcall Unit2::UpdateCaption()

    // {

    // Form1->Caption = "Updated in a thread";

    // }

    //---------------------------------------------------------------------------

    __fastcall

    TReadThread::TReadThread(bool CreateSuspended)

    : TThread(CreateSuspended)

    {

    }

    //---------------------------------------------------------------------------

    void __fastcall TReadThread::Execute()

    {

    //---- Place thread code here ----

    while (!

    Terminated)

    Synchronize(ReadData); }

    //---------------------------------------------------------------------------

    void __fastcall

    TReadThread::ReadData()

    {

    String Temp;

    char inbuff[1024];

    DWORD nBytesRead, dwEvent, dwError;

    COMSTAT cs;

    if (hComm ==

    INVALID_HANDLE_VALUE) return;

    //

    取得状态

    ClearCommError(hComm,&dwError,&cs);

    // 数据是否大于我们所准备的Buffer

    if (cs.cbInQue

    > sizeof(inbuff))

    {

    PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 数据

    return;

    }

    ReadFile(hComm,

    inbuff,cs.cbInQue,&nBytesRead,NULL); // 接收COM

    的数据

    // 转移数据到变量中

    inbuff[cs.cbInQue]=

    '\0';

    // 将数据显示在Memo1上

    Form1->mReceive->Text =

    Form1->mReceive->Text +

    inbuff;

    }

    主窗口单元文件:

    //---------------------------------------------------------------------------

    #include

    #pragma

    hdrstop

    #include

    "Unit1.h"

    #include "Unit2.h"

    //---------------------------------------------------------------------------

    #pragma package(smart_init)

    #pragma resource "*.dfm"

    TForm1 *Form1;

    HANDLE hComm; // 将给串行端口使用的Handle声明

    //---------------------------------------------------------------------------

    __fastcall TForm1::TForm1(TComponent* Owner)

    : TForm(Owner)

    {

    }

    //---------------------------------------------------------------------------

    void __fastcall

    TForm1::Button1Click(TObject *Sender)

    {

    char *ComNo;

    DCB dcb;

    String Temp;

    // 取得要打开的通信端口

    if(rdCOM->ItemIndex +1>9)

    Temp = "\\\\.\\COM"+IntToStr(rdCOM->ItemIndex

    +1);

    else

    Temp = "COM"+IntToStr(rdCOM->ItemIndex +1);

    // 转换到指针类型的Char

    ComNo = Temp.c_str();

    hComm = CreateFile(ComNo,GENERIC_READ | GENERIC_WRITE,

    0, NULL, OPEN_EXISTING, 0, 0);

    if (hComm == INVALID_HANDLE_VALUE) // 如果COM未打开

    {

    MessageBox(0, "打开通信端口错误!!","Comm Error",MB_OK);

    return;

    }

    // 将dcb地址传入,以取得通信参数

    GetCommState(hComm,&dcb); // 得知目前COM的状态

    dcb.BaudRate =

    CBR_9600; // 设置波特率为9600

    dcb.ByteSize =

    8; // 字节为8 bit

    dcb.Parity =

    NOPARITY; // Parity 为 None

    dcb.StopBits =

    ONESTOPBIT; // 1个Stop bit

    // 通信端口设置

    if (!SetCommState(hComm, &dcb))

    { // 设置COM的状态

    MessageBox

    (0, "通信端口设置错误!!!","Set Error",MB_OK);

    CloseHandle(hComm);

    return;

    }

    Read232->Resume();

    }

    //---------------------------------------------------------------------------

    void __fastcall

    TForm1::mSendKeyPress(TObject *Sender, char

    &Key)

    {

    String Temp;

    char *SendData;

    int ln;

    unsigned long lrc,BS;

    if (Key!=13) return;

    if (hComm==0) return; // 检查Handle值

    Temp = mSend->Text;// 取得传送的字符串

    SendData = Temp.c_str(); // 字符串转换

    // 取得传送的字符串长度

    BS = Temp.Length();

    //BS = StrLen(SendData); // 也可以使用此种方式取得字符串长度

    // 实际的传送动作

    WriteFile(hComm,SendData,BS, &lrc,NULL); //

    送出数据

    }

    //---------------------------------------------------------------------------

    void __fastcall

    TForm1::FormCreate(TObject *Sender)

    {

    Read232 = new TReadThread(true);

    Read232->FreeOnTerminate = true;

    //Terminated时自行摧毁 }

    //---------------------------------------------------------------------------

    void __fastcall

    TForm1::Button2Click(TObject *Sender)

    {

    Read232->Terminate();

    if (hComm!=INVALID_HANDLE_VALUE) CloseHandle(hComm);

    exit(EXIT_SUCCESS);

    }

    //---------------------------------------------------------------------------

    下图是EeePC

    下图是yilingPC

    到此结束!谢谢,请指正.

    展开全文
  • 蓝牙虚拟串口传入端口和传出端口

    千次阅读 2018-12-07 10:23:16
     是Windows主动向串口蓝牙适配器发起连接时所使用的虚拟串口号 传入COM端口  是串口蓝牙适配器主动向Windows发起连接时所使用的虚拟串口号。 就是选择电脑蓝牙的主从模式. 用电脑上的蓝牙连接其他蓝牙适配器从...
  • Thinkpad T550 蓝牙虚拟串口服务失败

    千次阅读 2015-12-31 11:07:56
    上位机软件与下位机程序通过串口通信,上位机是windows7 64位系统,因为windows通信协议栈存在蓝牙地址族,通过 RFCOMM 仿真串口通信,部分代码如下: SOCKADDR_BTH SockAddrBthServer= RemoteBthAddr; ...
  • 如何进行win8的蓝牙虚拟串口设置

    千次阅读 2015-01-11 18:23:39
    本文介绍的是不通过第三方软件进行蓝牙虚拟串口的设置和配对,其实笔者也尝试了使用千月的蓝牙软件,但是使用体验不是很好。 电脑蓝牙和设备之间的配对在这里就不做介绍了,我们假设已经完成了蓝牙的配对。 首先打开...
  • 蓝牙模块与pc的内置蓝牙连接成功后,可以用该软件为蓝牙设备虚拟出一个串口号,便于使用串口助手与蓝牙模块通信
  • 蓝牙虚拟串口操作

    千次阅读 2013-09-02 13:51:26
    转载原文地址:... 首先必须要几个文件:btdrt.dll,bthutil.dll,InTheHand.Net.Personal.dll,cecontrollib.dll;将,InTheHand.Net.Personal.dll文件添加到引用 蓝牙基本操作:搜索-连接-发送-接收 主要
  • 使用C#编写的windows CE蓝牙串口控制蓝牙设备发送接收数据。
  • 该源代码通过BluetoothAPIs.h扫描本地和远程蓝牙设备并发送配对请求,完成配对,通过增加串口服务开启虚拟串口,然后通过SerialPort进行串口通信,该代码在vs2008环境中运行成功
  • Compact Framework下的Bluetooth开发 之 Windows Embedded Source Tools for Bluetooth  .NET Compact Framework下的Bluetooth开发 之 32feet.NET  在这篇文章讲述Bluetooth Virtual Serial Port的开发,所谓...
  • 在之前的两篇文章分别讲述了在.NET Compact Framework下使用Windows Embedded Source Tools for Bluetooth和32feet.NET进行Bluetooth的开发,链接如下:.NET Compact Framework下的Bluetooth开发 之 Windows ...
  • 摘要:蓝牙通信平台在嵌入式系统的实现过程中,OBEX(对象交换)始终是很重要的一部分,基于OBEX的蓝牙文件传输得到...由于OBEX上的文件传输应用建立在RFCOMM实现的蓝牙仿真串口上,本文介绍OBEX文件传输的蓝牙虚拟串口
  • win7电脑虚拟蓝牙串口

    2018-08-18 20:52:01
    这份文档介绍了win7系统利用自带的蓝牙串口与外界蓝牙进行通信调试的方法
  • 双笔记本自带蓝牙串口通讯

    千次阅读 2019-12-12 14:43:07
    因此,对于都有蓝牙模块的电脑,可以通过将蓝牙虚拟串口,进行双机通讯。对于Electron的串口应用,蓝牙串口也是一种可选方式。 Window系统对蓝牙协议版本的支持 对于蓝牙模块之间的互连,如果支持的协议不兼容,是...
  • 而OBEX的实现是基于蓝牙仿真接口,所以蓝牙串口驱动程序的实现就有了很重要的意义。介绍了Windows CE下串口驱动程序的结构和一种具体的实现方法。 关键词:蓝牙 OBEX 嵌入式系统 驱动程序Windows CE作为一种...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,011
精华内容 404
关键字:

windows蓝牙虚拟串口