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.
main.cpp@11:ca1e0ca3a673, 2014-11-23 (annotated)
- 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?
User | Revision | Line number | New 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 |