Giao tiếp RS232 sử dụng lớp Serial

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • Kel'Thuzads
    Thành viên chính thức
    • Dec 2006
    • 85

    #1

    Giao tiếp RS232 sử dụng lớp Serial

    Như em thấy trong diễn đàn, việc giao tiếp với PC qua cổng COM mọi người chỉ giới thiệu về lớp MSCOM32 hoặc sử dụng thư viện động Port.dll. Liệu có cách khác không. Vừa rồi may mắn em được biết, ngoài hai PA đó ra thì người ta còn sử dụng lớp Serial . Thấy họ giới thiệu là nó rất ổn định, khá hay. Nó viết hoàn toàn bằng C/C++, có thể sử dụng trong các phần mềm như VC++, hay Cbuilder6.....Nó truyền nhận theo từng BYTE, và đặc biệt là có thể truyền được byte 0 như truyền dữ liệu bình thường (trong khi đó ở VC++ rất khó thực hiện với lớp MSCOM). Em thấy hay quá. Liệu bác nào đã làm phần này rồi có thể post lên cho anh em cùng học hỏi không, hoặc có chỗ nào trong diễn đàn có bàn về phần này rồi chỉ cho em với, hay có tài liệu gì về phần này cũng được.
    Cảm ơn các bác nhiều.
    Kel'Thuzads
    Mail:minhnguyen.ac@gmail.com
  • riquelme
    Thành viên mới
    • Feb 2007
    • 6

    #2
    Mình nhớ không nhầm thì đã có code mẫu của chương trình rồi mà. Đọc cái đó cũng hiểu được, trước đây mình cũng thử viết chương trình dùng lớp này, nhưng nó phải quét đầu vào liên tục. Có vẻ không được tiện lắm.
    |

    Comment

    • Kel'Thuzads
      Thành viên chính thức
      • Dec 2006
      • 85

      #3
      Vậy à. Thế bác có các file Serial.h và Serial.cpp ko. Up cho em xin được không. Em chưa làm bao giờ lại không có các file mã nguồn của lớp này nên cũng đành chịu. Mà nếu bác đã làm về phần này rồi có thể cho em xin đoạn code mẫu được không? Nếu ko up đc làm ơn gửi vào mail giúp em.
      Cảm ơn bác.
      Kel'Thuzads
      Mail:minhnguyen.ac@gmail.com

      Comment

      • ngohaibac
        Moderator
        • Sep 2005
        • 600

        #4
        Không biết có phải là lớp CSerial không nhỉ. Bạn download cái này xem:Lớp CSerial

        Tuy nhiên sử dụng để truyền thì đơn giản còn để nhận dữ liệu là một vấn đề đó, cẩn thận treo máy nhé.

        Để nhận dữ liệu theo ngắt thì bạn phải dùng multithread mới ổn đó.

        Chúc bạn thành công.
        Technical sale at WT Microelectronics S'pore
        Hỗ trợ dự án sử dụng các hãng Texas Instrument, STMicro, Freescale, Fairchild, International Rectifier, Ublox, Lumiled, Maxim
        Liên hệ: 0915.560.511 hoặc ngo.haibac@wtmec.com

        Comment

        • riquelme
          Thành viên mới
          • Feb 2007
          • 6

          #5
          Bác Bắc làm 1 bài về đa luồng đi. Em nghe nói rồi nhưng chưa biết thế nào cả.
          |

          Comment

          • Kel'Thuzads
            Thành viên chính thức
            • Dec 2006
            • 85

            #6
            Ban Bắc có code mẫu về phần này không. Post lên cho anh em học hỏi với. A mà mình xin đc lớp serial này rồi, không biết có giống với lớp cserial của bạn Bắc ko.
            Kel'Thuzads
            Mail:minhnguyen.ac@gmail.com

            Comment

            • Kel'Thuzads
              Thành viên chính thức
              • Dec 2006
              • 85

              #7
              Oh, sao không tải được nhỉ. củ chuối quá. Không biết paste vào có dài quá không.

              // Serial.h

              #ifndef __SERIAL_H__
              #define __SERIAL_H__

              #define FC_DTRDSR 0x01
              #define FC_RTSCTS 0x02
              #define FC_XONXOFF 0x04
              #define ASCII_BEL 0x07
              #define ASCII_BS 0x08
              #define ASCII_LF 0x0A
              #define ASCII_CR 0x0D
              #define ASCII_XON 0x11
              #define ASCII_XOFF 0x13

              class CSerial
              {

              public:
              CSerial();
              ~CSerial();

              BOOL Open( int nPort = 2, int nBaud = 9600 );
              BOOL Close( void );

              int ReadData( void *, int );
              int SendData( const char *, int );
              int ReadDataWaiting( void );

              BOOL IsOpened( void ){ return( m_bOpened ); }

              protected:
              BOOL WriteCommByte( unsigned char );

              HANDLE m_hIDComDev;
              OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
              BOOL m_bOpened;

              };

              #endif

              //===========================================
              Kel'Thuzads
              Mail:minhnguyen.ac@gmail.com

              Comment

              • Kel'Thuzads
                Thành viên chính thức
                • Dec 2006
                • 85

                #8
                // Serial.cpp

                #include "stdafx.h"
                #include "Serial.h"

                CSerial::CSerial()
                {

                memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
                memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
                m_hIDComDev = NULL;
                m_bOpened = FALSE;

                }

                CSerial::~CSerial()
                {

                Close();

                }

                BOOL CSerial::Open( int nPort, int nBaud )
                {

                if( m_bOpened ) return( TRUE );

                char szPort[15];
                char szComParams[50];
                DCB dcb;

                wsprintf( szPort, "COM%d", nPort );
                m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
                if( m_hIDComDev == NULL ) return( FALSE );

                memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
                memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

                COMMTIMEOUTS CommTimeOuts;
                CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
                CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
                CommTimeOuts.ReadTotalTimeoutConstant = 0;
                CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
                CommTimeOuts.WriteTotalTimeoutConstant = 5000;
                SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

                wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );

                m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
                m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

                dcb.DCBlength = sizeof( DCB );
                GetCommState( m_hIDComDev, &dcb );
                dcb.BaudRate = nBaud;
                dcb.ByteSize = 8;
                unsigned char ucSet;
                ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
                ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
                ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
                if( !SetCommState( m_hIDComDev, &dcb ) ||
                !SetupComm( m_hIDComDev, 10000, 10000 ) ||
                m_OverlappedRead.hEvent == NULL ||
                m_OverlappedWrite.hEvent == NULL ){
                DWORD dwError = GetLastError();
                if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
                if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
                CloseHandle( m_hIDComDev );
                return( FALSE );
                }

                m_bOpened = TRUE;

                return( m_bOpened );

                }

                BOOL CSerial::Close( void )
                {

                if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );

                if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
                if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
                CloseHandle( m_hIDComDev );
                m_bOpened = FALSE;
                m_hIDComDev = NULL;

                return( TRUE );

                }

                BOOL CSerial::WriteCommByte( unsigned char ucByte )
                {
                BOOL bWriteStat;
                DWORD dwBytesWritten;

                bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
                if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
                if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
                else{
                GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
                m_OverlappedWrite.Offset += dwBytesWritten;
                }
                }

                return( TRUE );

                }

                int CSerial::SendData( const char *buffer, int size )
                {

                if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

                DWORD dwBytesWritten = 0;
                int i;
                for( i=0; i<size; i++ ){
                WriteCommByte( buffer[i] );
                dwBytesWritten++;
                }

                return( (int) dwBytesWritten );

                }

                int CSerial::ReadDataWaiting( void )
                {

                if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

                DWORD dwErrorFlags;
                COMSTAT ComStat;

                ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

                return( (int) ComStat.cbInQue );

                }

                int CSerial::ReadData( void *buffer, int limit )
                {

                if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

                BOOL bReadStatus;
                DWORD dwBytesRead, dwErrorFlags;
                COMSTAT ComStat;

                ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
                if( !ComStat.cbInQue ) return( 0 );

                dwBytesRead = (DWORD) ComStat.cbInQue;
                if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

                bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
                if( !bReadStatus ){
                if( GetLastError() == ERROR_IO_PENDING ){
                WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
                return( (int) dwBytesRead );
                }
                return( 0 );
                }

                return( (int) dwBytesRead );

                }
                Kel'Thuzads
                Mail:minhnguyen.ac@gmail.com

                Comment

                • phuc0709
                  Thành viên mới
                  • Feb 2006
                  • 21

                  #9
                  Minh có example mẫu về sử dụng lớp Cserial này ko ? Gửi lên cho mọi người cùng tham khảo!
                  AC

                  Comment

                  • nhhlp2003
                    Thành viên mới
                    • Jul 2006
                    • 20

                    #10
                    Nếu bạn dùng VC++ thì bạn cài thêm MSDN ra và tìm trong phần về
                    Windown CE ấy, nó có mã ví dụ cho đó
                    mình hồi ấy dùng MSDN2001
                    hoặc đánh communication serial vào mà tìm kiếm

                    Comment

                    • toannguyen
                      Thành viên mới
                      • Apr 2007
                      • 4

                      #11
                      Có ai biết truyền file qua cổng COM không?
                      Thầy nói không truyền thành chuỗi nữa, mà phải truyền theo gói, vậy cái gói đó là như thế nào?
                      Và nói chung là truyền file từ máy này sang máy khác thì làm sao??

                      Comment

                      Về tác giả

                      Collapse

                      Kel'Thuzads Tìm hiểu thêm về Kel'Thuzads

                      Bài viết mới nhất

                      Collapse

                      Đang tải...