我爱builder

C++Builder 程序员博客

只需要接收数据这个功能就可以,接收的数据来自适配器里

C++Builder与RS-232串行通信控制

void __fastcall TForm1::MSComm1Comm(TObject *Sender)
{
        //AnsiString str;
        OleVariant s;
        if(MSComm1->CommEvent==comEvReceive)
       
        if(MSComm1->InBufferCount)
        {
                s=MSComm1->Input;
                strComBuffer= strComBuffer + s.AsType(varString);
                for (int i = 0; i < s.ArrayHighBound(1); i++)
                {
                        strComBuff[m_iComBuff_Len++] = s.GetElement(i);
                }
        }
}

}

                MSComm1->CommPort=PortNum;
                MSComm1->Settings="9600,n,8,1";
                MSComm1->InputMode=0;
                MSComm1->PortOpen=true;
串口设置

搜一搜,MSCOMM32的文章多的很
它的麻烦就是模式1用变体,模式0是文本,用WideString简单

进一步解释下怎么样?

我可以给个例子

==

邮箱时什么?

  • Filed under: C++ Builder
  • 如串口调试助手,在输入框中输入字节数据,如:FF   02   33   28   FA   AD,然后以十六进制将其发出,输入框无输入量限制。如何实现?请写出尽量完整的代码,谢!!!由于家境贫寒,所以是以才会友,送上1分,意思意思。请见谅!!!

    极度感谢i_love_pc(杰子)同志对本帖的大力支持。我已经找到办法了。谢谢!

    呵呵。。。昨天忘了和大家共享代码了:)
    如下:
              String   buf;
              byte   bytebuf[20];
              buf   =   Edit1-> Text;
              for   (int   i   =   1;   i   <=   buf.Length();   i++)
                      if   (buf.SubString(i,1)   ==   "   ")
                      {
                            buf.Delete(i,1);
                            i–;
                      }

              for   (int   i   =   0;   i   <   buf.Length()/2;   i++)
                      Memo1-> Lines-> Add(StrToInt( "0x "   +   buf.SubString(i*2+1,2)));
    大致就是这样了。感谢大家的关注!

    LZ太有才了!

    呵呵。。。
    请多指教:)

    不错,谢谢!

  • Filed under: C++ Builder
  • 俺弄个程序把接收到的数据放到RichEdit上(动态接收,一收到数据就放在RichEdi上),
    发现RichEdit存放一定数据后,后来接收的数据就乱套了,Memo就没有这样的问题,这
    是怎么回事,就连那个很有名的软件—串口调试助手V2.2 也有类似的问题。

    哪位能人指点一下是什么原因造成的吗?

    不知道你怎么做的

    以前我也遇到过,你看你是不是变量的size设置大点,试试

    以前我的问题是因为接收数据的位数超过变量的最大限,看看是不是同样的原因引起的

    接收缓冲够大了,

    后来乱是把该一行的数字攫断成几行。

    接收到的数据数目是对的,反而Memo自己有时候也把 [效验和] 和回车换行去掉了,造成该换行的时候不换行,
    接收的字节数量是对。这想不明白。

    具体问题说清楚下,也许我能替你解答

    如本来应该这样显示的(-代表任何英文字母;?为效验和(值1到255之间); \n表示回车换行):
    ————————–?\n                //
    ————————–?\n
    ————————–?\n
    ————————–?\n
    ……………………….            //后面的类似

    /////////////////////////////////////////////////////

    Memo(设置为长度过长会自动换行的)接收有时候显示为:

    —————————————————-?\n
    —————————————————-?\n ——–
    ——————?\n
    ————————–?\n
    ————————–?\n
    —————————————————-?\n———–
    —————?\n————————–?\n    ///很明显某行的效验和、回车换行被省略掉了。       
    ————————–?\n                     
    ————————–?\n 
    ……………………….                //后面的类似

    RichEdit更离谱:
    ————————–?\n                //
    ————————–?\n
    ————————–?\n
    ————————–?\n
    ………………………..              //一百多行后变为
    ——–
    ———–
    ——-?\n
    ——–
    ———–
    ——-?\n
    ———
    ———
    ——–?\n                              //很明显把一行截取三行了。
    ……………………….              //后面的类似

    RichEdit里面的内容不是纯文字,里面带格式的,把RichEdit里面的内容当二进制文件传输就没问题了。

    俺弄个程序把接收到的数据放到RichEdit上(动态接收,一收到数据就放在RichEdi上),
    发现RichEdit存放一定数据后,后来接收的数据就乱套了,Memo就没有这样的问题,这
    是怎么回事,就连那个很有名的软件—串口调试助手V2.2 也有类似的问题。

    哪位能人指点一下是什么原因造成的吗?

    你的意思是不是说只有接受少量数据时才正常,接受多了就不乱是不是这样?

    说明你收的的数据中夹杂着二进制数据(非显示字符或空格),
    如果应该没有,说明你的通讯线路可能有不稳定的地方,
    不要怀疑这些用了很久的东西,找自己的原因

    引用 10 楼 xiaocha 的回复:
    说明你收的的数据中夹杂着二进制数据(非显示字符或空格),
    如果应该没有,说明你的通讯线路可能有不稳定的地方,
    不要怀疑这些用了很久的东西,找自己的原因

    接收的数据是从其他设备送上来的,当然是二进制数据,而且每个字节有可能是0×00–0xFF的任何,
    我想就算是非显示字符,Memo或RichEdit都不要自作主张把它删除了,然后我可以把这些非显示字符翻译
    成对应的16进制。

    不对,Memo或RichEdit是文本窗口,不能显示非显示字符(除了少量,TAB等),遇到了这些字符不会显示,
    另外他们还有一个按单词分割换行的功能,非显示字符被认为是单词分割符,造成行显示不正确。
    你可以用 Notepad 打开一个二进制文件看看,就明白了。

  • Filed under: C++ Builder
  • 这是一个串口通讯的程序(网上下的),可是我不知道她从串口接受的数据方在哪里的?我要想串口写数据,该怎么写?请哪位大侠帮一下小弟。说的越详细越好!!!非常感谢了。急急急啊!!!!!!
    #include <windows.h> 
    #include <stdio.h> 
    #include <iostream> 
    using namespace std;
    #include <stdlib.h> 
    #include <fstream>
    using namespace std;
    #include <io.h> 
    #include <string.h>   
    #include <process.h>

    HANDLE  hCom  ;  //  准备打开的串口的句柄 
    HANDLE      hCommWatchThread  ;  //辅助线程的全局函数 

    LRESULT  CALLBACK  WndProc(HWND,UINT,WPARAM,LPARAM); 

    UINT  CommWatchProc(HWND  hSendWnd) 

    DWORD  dwEvtMask=0  ; 
    COMSTAT  ComStat  ; 
    DWORD  dwErrorFlags,dwLength,dwError;   
    BOOL  fReadStat = FALSE; 
    LPSTR  lpBuffer = NULL;   
       
    SetCommMask(  hCom,  EV_RXCHAR &brvbarEV_TXEMPTY  );//有哪些串口事件需要监视? 
    WaitCommEvent(  hCom,  &dwEvtMask,  NULL  );//  等待串口通信事件的发生 
    //检测返回的dwEvtMask,知道发生了什么串口事件 
    if  ((dwEvtMask  &  EV_RXCHAR)  ==  EV_RXCHAR)  //  缓冲区中有数据到达 

    ClearCommError(hCom,  &dwErrorFlags,  &ComStat  )  ; 
    dwLength  =  ComStat.cbInQue  ;  //输入缓冲区有多少数据? 
    if  (dwLength  >  0) 

    fReadStat  =  ReadFile(hCom,  lpBuffer,  dwLength,  &dwLength  ,NULL);  //读数据 
    if  (!fReadStat) 

    if  (GetLastError()  ==  ERROR_IO_PENDING) 

    while(!GetOverlappedResult(hCom,NULL,  &  dwLength,  TRUE))   

    dwError  =  GetLastError(); 
    if(dwError  ==  ERROR_IO_INCOMPLETE)  continue; 


    }
      //::PostMessage((HWND)hSendWnd,WM_NOTIFYPROCESS,0,0);//通知主线程,串口收到数据 


    }
    return  0; 

    int    SerialInit(  )  ;      //串口初始化 

    int  WINAPI  WinMain(HINSTANCE  hInstance,HINSTANCE  hPrevInstance, 
      LPSTR  lpCmdLine,int  nCmdShow) 

    static  TCHAR  szAppName[]=TEXT("HelloWorld"); 
    static  TCHAR  szClassName[]=TEXT("HelloWorldClass"); 
    HWND  hwnd; 
    MSG  msg; 
    WNDCLASS  wndclass; 
    unsigned  long  *  p=NULL; 
       
    wndclass.style  =  CS_HREDRAW  &brvbar  CS_VREDRAW; 
    wndclass.lpfnWndProc  =  WndProc; 
    wndclass.cbClsExtra  =  0; 
    wndclass.cbWndExtra  =  0; 
    wndclass.hInstance  =  hInstance; 
    wndclass.hIcon  =  LoadIcon(NULL,IDI_APPLICATION); 
    wndclass.hCursor  =  LoadCursor(NULL,IDC_ARROW); 
    wndclass.hbrBackground  =  (HBRUSH)GetStockObject(WHITE_BRUSH); 
    wndclass.lpszMenuName  =  NULL; 
    wndclass.lpszClassName  =  szClassName; 

      if(!RegisterClass(&wndclass)) 

    MessageBox(NULL,TEXT("This  program  requires  Windows  NT  !"), 
    "szAppName",MB_ICONERROR); 
    return  0; 

       
    hwnd  =  CreateWindow(szClassName, 
    TEXT("My  Input  Program"), 
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    NULL, 
    NULL, 
    hInstance, 
    NULL  ); 
    ShowWindow(hwnd,nCmdShow); 
    UpdateWindow(hwnd); 
       
    SerialInit(  );//串口初始化 

    //*****************开辟新线程******************************************** 
    hCommWatchThread=CreateThread((LPSECURITY_ATTRIBUTES)  NULL,//安全属性 
    0,  //初始化线程栈大小,却省为与主线程大小相同 
            (LPTHREAD_START_ROUTINE)CommWatchProc,  //线程的全局函数 
            NULL,  //此处传入了主框架的句柄 
            0,p); 
    //*****************开辟新线程******************************************** 
       
    while(GetMessage(&msg,NULL,0,0)) 

    TranslateMessage(&msg); 
    DispatchMessage(&msg); 

    return  msg.wParam; 

    int    SerialInit(  )    //初始化串口 

    //      DWORD  dwError; 
    DCB  dcb; 
    COMMTIMEOUTS  to; 
    BOOL  fSuccess; 
    //**************************打开串口*************************** 
    hCom  =  CreateFile("COM1",  GENERIC_READ  &brvbar  GENERIC_WRITE,  0, 
    NULL,  OPEN_EXISTING,  FILE_FLAG_OVERLAPPED,  NULL); 
    if  (hCom  ==  INVALID_HANDLE_VALUE)   

    MessageBox(NULL,TEXT("打开串口错误!"), 
    "ok",MB_ICONERROR); 

       
    //***************************打开串口**************************** 
       
       
    //***************************配置串口****************************   
    GetCommState(hCom,&dcb); 
    dcb.BaudRate  =  9600;  //波特率为9600 
    dcb.ByteSize  =  8;  //数据位数为8位 
    dcb.Parity  =  NOPARITY;  //无校验 
    dcb.StopBits  =  ONESTOPBIT;  //一个停止位 
    dcb.fBinary  =  FALSE; 
        if(!SetCommState(hCom,&dcb)) 

    MessageBox(NULL,  TEXT("设置错误"),  "OK",  MB_ICONERROR); 

       
    SetupComm(hCom,  1024,  1024); 
    //PurgeComm(hCom,  PURGE_TXCLEAR); 
    PurgeComm(  hCom,  PURGE_TXABORT  &brvbar  PURGE_RXABORT  &brvbar  PURGE_TXCLEAR  &brvbar  PURGE_RXCLEAR  );  //清干净输入、输出缓冲区 
    //***************************配置串口****************************   
       
       
        //******************将串口读操作的超时设定为10  毫秒************** 
    memset(&to,  0,  sizeof(to)); 
    to.ReadIntervalTimeout  =  10000; 
    SetCommTimeouts(hCom,  &to); 
    //******************将串口读操作的超时设定为10  毫秒************** 
       
       
    //******************设置事件掩模来监视指定通信端口上的事件(监视串口的错误和接收到字符两种事件)********       
    fSuccess=SetCommMask(hCom,  EV_RXCHAR &brvbarEV_TXEMPTY  );//设置事件驱动的类型 
    if  (!fSuccess)   

    MessageBox(NULL,  TEXT("SetCommMask  错误"),  "OK",  MB_ICONERROR); 

    //******************设置事件掩模来监视指定通信端口上的事件(监视串口的错误和接收到字符两种事件)******** 

       
    return  0; 
       

    LRESULT  CALLBACK  WndProc(HWND  hwnd,UINT  message,WPARAM  wParam, 
    LPARAM  lParam) 

    HDC  hdc; 
    PAINTSTRUCT  ps; 
    RECT  rect; 
    char  temp[128]; 
       
    switch(message) 

    case  WM_CREATE: 

    return  0; 

    //获取键盘输入 
    case  WM_KEYDOWN: 
    switch(wParam) 

    //按Esc键推出 
    case  VK_ESCAPE: 
    PostQuitMessage(0); 
    return  0; 

    //其余按键发声 
    MessageBeep(MB_OK); 
    return  0; 

    //按下鼠标左键发声 
    case  WM_LBUTTONDOWN: 
    MessageBeep(MB_OK);
    return  0; 

    //按下鼠标右键退出 
    case  WM_RBUTTONDOWN: 
    PostQuitMessage(0); 
    return  0; 

    //鼠标位置改变,显示坐标 
    case  WM_MOUSEMOVE: 
    hdc  =  GetDC(hwnd); 
    sprintf(temp,"x:  %d  ,  y:  %d",LOWORD(lParam),HIWORD(lParam)); 
    TextOut(hdc,10,10,temp,strlen(temp)); 
    ReleaseDC(hwnd,hdc); 
    return  0; 

    case  WM_PAINT: 
    hdc=BeginPaint(hwnd,&ps); 
    GetClientRect(hwnd,&rect); 
    EndPaint(hwnd,&ps); 
    return  0; 
    case  WM_DESTROY: 
    PostQuitMessage(0); 
    return  0; 

       
    return  DefWindowProc(hwnd,message,wParam,lParam); 

    我给你个例子,你自己看看

    发过去了

    非常感谢,还有哪些大哥能帮我啊?请快点吧。。
    小弟非常着急啊。。。

    请哪位帮我分析一下这个程序。。。
    不胜感激!!!

    怎么没有人说话呢????

  • Filed under: C++ Builder
  • 我用MSCOMM控件做一个串口通讯程序,发送没问题,接收的时候,我是想把接收到的16进制数据转换成字符形式,并在文本框里显示,下位机发上来的数据是发送的字符的ASCII码值,最后一个是"!",上位机给下位机发送的查询命令不同,下位机每次返回来的数据字节数也不同,但是每次最后都会有一个"!",做为结束标志,我“!”作为结束判断标志,但我程序也未能实现,另外一个就是当我发送一个数据后,关闭窗体,却提示如下错误:“Project Project1.exe raised exception class EAccessViolation with message 'Accessviolation at address 0041A55B.Read of address 0000034'.Process stopped.Use Step or Run to continue.”错误,请问这是什么错误啦?我该怎么写程序去判断那个“!”符号啦?
    我的串口接收程序如下:
    void __fastcall TForm1::Uart_RecevieByte(TObject *Sender)
    {

            OleVariant  RxBuff;
            unsigned int ByteNum;
            switch (MSComm1->CommEvent)
            {

                    case comEvReceive:
                    {

                            if(MSComm1->InBufferCount>0)
                            {
                                    RxBuff=MSComm1->Input;//如果缓冲区中有多于一个字节的数据
                            }
                            ByteNum=RxBuff.ArrayHighBound(1);//将实际读的字节数取出

                            for(int i=0;i <=ByteNum;i++)
                            {
                                    ReBuff[BuffPtr++] = RxBuff.GetElement(i);//将接收数据读入自己的缓冲区
                            }
                            //if(UpCase(ReBuff[BuffPtr-1])=='!')
                            if(BuffPtr == 17)
                            {
                                    for(int i=0;i <BuffPtr;i++)
                                    {
                                            Edit1->Text +=char(ReBuff[i]);
                                    }
                                    BuffPtr=0;
                                    MSComm1->InBufferCount=0;
                                    //success = true;
                                    //Beep();
                            }

                    }

            }
    }
    如果我把这段接收程序屏蔽掉,关闭窗口的时候就不提示以上错误,请问我这程序该如何实现比较好?

  • Filed under: C++ Builder
  • 大虾们:
          问题是这样的,我用的仪表采集到数据显示后有RS485通讯接口,我把这几个仪表的485口串接
    起来,然后用一个485转232接头接到PC机上。仪表是采用ModBus协议:从站地址 功能代码 数据区 CRC16 
          我用API函数写的串口打开和发送数据的命令,但是不知道如何控制他们显示在软件上呢?
    我写的串口接受程序和硬件连也显示不出来ⷂ𗂷ⷂ𗠼br>     求助啊~~~~~~~~~~~~~

  • Filed under: C++ Builder
  •     通讯协议包括头文件(Soh)  地址码(Addr)  数据块长(Len) 数据块(Data) 检验和(Checksum) 尾块(LF)
        其中Checksum为从Addr开始到数据快捷素所有字节之和(即字符的ASC码之和),取14位(最高2为丢弃),分高、低两个7bit字节,将bit8置1.低字节在前,高字节在后。
        例如 ,从Addr开始到数据块结束所有字节之和为32341(7E55H),则对其2 位最高位后为3E55H,氛围两个7字节7CH和55H,最高位置1后为FCH和D5H,所以检验和为D5H,FCH(低字节在前)。
        请问这个检验和的计算如何实现?

    BYTE Data[8];
    WORD wCheckSum;
    BYTE b1,b2;

    wCheckSum = 0;
    for ( int i = 0; i < 8; i++ )
    {
        wCheckSum += Data[i];
    }

    wCheckSum &= 0×3FFF;                // 去掉最高的两位

    b1 = (BYTE)wCheckSum;            // 低字节
    b1 &brvbar= 0×80;      // 将最高位置1

    b2 = (BYTE)((wCheckSum >> 7);    // 高字节
    b2 = &brvbar= 0×80;    // 将最高位置1

    wCheckSum = ((WORD)b1) < < 8;
    wCheckSum &brvbar= b2;                  // 最后的校验值

    写的非常清楚,很是感谢。
    我还想问下,发送到串口缓冲区的数据是十六进制的形式,我想吧接受到的数据在解析以前先在Memo控件里显示,请问这个格式应该怎么样转化呢?
    谢谢!
    答者必有分!

  • Filed under: C++ Builder
  •       关于串口用C++ builder 编程,请问RS232 与RS485 软件编程上有否区别?如果一端为232,另一端为485,能否实现通讯?是不是要加一个硬件转换的玩意?RS232可以用MSCOMM32控件编程,RS485可以用吗?

    rs-232-485转换器,有卖的。

    RS485可以使用 Victor串口VCL控件 第三方控件

    http://www.ccrun.com/view.asp?id=157

    232和485只是电气特性不同而已,编程是一样的

    232和485之间需要一个转换,市面上有转换器,很便宜的

    引用 4 楼 cptang 的回复:
    232和485只是电气特性不同而已,编程是一样的

    232和485之间需要一个转换,市面上有转换器,很便宜的

    232 跟 485编程是有区别的,485 需要改变 RTS 值控制读或者写状态
    但是如果是从 232 出来通过 232-485 转换器的话,转换器会自动控制,不用编程管理 232 端口

    工业级的 485 转换器要 200 多 RMB的

    顶顶。

    个人推荐,控件用SPComm,比MSComm好用。至于485和232的问题,PC的程序只与232接口,所以跟232下面是否转的485没有关系。

    自己弄个也很快.

        要用串口想某设备写入所谓的两字节ASCII命令,是否直接向其写入两字节字符串即可?因为字符串在算机中就是以ASCII码存放的,这样理解是否正确?请高手们指点迷津。

  • Filed under: C++ Builder
  •   向串口发送一个字符串a,
      Rd_232是串口句柄
      nNumberOfBytesToWrite=a.Length();
      程序执行WriteFile(Rd_232,&a,nNumberOfBytesToWrite,&lpNumberOfBytesWrite,NULL);
      结果:lpNumberOfBytesWrite 和 nNumberOfBytesToWrite 不一致,
      比方说:向串口发送了100个字符,可函数WriteFile实际发送了99个
     
      我试过清空串口输入、输出缓冲区,可没用。各位大虾,怎么解决?

    查你的SetCommState参数,可能是参数设置的问题

    怎么知道是哪些字符没有发送?

    应该是: nNumberOfBytesToWrite=a.Length()+1; 因为对于字符串来说实际长度是和字符数组长度不一样的,串比数组长度多一个字符长度,即'\0',实际串口发送是一个一个字符发送,它会认为最后一个字符是'\0',而不发送最后一个字符。

    nNumberOfBytesToWrite=a.c_str();//这是发送字符串,a.Length()发的是a字符串的字节数,结果肯定不一样了。

  • Filed under: C++ Builder
  • 我同学要从单片机通过串口,传输数据给电脑,我如何利用BCB做个软件,接收那些数据

    http://www.ccrun.com
    这个网站有victor下载的,感觉还不错!

    我想在BCB上实现。。。又这类函数么

    用MSCOMM控件,再加个定时器,每100MS读一次串中就行 了,很稳定,百试不爽!

    引用 2 楼 52vc 的回复:
    http://www.ccrun.com
    这个网站有victor下载的,感觉还不错!

    自己写太麻烦,用控件好

  • Filed under: C++ Builder
  • 类别

    最新

    标签

    链接


    存档