rs485_example.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /* Uart Events Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "freertos/FreeRTOS.h"
  11. #include "freertos/task.h"
  12. #include "esp_system.h"
  13. #include "nvs_flash.h"
  14. #include "driver/uart.h"
  15. #include "freertos/queue.h"
  16. #include "esp_log.h"
  17. #include "sdkconfig.h"
  18. /**
  19. * This is a example which echos any data it receives on UART back to the sender using RS485 interface in half duplex mode.
  20. */
  21. #define TAG "RS485_ECHO_APP"
  22. // Note: Some pins on target chip cannot be assigned for UART communication.
  23. // Please refer to documentation for selected board and target to configure pins using Kconfig.
  24. #define ECHO_TEST_TXD (CONFIG_ECHO_UART_TXD)
  25. #define ECHO_TEST_RXD (CONFIG_ECHO_UART_RXD)
  26. // RTS for RS485 Half-Duplex Mode manages DE/~RE
  27. #define ECHO_TEST_RTS (CONFIG_ECHO_UART_RTS)
  28. // CTS is not used in RS485 Half-Duplex Mode
  29. #define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)
  30. #define BUF_SIZE (127)
  31. #define BAUD_RATE (CONFIG_ECHO_UART_BAUD_RATE)
  32. // Read packet timeout
  33. #define PACKET_READ_TICS (100 / portTICK_PERIOD_MS)
  34. #define ECHO_TASK_STACK_SIZE (2048)
  35. #define ECHO_TASK_PRIO (10)
  36. #define ECHO_UART_PORT (CONFIG_ECHO_UART_PORT_NUM)
  37. // Timeout threshold for UART = number of symbols (~10 tics) with unchanged state on receive pin
  38. #define ECHO_READ_TOUT (3) // 3.5T * 8 = 28 ticks, TOUT=3 -> ~24..33 ticks
  39. static void echo_send(const int port, const char* str, uint8_t length)
  40. {
  41. if (uart_write_bytes(port, str, length) != length) {
  42. ESP_LOGE(TAG, "Send data critical failure.");
  43. // add your code to handle sending failure here
  44. abort();
  45. }
  46. }
  47. // An example of echo test with hardware flow control on UART
  48. static void echo_task(void *arg)
  49. {
  50. const int uart_num = ECHO_UART_PORT;
  51. uart_config_t uart_config = {
  52. .baud_rate = BAUD_RATE,
  53. .data_bits = UART_DATA_8_BITS,
  54. .parity = UART_PARITY_DISABLE,
  55. .stop_bits = UART_STOP_BITS_1,
  56. .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
  57. .rx_flow_ctrl_thresh = 122,
  58. .source_clk = UART_SCLK_DEFAULT,
  59. };
  60. // Set UART log level
  61. esp_log_level_set(TAG, ESP_LOG_INFO);
  62. ESP_LOGI(TAG, "Start RS485 application test and configure UART.");
  63. // Install UART driver (we don't need an event queue here)
  64. // In this example we don't even use a buffer for sending data.
  65. ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0));
  66. // Configure UART parameters
  67. ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
  68. ESP_LOGI(TAG, "UART set pins, mode and install driver.");
  69. // Set UART pins as per KConfig settings
  70. ESP_ERROR_CHECK(uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));
  71. // Set RS485 half duplex mode
  72. ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
  73. // Set read timeout of UART TOUT feature
  74. ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, ECHO_READ_TOUT));
  75. // Allocate buffers for UART
  76. uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
  77. ESP_LOGI(TAG, "UART start recieve loop.\r");
  78. echo_send(uart_num, "Start RS485 UART test.\r\n", 24);
  79. while (1) {
  80. //Read data from UART
  81. int len = uart_read_bytes(uart_num, data, BUF_SIZE, PACKET_READ_TICS);
  82. //Write data back to UART
  83. if (len > 0) {
  84. echo_send(uart_num, "\r\n", 2);
  85. char prefix[] = "RS485 Received: [";
  86. echo_send(uart_num, prefix, (sizeof(prefix) - 1));
  87. ESP_LOGI(TAG, "Received %u bytes:", len);
  88. printf("[ ");
  89. for (int i = 0; i < len; i++) {
  90. printf("0x%.2X ", (uint8_t)data[i]);
  91. echo_send(uart_num, (const char*)&data[i], 1);
  92. // Add a Newline character if you get a return charater from paste (Paste tests multibyte receipt/buffer)
  93. if (data[i] == '\r') {
  94. echo_send(uart_num, "\n", 1);
  95. }
  96. }
  97. printf("] \n");
  98. echo_send(uart_num, "]\r\n", 3);
  99. } else {
  100. // Echo a "." to show we are alive while we wait for input
  101. echo_send(uart_num, ".", 1);
  102. ESP_ERROR_CHECK(uart_wait_tx_done(uart_num, 10));
  103. }
  104. }
  105. vTaskDelete(NULL);
  106. }
  107. void app_main(void)
  108. {
  109. //A uart read/write example without event queue;
  110. xTaskCreate(echo_task, "uart_echo_task", ECHO_TASK_STACK_SIZE, NULL, ECHO_TASK_PRIO, NULL);
  111. }