This is a RS485 class that uses the second UART and was tested on a Nucleo F030R8. A main demo program howto use the class is included. This class control the direction pin on the transceiver buffer automatically, and used transmit and receive interrupts. Ring buffers (256 bytes) are implemented on both transmission and reception. It assumes a ADM3485 'type' buffer where pins 2 ans 3 are connected and seen as direction. This test program could easily be adapted as base for other programs.
Diff: dlms_comms.cpp
- Revision:
- 11:ca1e0ca3a673
- Parent:
- 10:e104a1b24165
--- a/dlms_comms.cpp Tue Nov 11 21:02:06 2014 +0000 +++ b/dlms_comms.cpp Sun Nov 23 08:13:26 2014 +0000 @@ -5,11 +5,11 @@ //#define DEBUG_DLMS_COMMS - // Instantiate the raw serial (2nd uart) Tx then Rx +// Instantiate the raw serial (2nd uart) Tx then Rx RawSerial rs485(PA_9, PA_10); - // pin to switch the rs485 buffer direction + +// pin to switch the rs485 buffer direction DigitalOut dir_485 (PB_0); - //DigitalOut dir_485 (D7); /** --------------------------------------------------------------------------- * @brief C O N S T R U C T O R @@ -30,24 +30,11 @@ // when characters received rs485.attach(this, &dlms_comms::Rx_interrupt, - //RawSerial::RxIrq Serial::RxIrq); timer = NULL; debug_uart = NULL; tx_irq_count = 0l; rx_irq_count = 0l; - - -// /** Set the flow control type on the serial port -// * -// * @param type the flow control type (Disabled, RTS, CTS, RTSCTS) -// * @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS) -// * @param flow2 the second flow control pin (CTS for RTSCTS) -// */ -// rs485.set_flow_control(RTSCTS , //Flow type, -// dir_485, //PB_0, //PinName flow1=NC, -// dir_485 //PB_0 //PinName flow2=NC -// ); } /** --------------------------------------------------------------------------- * @brief bq34z110::init_port_expander Put all ports in INPUT mode @@ -60,9 +47,9 @@ // we use the parent timer and debug port debug_uart = parent_uart; timer = parent_timer; -//#ifdef DEBUG_DLMS_COMMS - //debug_uart->printf (" init_dlms_comms..\r\n"); -//#endif +#ifdef DEBUG_DLMS_COMMS + debug_uart->printf (" init_dlms_comms..\r\n"); +#endif } /** --------------------------------------------------------------------------- * @brief dlms_comms::initialise This method initialise the rs485 comms port @@ -107,12 +94,12 @@ rs485.format((int) bits, my_parity, (int) stop_bits); -//# ifdef DEBUG_DLMS_COMMS - //debug_uart->printf (" init_dlms_comms..Baudrate (%d) %d bits Parity=%c\r\n", - // baudrate, bits, parity); -//# endif +# ifdef DEBUG_DLMS_COMMS + debug_uart->printf (" init_dlms_comms..Baudrate (%d) %d bits Parity=%c\r\n", + baudrate, bits, parity); // dummy send packet to rs485 - //send_packet ("\r\nHello cruel world\r\n",12); + send_packet ("\r\nHello cruel world\r\n",12); +# endif if ( rs485.readable()) rs485.getc(); } @@ -130,9 +117,11 @@ void dlms_comms::Tx_interrupt(void) { tx_irq_count++; + + // disable the transmit interrupt + rs485.attach(NULL, Serial::TxIrq); // enable the receiver, we are finito with the transmission of characters // this changes the direction on the transceiver buffer - rs485.attach(NULL, Serial::TxIrq); dir_485 = 0; } /** ---------------------------------------------------------------------------