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.

Dependencies:   mbed

Committer:
creatron
Date:
Sun Nov 23 08:13:26 2014 +0000
Revision:
11:ca1e0ca3a673
Parent:
9:d49cdc77f867
Commit to be publised

Who changed what in which revision?

UserRevisionLine numberNew contents of line
creatron 0:044dfba47660 1 #include "mbed.h"
creatron 0:044dfba47660 2 #include "dlms_comms.h"
creatron 11:ca1e0ca3a673 3 /** ---------------------------------------------------------------------------
creatron 11:ca1e0ca3a673 4 * @brief This module was tested on a Nucleo F030R8 with dual UARTS
creatron 11:ca1e0ca3a673 5 * The debugger uart is the normal , and the second uart was used for
creatron 11:ca1e0ca3a673 6 * RS485 communications
creatron 11:ca1e0ca3a673 7 * @note The ring buffers are 256 bytes, that implies that if an unsigned
creatron 11:ca1e0ca3a673 8 * char is used as index , the ++index wraps automatically, is other
creatron 11:ca1e0ca3a673 9 * ring buffer sizes is used, please wrap the head and tail indexes
creatron 11:ca1e0ca3a673 10 * appropiate
creatron 11:ca1e0ca3a673 11 * @note The timer was instantiate and used dering debugging to display
creatron 11:ca1e0ca3a673 12 * the timing.. kept just for incase one needs it
creatron 11:ca1e0ca3a673 13 **/
creatron 11:ca1e0ca3a673 14
creatron 0:044dfba47660 15 // instantiate classes
creatron 0:044dfba47660 16 Timer timer;
creatron 0:044dfba47660 17 // debug serial comms
creatron 0:044dfba47660 18 RawSerial debugger(SERIAL_TX, SERIAL_RX);
creatron 11:ca1e0ca3a673 19 // rs485 comms class on 2nd uart
creatron 0:044dfba47660 20 dlms_comms dlms;
creatron 0:044dfba47660 21
creatron 0:044dfba47660 22 DigitalOut myled(LED1);
creatron 0:044dfba47660 23
creatron 0:044dfba47660 24 #define POLL_TIME_MS 100
creatron 0:044dfba47660 25
creatron 0:044dfba47660 26 /** -------------------------------------------------------------------------
creatron 0:044dfba47660 27 * @brief the setup routine runs once when you press reset
creatron 0:044dfba47660 28 */
creatron 0:044dfba47660 29 void setup(void)
creatron 0:044dfba47660 30 {
creatron 0:044dfba47660 31 // initialize serial communication at 115200 bits per second:
creatron 0:044dfba47660 32 debugger.baud (115200);
creatron 11:ca1e0ca3a673 33 // use the defaults
creatron 11:ca1e0ca3a673 34 debugger.format();
creatron 11:ca1e0ca3a673 35 // annouce yourself to the world
creatron 11:ca1e0ca3a673 36 debugger.printf ("\r\n\n>> Creatron RS485 test program Nov 2014 \r\n");
creatron 11:ca1e0ca3a673 37 // start the timer
creatron 0:044dfba47660 38 timer.start();
creatron 11:ca1e0ca3a673 39 // this allows the rs485 class to use the parent timer and printf classes
creatron 11:ca1e0ca3a673 40 // in this class
creatron 0:044dfba47660 41 dlms.init ( &debugger, &timer);
creatron 11:ca1e0ca3a673 42 // initialise the rs485 class
creatron 0:044dfba47660 43 dlms.initialise (9600, // baudrate
creatron 0:044dfba47660 44 8, // bits,
creatron 0:044dfba47660 45 'n', // parity
creatron 9:d49cdc77f867 46 1); // stop_bits
creatron 0:044dfba47660 47 debugger.printf (">> Setup Done \r\n");
creatron 0:044dfba47660 48 }
creatron 0:044dfba47660 49 /** ---------------------------------------------------------------------------
creatron 0:044dfba47660 50 * @brief M A I N
creatron 0:044dfba47660 51 */
creatron 0:044dfba47660 52 int main(void)
creatron 0:044dfba47660 53 {
creatron 0:044dfba47660 54 // timer to do some timing
creatron 0:044dfba47660 55 UINT_64 compare_ms = 0l;
creatron 0:044dfba47660 56 UINT_64 current_ms;
creatron 11:ca1e0ca3a673 57 // my variable.. just a tester to 'see' the state of the RS485 transceiver
creatron 0:044dfba47660 58 bool direction_485 = false;
creatron 11:ca1e0ca3a673 59 // char to command functions
creatron 0:044dfba47660 60 char ch;
creatron 0:044dfba47660 61
creatron 0:044dfba47660 62 // initialise
creatron 0:044dfba47660 63 setup();
creatron 11:ca1e0ca3a673 64 debugger.printf (">> Ready.. \r\n"
creatron 11:ca1e0ca3a673 65 " Press 1 to send RS485 PacketDemo .. \r\n");
creatron 11:ca1e0ca3a673 66 // endless loop, glad I dont have to do this
creatron 0:044dfba47660 67 do
creatron 0:044dfba47660 68 {
creatron 11:ca1e0ca3a673 69 // use the timer to toggle I am alife led
creatron 0:044dfba47660 70 current_ms = timer.read_ms();
creatron 0:044dfba47660 71 current_ms -= compare_ms;
creatron 0:044dfba47660 72 if (current_ms > POLL_TIME_MS)
creatron 0:044dfba47660 73 {
creatron 0:044dfba47660 74 compare_ms += POLL_TIME_MS;
creatron 0:044dfba47660 75 if (myled)
creatron 0:044dfba47660 76 myled = false;
creatron 0:044dfba47660 77 else
creatron 0:044dfba47660 78 myled = true;
creatron 0:044dfba47660 79 }
creatron 11:ca1e0ca3a673 80
creatron 11:ca1e0ca3a673 81 // try to detect a direction change on the RS485 transceiver
creatron 11:ca1e0ca3a673 82 // and keep the user informed .. just for ammusement
creatron 0:044dfba47660 83 if (direction_485 != dlms.get_dir485())
creatron 0:044dfba47660 84 {
creatron 0:044dfba47660 85 direction_485 = dlms.get_dir485();
creatron 11:ca1e0ca3a673 86 debugger.printf("\r\n> Dir Changed ");
creatron 0:044dfba47660 87 if (direction_485)
creatron 0:044dfba47660 88 debugger.printf("1 \r\n");
creatron 0:044dfba47660 89 else
creatron 0:044dfba47660 90 debugger.printf("0 \r\n");
creatron 0:044dfba47660 91 }
creatron 11:ca1e0ca3a673 92 // check to see if the user has a 'request' to be executed
creatron 1:7091401482c5 93 if (debugger.readable())
creatron 1:7091401482c5 94 {
creatron 2:c99c596be3d1 95 ch = debugger.getc() & 0x7f;
creatron 1:7091401482c5 96 switch (ch)
creatron 1:7091401482c5 97 {
creatron 11:ca1e0ca3a673 98 // fine ..
creatron 1:7091401482c5 99 case '1':
creatron 11:ca1e0ca3a673 100 // this was designed to send binary packets (structure), thus
creatron 11:ca1e0ca3a673 101 // if you want to send null terminated strings one could
creatron 11:ca1e0ca3a673 102 // just use the strlen() function for the amount of bytes
creatron 11:ca1e0ca3a673 103 // to be send, the transmission (send_packet) will happily send zeros
creatron 11:ca1e0ca3a673 104 dlms.send_packet ("\r\nSend test packet to RS485\r\n", 29);
creatron 1:7091401482c5 105 break;
creatron 1:7091401482c5 106 }
creatron 11:ca1e0ca3a673 107 // show some stats .. keep em happy
creatron 6:70460dcbc43c 108 debugger.printf (">> %c 0x%02X IRQ rxcount=%5ld txcount=%5ld Dir_485=%d\r\n", ch, ch,
creatron 3:29454cac7930 109 dlms.ret_rx_irq_count(),
creatron 6:70460dcbc43c 110 dlms.ret_tx_irq_count(),
creatron 6:70460dcbc43c 111 dlms.ret_dir_485());
creatron 1:7091401482c5 112 }
creatron 11:ca1e0ca3a673 113 // if any char received on the RS485 bus, display it ..
creatron 11:ca1e0ca3a673 114 // assumes this is printable
creatron 3:29454cac7930 115 if (dlms.char_available())
creatron 3:29454cac7930 116 {
creatron 11:ca1e0ca3a673 117 ch = dlms.get_char();
creatron 11:ca1e0ca3a673 118 debugger.printf("RX Char %c 0x%02X\r\n", ch, ch);
creatron 3:29454cac7930 119 }
creatron 0:044dfba47660 120 }
creatron 0:044dfba47660 121 while (1);
creatron 0:044dfba47660 122 }
creatron 0:044dfba47660 123 //----[ then end]-------------------------------------------------------------
creatron 0:044dfba47660 124
creatron 0:044dfba47660 125