Re[3]: Программирование общения двух ПК через протокол MODBU
От: Splin Беларусь  
Дата: 12.08.04 08:35
Оценка:
Здравствуйте, jak, Вы писали:

jak>буду очень благодарен за исходник класса. Если можно пришли кусок кода для примера как организовывать общение между мастером и слэйвом.

jak>и по поводу соединения через RS232 компы могут быть отдалены друг от друга на расстояние порятка 1500м. на сколько я понимаю просто rs232 тянет в лучшем случаем метров на 10. Правильно? и что тогда делать?

В этом случае можно протянуть кабель и установить обычные модемы, которые будут обеспечивать связь (можно использовать радио-модемы). Я не очень вкурсе конкретных устройств, т.к. я программист. Могу лишь сказать, что мы когда-то использовали некое устройство "удлинитель порта" позволяющие передавать данные по RS232 на большие растояния (точно не скажу насколько . Что касается кода — это вот такой класс (реализацию могу тоже предоставить после небольшой правки, если интересно, конечно...):

class CModbusConnection  
{
public:
    enum
    {
        RtuFrameMaxSize = 256,
        RtuFrameMinSize = 4,
        
        fExceptionMask = 0x80,

        // Bit access
        fReadDiscreteInputs = 1,
        fReadCoils = 2,
        fWriteSingleCoil = 5,
        fWriteMultipleCoils = 15,
        // 16 bits access
        fReadInputRegisters = 4,
        fReadHoldingRegisters = 3,
        fWriteSingleRegister = 6,
        fWriteMultipleRegisters = 16,
        // Diagnostics
        fReadExceptionStatus = 7
    };

public:
    CModbusConnection();
    ~CModbusConnection();

    // Open comm port
    bool Open(
        /* [in] */ LPCTSTR lpszPortName,
        /* [in] */ DWORD dwPortBaudRate,
        /* [in] */ BYTE byPortByteSize,
        /* [in] */ BYTE byPortParity,
        /* [in] */ BYTE byPortStopBits,
        /* [in] */ DWORD dwTimeoutRead,
        /* [in] */ DWORD dwTimeoutWrite);
    
    // Is openned comm port?
    bool IsOpened();
    
    // Close comm port
    void Close();

    // Sets the retry options
    void SetRetryOptions(DWORD dwRetryCount, DWORD dwRetryDelay);
    // Returnes the retry options
    void GetRetryOptions(DWORD& dwRetryCount, DWORD& dwRetryDelay) const;

public:
    // Sends read request (functions 1, 2, 3, 4)
    bool ReadRequest(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ BYTE byFunction,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [out] */ BYTE* pbyData,
        /* [in] */ BYTE byDataSize,
        /* [out] */ BYTE& byDataRealSize);

public:
    // #01 - Read Discrete Inputs
    bool ReadDiscreteInputs(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [out] */ BYTE* pbyData,
        /* [in] */ BYTE byDataSize,
        /* [out] */ BYTE& byDataRealSize);
    
    // #02 - Read Coils
    bool ReadCoils(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [out] */ BYTE* pbyData,
        /* [in] */ BYTE byDataSize,
        /* [out] */ BYTE& byDataRealSize);

    // #03 - Read Holding Registers
    bool ReadHoldingRegisters(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [out] */ BYTE* pbyData,
        /* [in] */ BYTE byDataSize,
        /* [out] */ BYTE& byDataRealSize);
    
    // #04 - Read Input Registers
    bool ReadInputRegisters(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [out] */ BYTE* pbyData,
        /* [in] */ BYTE byDataSize,
        /* [out] */ BYTE& byDataRealSize);

    // #05 - Write Single Coil
    bool WriteSingleCoil(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wAddres,
        /* [in] */ WORD wData);
    
    // #06 - Write Single Register
    bool WriteSingleRegister(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wAddres,
        /* [in] */ WORD wData);

    // #07 - Read Exception Status
    bool ReadExceptionStatus(
        /* [in] */ BYTE bySlaveAddres,
        /* [out] */ BYTE& byStatus);

    // #15 - Write Multiple Coils
    bool WriteMultipleCoils(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [in] */ const BYTE* pbyData,
        /* [in] */ BYTE byDataSize);
    
    // #16 - Write Multiple Registers
    bool WriteMultipleRegisters(
        /* [in] */ BYTE bySlaveAddres,
        /* [in] */ WORD wStartingAddres,
        /* [in] */ WORD wQuantity,
        /* [in] */ const WORD* pwData,
        /* [in] */ BYTE byDataSize);

protected:    
    bool SendQueryWithRetry(
        /* [in] */ const BYTE* pbyQuery,
        /* [in] */ WORD wQuerySize,
        /* [out] */ BYTE* pbyResponse,
        /* [in] */ WORD wResponseSize,
        /* [out] */ WORD* pwResponseRealSize);

    bool SendQuery(
        /* [in] */ const BYTE* pbyQuery,
        /* [in] */ WORD wQuerySize,
        /* [out] */ BYTE* pbyResponse,
        /* [in] */ WORD wResponseSize,
        /* [out] */ WORD* pwResponseRealSize);

    bool ValidateResponse(
        /* [in] */ const BYTE* pbyQuery,
        /* [in] */ WORD wQuerySize,
        /* [in] */ const BYTE* pbyResponse,
        /* [in] */ WORD wResponseSize,
        /* [in] */ WORD wResponseRealSize);

protected:
    void TraceModbusError(LPCTSTR lpszPortName, BYTE byError, LPCTSTR lpszMessage);

    void TraceCommError(LPCTSTR lpszPortName, DWORD dwError, LPCTSTR lpszMessage);
    void TraceCommError(LPCTSTR lpszPortName, LPCTSTR lpszMessage);
    void TraceCommInfo(LPCTSTR lpszPortName, LPCTSTR lpszMessage);
    void TraceCommDebug(LPCTSTR lpszPortName, LPCTSTR lpszMessage);
    
    void TraceFrame(const BYTE* pbyFrame, const WORD wFrameSize, bool bQuery);
    
    bool ClearAndTraceCommError(HRESULT hrError, LPCTSTR lpszMessage);

protected:
    CString m_strPortName;
    HANDLE m_hCommPort;

protected:
    DWORD m_dwRetryCount;
    DWORD m_dwRetryDelay;
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.