mbed-modbus-RTU (modbus slave to control 6 LEDs)
Dependencies: Modbus nvt_rs485
Fork of NuMaker-mbed-modbus-sample by
main.cpp@6:7fb2dc9292b7, 2017-01-05 (annotated)
- Committer:
- rkuo2000
- Date:
- Thu Jan 05 13:33:34 2017 +0000
- Revision:
- 6:7fb2dc9292b7
- Parent:
- 5:3e19326b47f7
mbed-modbus-RTU to control 6 LEDs
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rkuo2000 | 5:3e19326b47f7 | 1 | // |
rkuo2000 | 5:3e19326b47f7 | 2 | // modbus RTU sample code |
rkuo2000 | 5:3e19326b47f7 | 3 | // |
rkuo2000 | 5:3e19326b47f7 | 4 | // EVB : NuMaker-PFM-NUC472 |
rkuo2000 | 5:3e19326b47f7 | 5 | // Connections: |
rkuo2000 | 5:3e19326b47f7 | 6 | // D0 & D1 : to USB-to-UART (PC running modbus master software simulator) |
rkuo2000 | 5:3e19326b47f7 | 7 | // D2 ~ D7 : to external LEDs |
rkuo2000 | 5:3e19326b47f7 | 8 | // |
rkuo2000 | 5:3e19326b47f7 | 9 | // if choose on-board RS485, then go to Modbus/portserial.cpp line#38 |
rkuo2000 | 5:3e19326b47f7 | 10 | // Modify '//#define DEF_RS485_PORT 1' to '#define DEF_RS485_PORT 1' |
rkuo2000 | 5:3e19326b47f7 | 11 | // |
rkuo2000 | 5:3e19326b47f7 | 12 | // PC modbus master command = Write Single Register |
rkuo2000 | 5:3e19326b47f7 | 13 | // ID = 1, Func = 6, Addr = 4, Data = 0x003F (6 bits for 6 LEDs) |
rkuo2000 | 6:7fb2dc9292b7 | 14 | // |
wclin | 0:1e78831318df | 15 | /* ----------------------- System includes --------------------------------*/ |
wclin | 0:1e78831318df | 16 | #include "mbed.h" |
wclin | 0:1e78831318df | 17 | #include "rtos.h" |
wclin | 0:1e78831318df | 18 | /*----------------------- Modbus includes ----------------------------------*/ |
wclin | 0:1e78831318df | 19 | #include "mb.h" |
wclin | 0:1e78831318df | 20 | #include "mbport.h" |
wclin | 0:1e78831318df | 21 | |
wclin | 0:1e78831318df | 22 | /* ----------------------- Defines ------------------------------------------*/ |
rkuo2000 | 5:3e19326b47f7 | 23 | #define MODBUS_BAUDRATE 9600 |
wclin | 0:1e78831318df | 24 | // Sharing buffer index |
rkuo2000 | 5:3e19326b47f7 | 25 | enum { // Modbus Slave Address |
rkuo2000 | 5:3e19326b47f7 | 26 | eData_MBInCounter, // 0: In Counter |
rkuo2000 | 5:3e19326b47f7 | 27 | eData_MBOutCounter, // 1: Out Counter |
rkuo2000 | 5:3e19326b47f7 | 28 | eData_MBError, // 2: Error code |
rkuo2000 | 5:3e19326b47f7 | 29 | eData_DI, // 3: DI |
rkuo2000 | 5:3e19326b47f7 | 30 | eData_DO, // 4: DO = LED[x] |
rkuo2000 | 5:3e19326b47f7 | 31 | eData_RGB, // 5: DO = RGB LED |
rkuo2000 | 5:3e19326b47f7 | 32 | eData_MBResistorVar, // 6: Variable Resistor |
rkuo2000 | 5:3e19326b47f7 | 33 | eData_TemperatureSensor, // 7: Temperature Sensor |
rkuo2000 | 5:3e19326b47f7 | 34 | eData_Cnt |
wclin | 0:1e78831318df | 35 | } E_DATA_TYPE; |
wclin | 0:1e78831318df | 36 | |
wclin | 0:1e78831318df | 37 | #define REG_INPUT_START 1 |
wclin | 0:1e78831318df | 38 | #define REG_INPUT_NREGS eData_Cnt |
rkuo2000 | 5:3e19326b47f7 | 39 | #define SLAVE_ID 0x01 |
wclin | 0:1e78831318df | 40 | /* ----------------------- Static variables ---------------------------------*/ |
wclin | 0:1e78831318df | 41 | static USHORT usRegInputStart = REG_INPUT_START; |
wclin | 0:1e78831318df | 42 | static USHORT usRegInputBuf[REG_INPUT_NREGS]; |
wclin | 0:1e78831318df | 43 | |
wclin | 0:1e78831318df | 44 | DigitalOut led1(LED1); // For temperature worker. |
wclin | 0:1e78831318df | 45 | DigitalOut led2(LED2); // For Modbus worker. |
wclin | 0:1e78831318df | 46 | DigitalOut led3(LED3); // For Holder CB |
wclin | 0:1e78831318df | 47 | |
rkuo2000 | 5:3e19326b47f7 | 48 | #define DEF_LED_NUM 6 |
shliu1 |
4:f69e05cb6714 | 49 | #if defined(TARGET_NUMAKER_PFM_NUC472) |
rkuo2000 | 5:3e19326b47f7 | 50 | DigitalOut LED[DEF_LED_NUM] = { PF_9, PF_10, PC_10, PC_11, PA_10, PA_9 } ; |
shliu1 |
4:f69e05cb6714 | 51 | #elif defined(TARGET_NUMAKER_PFM_M453) |
rkuo2000 | 5:3e19326b47f7 | 52 | DigitalOut LED[DEF_LED_NUM] = { PC_6, PC_7, PC_11, PC_12, PC_13, PC_14 } ; |
shliu1 |
4:f69e05cb6714 | 53 | #endif |
wclin | 0:1e78831318df | 54 | |
rkuo2000 | 5:3e19326b47f7 | 55 | void light_leds() |
wclin | 0:1e78831318df | 56 | { |
wclin | 0:1e78831318df | 57 | int i=0; |
rkuo2000 | 5:3e19326b47f7 | 58 | USHORT usOutValue = usRegInputBuf[eData_DO]; |
rkuo2000 | 5:3e19326b47f7 | 59 | for ( i=0; i<DEF_LED_NUM ; i++) |
rkuo2000 | 5:3e19326b47f7 | 60 | if((usOutValue&(0x01<<i)) !=0) LED[i]=1; |
rkuo2000 | 5:3e19326b47f7 | 61 | else LED[i]=0; |
wclin | 0:1e78831318df | 62 | } |
wclin | 0:1e78831318df | 63 | |
wclin | 0:1e78831318df | 64 | /* ----------------------- Start implementation -----------------------------*/ |
wclin | 0:1e78831318df | 65 | int |
wclin | 0:1e78831318df | 66 | main( void ) |
wclin | 0:1e78831318df | 67 | { |
wclin | 0:1e78831318df | 68 | eMBErrorCode eStatus; |
wclin | 0:1e78831318df | 69 | |
wclin | 0:1e78831318df | 70 | // Initialise some registers |
wclin | 0:1e78831318df | 71 | for (int i=0; i<REG_INPUT_NREGS; i++) |
wclin | 0:1e78831318df | 72 | usRegInputBuf[i] = 0x0; |
rkuo2000 | 5:3e19326b47f7 | 73 | |
rkuo2000 | 5:3e19326b47f7 | 74 | light_leds(); // Control LEDs |
rkuo2000 | 5:3e19326b47f7 | 75 | |
rkuo2000 | 5:3e19326b47f7 | 76 | printf("\n\r"); |
rkuo2000 | 5:3e19326b47f7 | 77 | //printf("We will set modbus slave ID-%d(0x%x) for the device.\r\n", usSlaveID, usSlaveID ); |
rkuo2000 | 5:3e19326b47f7 | 78 | printf("modbus master : %d bps \r\n", MODBUS_BAUDRATE); |
rkuo2000 | 5:3e19326b47f7 | 79 | printf("modbus slave ID: %d \r\n", SLAVE_ID, SLAVE_ID ); |
rkuo2000 | 5:3e19326b47f7 | 80 | printf("\r\n"); |
rkuo2000 | 5:3e19326b47f7 | 81 | printf("To control modbus slave LEDs, use modbus poll\r\n"); |
rkuo2000 | 5:3e19326b47f7 | 82 | printf("command: ID= %d, Func = 6, Addr = %d, Data = LED[x] -- Write Single Register\r\n", SLAVE_ID, eData_DO); |
wclin | 0:1e78831318df | 83 | |
wclin | 0:1e78831318df | 84 | /* Enable the Modbus Protocol Stack. */ |
rkuo2000 | 5:3e19326b47f7 | 85 | if ( (eStatus = eMBInit( MB_RTU, SLAVE_ID, 0, MODBUS_BAUDRATE, MB_PAR_NONE )) != MB_ENOERR ) |
wclin | 0:1e78831318df | 86 | goto FAIL_MB; |
wclin | 0:1e78831318df | 87 | else if ( (eStatus = eMBEnable( ) ) != MB_ENOERR ) |
wclin | 0:1e78831318df | 88 | goto FAIL_MB_1; |
wclin | 0:1e78831318df | 89 | else { |
wclin | 0:1e78831318df | 90 | for( ;; ) |
wclin | 0:1e78831318df | 91 | { |
rkuo2000 | 5:3e19326b47f7 | 92 | xMBPortSerialPolling(); |
wclin | 0:1e78831318df | 93 | if ( eMBPoll( ) != MB_ENOERR ) break; |
wclin | 0:1e78831318df | 94 | } |
wclin | 0:1e78831318df | 95 | } |
wclin | 0:1e78831318df | 96 | |
wclin | 0:1e78831318df | 97 | FAIL_MB_1: |
wclin | 0:1e78831318df | 98 | eMBClose(); |
wclin | 0:1e78831318df | 99 | |
wclin | 0:1e78831318df | 100 | FAIL_MB: |
wclin | 0:1e78831318df | 101 | for( ;; ) |
wclin | 0:1e78831318df | 102 | { |
wclin | 0:1e78831318df | 103 | led2 = !led2; |
wclin | 0:1e78831318df | 104 | Thread::wait(200); |
wclin | 0:1e78831318df | 105 | } |
wclin | 0:1e78831318df | 106 | } |
wclin | 0:1e78831318df | 107 | |
wclin | 0:1e78831318df | 108 | eMBErrorCode |
wclin | 0:1e78831318df | 109 | eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ) |
wclin | 0:1e78831318df | 110 | { |
wclin | 0:1e78831318df | 111 | eMBErrorCode eStatus = MB_ENOERR; |
wclin | 0:1e78831318df | 112 | int iRegIndex; |
wclin | 0:1e78831318df | 113 | |
wclin | 0:1e78831318df | 114 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 115 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 116 | { |
wclin | 0:1e78831318df | 117 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 118 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 119 | { |
wclin | 0:1e78831318df | 120 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 121 | ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 ); |
wclin | 0:1e78831318df | 122 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 123 | ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF ); |
wclin | 0:1e78831318df | 124 | iRegIndex++; |
wclin | 0:1e78831318df | 125 | usNRegs--; |
wclin | 0:1e78831318df | 126 | } |
wclin | 0:1e78831318df | 127 | } |
wclin | 0:1e78831318df | 128 | else |
wclin | 0:1e78831318df | 129 | { |
wclin | 0:1e78831318df | 130 | eStatus = MB_ENOREG; |
wclin | 0:1e78831318df | 131 | } |
rkuo2000 | 5:3e19326b47f7 | 132 | |
wclin | 0:1e78831318df | 133 | return eStatus; |
wclin | 0:1e78831318df | 134 | } |
rkuo2000 | 5:3e19326b47f7 | 135 | |
wclin | 0:1e78831318df | 136 | eMBErrorCode |
wclin | 0:1e78831318df | 137 | eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode ) |
wclin | 0:1e78831318df | 138 | { |
wclin | 0:1e78831318df | 139 | eMBErrorCode eStatus = MB_ENOERR; |
wclin | 0:1e78831318df | 140 | int iRegIndex; |
wclin | 0:1e78831318df | 141 | |
wclin | 0:1e78831318df | 142 | usRegInputBuf[eData_MBInCounter]++; |
wclin | 0:1e78831318df | 143 | usRegInputBuf[eData_MBOutCounter]++; |
wclin | 0:1e78831318df | 144 | |
wclin | 0:1e78831318df | 145 | if (eMode == MB_REG_READ) |
wclin | 0:1e78831318df | 146 | { |
rkuo2000 | 5:3e19326b47f7 | 147 | printf("modbus : MB REG READ...\r\n"); |
wclin | 0:1e78831318df | 148 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 149 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 150 | { |
wclin | 0:1e78831318df | 151 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 152 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 153 | { |
wclin | 0:1e78831318df | 154 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 155 | ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 ); |
wclin | 0:1e78831318df | 156 | *pucRegBuffer++ = |
wclin | 0:1e78831318df | 157 | ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF ); |
wclin | 0:1e78831318df | 158 | iRegIndex++; |
wclin | 0:1e78831318df | 159 | usNRegs--; |
wclin | 0:1e78831318df | 160 | } |
wclin | 0:1e78831318df | 161 | } |
wclin | 0:1e78831318df | 162 | } |
rkuo2000 | 5:3e19326b47f7 | 163 | |
wclin | 0:1e78831318df | 164 | if (eMode == MB_REG_WRITE) |
wclin | 0:1e78831318df | 165 | { |
rkuo2000 | 5:3e19326b47f7 | 166 | printf("modbus : MB REG Write...\r\n"); |
wclin | 0:1e78831318df | 167 | if( ( usAddress >= REG_INPUT_START ) |
wclin | 0:1e78831318df | 168 | && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) ) |
wclin | 0:1e78831318df | 169 | { |
rkuo2000 | 5:3e19326b47f7 | 170 | iRegIndex = ( int )( usAddress - usRegInputStart ); |
wclin | 0:1e78831318df | 171 | while( usNRegs > 0 ) |
wclin | 0:1e78831318df | 172 | { |
rkuo2000 | 5:3e19326b47f7 | 173 | usRegInputBuf[iRegIndex] = ((unsigned int) *pucRegBuffer << 8) | ((unsigned int) *(pucRegBuffer+1)); |
wclin | 0:1e78831318df | 174 | pucRegBuffer+=2; |
wclin | 0:1e78831318df | 175 | iRegIndex++; |
wclin | 0:1e78831318df | 176 | usNRegs--; |
rkuo2000 | 5:3e19326b47f7 | 177 | } |
rkuo2000 | 5:3e19326b47f7 | 178 | light_leds(); // Control LEDs |
wclin | 0:1e78831318df | 179 | } |
wclin | 0:1e78831318df | 180 | } |
rkuo2000 | 5:3e19326b47f7 | 181 | |
wclin | 0:1e78831318df | 182 | led3=!led3; |
wclin | 0:1e78831318df | 183 | |
wclin | 0:1e78831318df | 184 | return eStatus; |
wclin | 0:1e78831318df | 185 | } |
rkuo2000 | 5:3e19326b47f7 | 186 | |
rkuo2000 | 5:3e19326b47f7 | 187 | |
wclin | 0:1e78831318df | 188 | eMBErrorCode |
wclin | 0:1e78831318df | 189 | eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, |
wclin | 0:1e78831318df | 190 | eMBRegisterMode eMode ) |
wclin | 0:1e78831318df | 191 | { |
wclin | 0:1e78831318df | 192 | return MB_ENOREG; |
wclin | 0:1e78831318df | 193 | } |
rkuo2000 | 5:3e19326b47f7 | 194 | |
wclin | 0:1e78831318df | 195 | eMBErrorCode |
wclin | 0:1e78831318df | 196 | eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) |
wclin | 0:1e78831318df | 197 | { |
wclin | 0:1e78831318df | 198 | return MB_ENOREG; |
wclin | 0:1e78831318df | 199 | } |