/** * Initialize ModBus master. * * @param ucSlaveAddress - Not used in master mode * @param ucPort - Serial port number * @param ulBaudRate - Serial port baud rate * @param eParity - MB_PAR_NONE, MB_PAR_ODD, MB_PAR_EVEN * @return MB_ENOERR on success */ eMBErrorCode eMBRTUInit(UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity) { eMBErrorCode eStatus = MB_ENOERR; ULONG ulTimerT35_50us; ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION( ); /* Modbus RTU uses 8 Databits. */ if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) { eStatus = MB_EPORTERR; } if( ulBaudRate > 19200 ) { /* The timer reload value for a character is given by: * * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) * = 11 * Ticks_per_1s / Baudrate * = 220000 / Baudrate * The reload for t3.5 is 1.5 times this value and similarly * for t3.5. */ ulTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); } DEBUG_PUTSTRING1("T35 = ", ulTimerT35_50us); if( xMBPortTimersInit( ( USHORT ) ulTimerT35_50us ) != TRUE ) { eStatus = MB_EPORTERR; } EXIT_CRITICAL_SECTION( ); return eStatus; }
void vMBPortTimersEnable(void){ /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */ OpenTimer5(); xMBPortTimersInit(usTimerT35_50us); //Adjust timing for real timeouts //ConfigIntTimer3(T2_INT_ON | T2_INT_PRIOR_2); _T5IE = 1; T5CONbits.TON = 1; // Start Timer // INTCONbits.GIE = 1; //INTEnableSystemMultiVectoredInt(); }
/** ----------------------------------------------------------------------------------------------------------------------- eMBRTUInit ----------------------------------------------------------------------------------------------------------------------- * Event Handler for GPI module * * @date DEC/02/2013 * @author FW_DEV_2 * @pre None * @return None ************************************************************************************************************************ */ eMBErrorCode eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) { eMBErrorCode eStatus = MB_ENOERR; ULONG usTimer1_5=0; ULONG usTimer3_5=0; printf("Initializing RTU\n"); ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION( ); /* Modbus RTU uses 8 Databits. */ if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) { printf("Serial port initialization failed\n"); eStatus = MB_EPORTERR; } else { /* If baudrate > 19200 then we should use the fixed timer values * t35 = 1750us. Otherwise t35 must be 3.5 times the character time. */ if( ulBaudRate > 19200 ) { usTimer1_5 = 75000; /* 750 us */ usTimer3_5 = 175000; /* 1.750 ms*/ } else { /* The timer reload value for a character is given by: * * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) * = 11 * Ticks_per_1s / Baudrate * = 220000 / Baudrate * The reload for t3.5 is 1.5 times this value and similary * for t3.5. */ usTimer1_5 = (1500000/ulBaudRate); // usTimer3_5 = (3500000/ulBaudRate); } printf("Initialize timer"); if( xMBPortTimersInit( ( USHORT ) usTimer3_5 ) != TRUE ) { eStatus = MB_EPORTERR; } } EXIT_CRITICAL_SECTION( ); return eStatus; }
/* ----------------------- Start implementation -----------------------------*/ eMBErrorCode eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) { eMBErrorCode eStatus = MB_ENOERR; ULONG usTimerT35_50us; ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION(); /* Modbus RTU uses 8 Databits. */ if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE ) { eStatus = MB_EPORTERR; } else { /* If baudrate > 19200 then we should use the fixed timer values * t35 = 1750us. Otherwise t35 must be 3.5 times the character time. */ //如果波特率超过19200 使用固定的时间间隔,1750us //其他情况,则要进行计算。 if( ulBaudRate > 19200 ) { usTimerT35_50us = 35; /* 1750us. */ } else { /* The timer reload value for a character is given by: * * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) * = 11 * Ticks_per_1s / Baudrate * = 220000 / Baudrate * The reload for t3.5 is 1.5 times this value and similary * for t3.5. */ usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); } //初始化定时器 if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE ) { eStatus = MB_EPORTERR; } } EXIT_CRITICAL_SECTION( ); return eStatus; }
/* ----------------------- Start implementation -----------------------------*/ eMBErrorCode eMBRTUInit( uint8_t ucSlaveAddress, uint8_t ucPort, speed_t ulBaudRate, eMBParity eParity ) { eMBErrorCode eStatus = MB_ENOERR; uint32_t usTimerT35_50us; ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION( ); /* Modbus RTU uses 8 Databits. */ if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != true ) { eStatus = MB_EPORTERR; } else { /* If baudrate > 19200 then we should use the fixed timer values * t35 = 1750us. Otherwise t35 must be 3.5 times the character time. */ if( ulBaudRate > 19200 ) { usTimerT35_50us = 35; /* 1800us. */ } else { /* The timer reload value for a character is given by: * * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 ) * = 11 * Ticks_per_1s / Baudrate * = 220000 / Baudrate * The reload for t3.5 is 1.5 times this value and similary * for t3.5. */ usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate ); } if( xMBPortTimersInit( ( uint16_t ) usTimerT35_50us ) != true ) { eStatus = MB_EPORTERR; } } EXIT_CRITICAL_SECTION( ); return eStatus; }
/* ----------------------- Start implementation -----------------------------*/ eMBErrorCode eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) { eMBErrorCode eStatus = MB_ENOERR; ( void )ucSlaveAddress; ENTER_CRITICAL_SECTION( ); ucMBLFCharacter = MB_ASCII_DEFAULT_LF; if( xMBPortSerialInit( ucPort, ulBaudRate, 7, eParity ) != TRUE ) { eStatus = MB_EPORTERR; } else if( xMBPortTimersInit( MB_ASCII_TIMEOUT_SEC * 20000UL ) != TRUE ) { eStatus = MB_EPORTERR; } EXIT_CRITICAL_SECTION( ); return eStatus; }
void main( void ) { eMBErrorCode eStatus; /* Use external 32.768 Hz crystal to generate 4.194.304 Hz bus clock */ ICGC1 = 0x38; // ??=0,RANGE=0,REFS=1,CLKS=1:1,OSCSTEN=0,??=0:0 while( ICGS2_DCOS == 0 ); #if 0 /* Test code for porting */ #if 1 /* Timer test * Comment out call to pxMBPortCBTimerExpired() in prvvTIMERExpiredISR when testing the timer */ /* Disable the COP watchdog */ SOPT = 0x53; // COPE=0,COPT=1,STOPE=0,??=1:0:0,BKGDPE=1,??=1 ( void )xMBPortTimersInit( 20000 ); EnableInterrupts; for( ;; ) { vMBPortTimersEnable( ); _Wait; // wait for an interrupt /* toggle LED1 */ PTFD_PTFD0 = !PTFD_PTFD0; PTFDD_PTFDD0 = 1; } #else /* Receiver test * Comment out call to pxMBFrameCBByteReceived() in prvvUARTRxISR() when testing the receiver */ /* Disable the COP watchdog */ SOPT = 0x53; // COPE=0,COPT=1,STOPE=0,??=1:0:0,BKGDPE=1,??=1 /* Enable the receiver. */ assert( xMBPortSerialInit( 0, 9600, 8, MB_PAR_NONE ) ); EnableInterrupts; for( ;; ) { UCHAR ucByte; vMBPortSerialEnable( TRUE, FALSE ); _Wait; // wait for an interrupt assert( xMBPortSerialGetByte( &ucByte ) ); /* toggle LED1 */ PTFD_PTFD0 = !PTFD_PTFD0; PTFDD_PTFDD0 = 1; /* Transmitter test * Comment out call to pxMBFrameCBTransmitterEmpty() in prvvUARTTxReadyISR() when testing the transmitter */ #if 0 vMBPortSerialEnable( FALSE, TRUE ); assert( xMBPortSerialPutByte( ucByte ) ); _Wait; // wait for an interrupt /* toggle LED1 */ PTFD_PTFD0 = !PTFD_PTFD0; #endif // Transmitter test } #endif // Receiver test #else /* Demo * NOTE: Make sure the callbacks in the three ISPs have been restored after above testing */ /* Initialization */ eStatus = eMBInit( MB_RTU, 0x0A, 0, 38400, MB_PAR_EVEN ); // eStatus = eMBInit( MB_ASCII, 0x0A, 0, 38400, MB_PAR_EVEN ); /* Enable the Modbus Protocol Stack. */ eStatus = eMBEnable( ); /* Start polling */ EnableInterrupts; for( ;; ) { /* Poll for Modbus events */ ( void )eMBPoll( ); /* Count the number of polls */ usRegInputBuf[0]++; /* Count the number of timer overflows */ if( TPM1SC_TOF ) { TPM1SC_TOF = 0; ENTER_CRITICAL_SECTION( ); if( ++usRegInputBuf[1] == 0 ) // Happens every 2 seconds usRegInputBuf[2]++; // Happens every 36.4 hours EXIT_CRITICAL_SECTION( ); } /* Keep the COP watchdog happy */ __RESET_WATCHDOG( ); } #endif // Test code when porting }