NuMaker Modbus-RS485
Dependencies: Modbus nvt_rs485
Fork of modbus-over-rs485-sample by
main.cpp@22:e14caaceb177, 6 months ago (annotated)
- Committer:
- morgandu
- Date:
- Mon May 13 09:02:49 2024 +0000
- Revision:
- 22:e14caaceb177
- Parent:
- 20:71bf2986ea97
Update Modbus.lib and nvt_rs485.lib to support NuMaker-IoT-M487
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wclin | 0:1e78831318df | 1 | /* |
wclin | 0:1e78831318df | 2 | * The program is a sample code. |
wclin | 0:1e78831318df | 3 | * It needs run with some NuMaker-PFM-NUC472 boards. |
wclin | 1:f9d748875768 | 4 | * |
wclin | 1:f9d748875768 | 5 | * Please remeber to modify global definition to enable RS485 port on board. |
wclin | 1:f9d748875768 | 6 | * Modify '//#define DEF_RS485_PORT 1' to '#define DEF_RS485_PORT 1' |
wclin | 0:1e78831318df | 7 | */ |
wclin | 0:1e78831318df | 8 | |
wclin | 0:1e78831318df | 9 | /* ----------------------- System includes --------------------------------*/ |
wclin | 0:1e78831318df | 10 | #include "mbed.h" |
wclin | 0:1e78831318df | 11 | #include "rtos.h" |
wclin | 0:1e78831318df | 12 | /*----------------------- Modbus includes ----------------------------------*/ |
wclin | 0:1e78831318df | 13 | #include "mb.h" |
wclin | 0:1e78831318df | 14 | #include "mbport.h" |
wclin | 0:1e78831318df | 15 | |
wclin | 0:1e78831318df | 16 | /* ----------------------- Defines ------------------------------------------*/ |
wclin | 0:1e78831318df | 17 | // Sharing buffer index |
wclin | 0:1e78831318df | 18 | enum { |
wclin | 0:1e78831318df | 19 | eData_MBInCounter, |
wclin | 0:1e78831318df | 20 | eData_MBOutCounter, |
wclin | 0:1e78831318df | 21 | eData_MBError, |
wclin | 0:1e78831318df | 22 | eData_DI, |
wclin | 0:1e78831318df | 23 | eData_DATA, |
wclin | 0:1e78831318df | 24 | eData_Cnt |
wclin | 0:1e78831318df | 25 | } E_DATA_TYPE; |
wclin | 0:1e78831318df | 26 | |
wclin | 0:1e78831318df | 27 | #define REG_INPUT_START 1 |
wclin | 0:1e78831318df | 28 | #define REG_INPUT_NREGS eData_Cnt |
wclin | 0:1e78831318df | 29 | /* ----------------------- Static variables ---------------------------------*/ |
wclin | 0:1e78831318df | 30 | static USHORT usRegInputStart = REG_INPUT_START; |
wclin | 0:1e78831318df | 31 | static USHORT usRegInputBuf[REG_INPUT_NREGS]; |
wclin | 0:1e78831318df | 32 | |
wclin | 0:1e78831318df | 33 | DigitalOut led1(LED1); // For temperature worker. |
wclin | 0:1e78831318df | 34 | DigitalOut led2(LED2); // For Modbus worker. |
wclin | 0:1e78831318df | 35 | DigitalOut led3(LED3); // For Holder CB |
wclin | 0:1e78831318df | 36 | |
shliu1 | 20:71bf2986ea97 | 37 | #define DEF_PIN_NUM 6 |
shliu1 | 20:71bf2986ea97 | 38 | DigitalIn DipSwitch[DEF_PIN_NUM] = { D2, D3, D4, D5, D6, D7 } ; |
wclin | 0:1e78831318df | 39 | |
wclin | 0:1e78831318df | 40 | unsigned short GetValueOnDipSwitch() |
wclin | 0:1e78831318df | 41 | { |
wclin | 0:1e78831318df | 42 | int i=0; |
wclin | 0:1e78831318df | 43 | unsigned short usDipValue = 0x0; |
wclin | 0:1e78831318df | 44 | for ( i=0; i<DEF_PIN_NUM ; i++) |
wclin | 0:1e78831318df | 45 | usDipValue |= DipSwitch[i].read() << i; |
wclin | 0:1e78831318df | 46 | usDipValue = (~usDipValue) & 0x003F; |
wclin | 0:1e78831318df | 47 | return usDipValue; |
wclin | 0:1e78831318df | 48 | } |
wclin | 0:1e78831318df | 49 | |
wclin | 0:1e78831318df | 50 | void worker_uart(void const *args) |
wclin | 0:1e78831318df | 51 | { |
wclin | 0:1e78831318df | 52 | int counter=0; |
wclin | 0:1e78831318df | 53 | // For UART-SERIAL Tx/Rx Service. |
wclin | 0:1e78831318df | 54 | while (true) |
wclin | 0:1e78831318df | 55 | { |
wclin | 0:1e78831318df | 56 | //xMBPortSerialPolling(); |
wclin | 0:1e78831318df | 57 | if ( counter > 10000 ) |
wclin | 0:1e78831318df | 58 | { |
wclin | 0:1e78831318df | 59 | led2 = !led2; |
wclin | 0:1e78831318df | 60 | counter=0; |
wclin | 0:1e78831318df | 61 | } |
wclin | 0:1e78831318df | 62 | counter++; |
wclin | 0:1e78831318df | 63 | } |
wclin | 0:1e78831318df | 64 | } |
wclin | 0:1e78831318df | 65 | |
wclin | 0:1e78831318df | 66 | /* ----------------------- Start implementation -----------------------------*/ |
wclin | 0:1e78831318df | 67 | int |
wclin | 0:1e78831318df | 68 | main( void ) |
wclin | 0:1e78831318df | 69 | { |
wclin | 0:1e78831318df | 70 | eMBErrorCode eStatus; |
wclin | 0:1e78831318df | 71 | //Thread uart_thread(worker_uart); |
wclin | 0:1e78831318df | 72 | unsigned short usSlaveID=GetValueOnDipSwitch(); |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 73 | #ifdef MBED_MAJOR_VERSION |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 74 | printf("Mbed OS version %d.%d.%d\r\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION); |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 75 | #endif |
wclin | 0:1e78831318df | 76 | // Initialise some registers |
wclin | 0:1e78831318df | 77 | for (int i=0; i<REG_INPUT_NREGS; i++) |
wclin | 0:1e78831318df | 78 | usRegInputBuf[i] = 0x0; |
wclin | 0:1e78831318df | 79 | |
wclin | 0:1e78831318df | 80 | printf("We will set modbus slave ID-%d(0x%x) for the device.\r\n", usSlaveID, usSlaveID ); |
wclin | 0:1e78831318df | 81 | |
wclin | 0:1e78831318df | 82 | /* Enable the Modbus Protocol Stack. */ |
wclin | 0:1e78831318df | 83 | if ( (eStatus = eMBInit( MB_RTU, usSlaveID, 0, 115200, MB_PAR_NONE )) != MB_ENOERR ) |
wclin | 0:1e78831318df | 84 | goto FAIL_MB; |
wclin | 0:1e78831318df | 85 | else if ( (eStatus = eMBEnable( ) ) != MB_ENOERR ) |
wclin | 0:1e78831318df | 86 | goto FAIL_MB_1; |
wclin | 0:1e78831318df | 87 | else { |
wclin | 0:1e78831318df | 88 | for( ;; ) |
wclin | 0:1e78831318df | 89 | { |
wclin | 0:1e78831318df | 90 | xMBPortSerialPolling(); |
wclin | 0:1e78831318df | 91 | if ( eMBPoll( ) != MB_ENOERR ) break; |
wclin | 0:1e78831318df | 92 | } |
wclin | 0:1e78831318df | 93 | } |
wclin | 0:1e78831318df | 94 | |
wclin | 0:1e78831318df | 95 | FAIL_MB_1: |
wclin | 0:1e78831318df | 96 | eMBClose(); |
wclin | 0:1e78831318df | 97 | |
wclin | 0:1e78831318df | 98 | FAIL_MB: |
wclin | 0:1e78831318df | 99 | for( ;; ) |
wclin | 0:1e78831318df | 100 | { |
wclin | 0:1e78831318df | 101 | led2 = !led2; |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 102 | #if MBED_MAJOR_VERSION >= 6 |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 103 | ThisThread::sleep_for(200); |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 104 | #else |
wclin | 0:1e78831318df | 105 | Thread::wait(200); |
SHLIU1@OANBE02333.nuvoton.com | 15:a935936e74c1 | 106 | #endif |
wclin | 0:1e78831318df | 107 | } |
wclin | 0:1e78831318df | 108 | } |
wclin | 0:1e78831318df | 109 | |
wclin | 0:1e78831318df | 110 | |
wclin | 0:1e78831318df | 111 | |
wclin | 0:1e78831318df | 112 | |
wclin | 0:1e78831318df | 113 | eMBErrorCode |
wclin | 0:1e78831318df | 114 | eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ) |
wclin | 0:1e78831318df | 115 | { |
wclin | 0:1e78831318df | 116 | eMBErrorCode eStatus = MB_ENOERR; |
wclin | 0:1e78831318df | 117 | int iRegIndex; |
wclin | 0:1e78831318df | 118 | |
wclin | 0:1e78831318df | 119 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 120 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 121 | { |
wclin | 0:1e78831318df | 122 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 123 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 124 | { |
wclin | 0:1e78831318df | 125 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 126 | ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 ); |
wclin | 0:1e78831318df | 127 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 128 | ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF ); |
wclin | 0:1e78831318df | 129 | iRegIndex++; |
wclin | 0:1e78831318df | 130 | usNRegs--; |
wclin | 0:1e78831318df | 131 | } |
wclin | 0:1e78831318df | 132 | } |
wclin | 0:1e78831318df | 133 | else |
wclin | 0:1e78831318df | 134 | { |
wclin | 0:1e78831318df | 135 | eStatus = MB_ENOREG; |
wclin | 0:1e78831318df | 136 | } |
wclin | 0:1e78831318df | 137 | |
wclin | 0:1e78831318df | 138 | return eStatus; |
wclin | 0:1e78831318df | 139 | } |
wclin | 0:1e78831318df | 140 | |
wclin | 0:1e78831318df | 141 | eMBErrorCode |
wclin | 0:1e78831318df | 142 | eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode ) |
wclin | 0:1e78831318df | 143 | { |
wclin | 0:1e78831318df | 144 | eMBErrorCode eStatus = MB_ENOERR; |
wclin | 0:1e78831318df | 145 | int iRegIndex; |
wclin | 0:1e78831318df | 146 | |
wclin | 0:1e78831318df | 147 | usRegInputBuf[eData_MBInCounter]++; |
wclin | 0:1e78831318df | 148 | usRegInputBuf[eData_MBOutCounter]++; |
wclin | 0:1e78831318df | 149 | |
wclin | 0:1e78831318df | 150 | if (eMode == MB_REG_READ) |
wclin | 0:1e78831318df | 151 | { |
wclin | 0:1e78831318df | 152 | usRegInputBuf[eData_DI] = GetValueOnDipSwitch(); |
wclin | 0:1e78831318df | 153 | |
wclin | 0:1e78831318df | 154 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 155 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 156 | { |
wclin | 0:1e78831318df | 157 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 158 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 159 | { |
wclin | 0:1e78831318df | 160 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 161 | ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 ); |
wclin | 0:1e78831318df | 162 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 163 | ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF ); |
wclin | 0:1e78831318df | 164 | iRegIndex++; |
wclin | 0:1e78831318df | 165 | usNRegs--; |
wclin | 0:1e78831318df | 166 | } |
wclin | 0:1e78831318df | 167 | } |
wclin | 0:1e78831318df | 168 | } |
wclin | 0:1e78831318df | 169 | |
wclin | 0:1e78831318df | 170 | if (eMode == MB_REG_WRITE) |
wclin | 0:1e78831318df | 171 | { |
wclin | 0:1e78831318df | 172 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 173 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 174 | { |
wclin | 0:1e78831318df | 175 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 176 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 177 | { |
wclin | 0:1e78831318df | 178 | usRegInputBuf[iRegIndex] = ((unsigned int) *pucRegBuffer << 8) | ((unsigned int) *(pucRegBuffer+1)); |
wclin | 0:1e78831318df | 179 | pucRegBuffer+=2; |
wclin | 0:1e78831318df | 180 | iRegIndex++; |
wclin | 0:1e78831318df | 181 | usNRegs--; |
wclin | 0:1e78831318df | 182 | } |
wclin | 0:1e78831318df | 183 | } |
wclin | 0:1e78831318df | 184 | } |
wclin | 0:1e78831318df | 185 | |
wclin | 0:1e78831318df | 186 | led3=!led3; |
wclin | 0:1e78831318df | 187 | |
wclin | 0:1e78831318df | 188 | return eStatus; |
wclin | 0:1e78831318df | 189 | } |
wclin | 0:1e78831318df | 190 | |
wclin | 0:1e78831318df | 191 | |
wclin | 0:1e78831318df | 192 | eMBErrorCode |
wclin | 0:1e78831318df | 193 | eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, |
wclin | 0:1e78831318df | 194 | eMBRegisterMode eMode ) |
wclin | 0:1e78831318df | 195 | { |
wclin | 0:1e78831318df | 196 | return MB_ENOREG; |
wclin | 0:1e78831318df | 197 | } |
wclin | 0:1e78831318df | 198 | |
wclin | 0:1e78831318df | 199 | eMBErrorCode |
wclin | 0:1e78831318df | 200 | eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) |
wclin | 0:1e78831318df | 201 | { |
wclin | 0:1e78831318df | 202 | return MB_ENOREG; |
wclin | 0:1e78831318df | 203 | } |