Kỹ thuật điện tử & Điện lạnh

Giao tiếp UART với ESP-IDF kiến thức mới năm 2023

Giao tiếp UART với ESP-IDF – Cập nhật kiến thức mới nhất năm 2023

ESP32 tích hợp ba bộ điều khiển UART, có nghĩa là chúng ta có thể có ba kết nối UART khác nhau cùng lúc trên cùng một thiết lập phần cứng. Khi sử dụng bộ phát triển ESP32, một trong những bộ điều khiển UART này được dành riêng cho giao tiếp nối tiếp với PC qua USB cho mục đích lập trình và in nối tiếp. Hàm printf trong các ứng dụng của chúng tôi sử dụng bộ điều khiển UART nàky.
Trong ví dụ này, chúng ta cần hai bảng devkit, chúng ta sẽ kết nối với nó qua UART. Một kit sẽ gắn DHT11 vào nó và nó sẽ gửi kết quả đo nhiệt độ đến ESP32 thứ hai kia. ESP thứ 2 sẽ in kết quả đọc này qua USB và chúng ta có thể theo dõi nó bằng màn hình nối tiếp tích hợp của PlatformIO. Hình sau cho thấy sơ đồ phần cứng kết nối :

Chúng ta cần phát triển hai ứng dụng khác nhau cho ESP32-1 (người gửi) và ESP32-2 (người nhận). ESP32-1 sẽ đọc từ DHT11 và truyền đọc qua chân UART2-TX. ESP32-2 sẽ đợi dữ liệu từ chân UART2-RX của nó và sẽ in kết quả đọc trên màn hình nối tiếp khi nó đã được nhận. Hãy bắt đầu với ứng dụng ESP32-1:

#include "dht.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdint.h>
#include "driver/uart.h"
#define DHT11_PIN 18
#define UART_PORT UART_NUM_2
#define TXD_PIN 17
#define RXD_PIN 16
#define UART_BUFF_SIZE 1024

Ở đây, chúng ta bao gồm trình điều khiển / uart.h cho chức năng UART.chúng ta cũng xác định các chân truyền và nhận dữ liệu, tương ứng là chân 17 và chân 16. Ngoài ra, chúng ta xác định kích thước của buffer nhận. Mặc dù chúng ta sẽ không sử dụng nó vì ứng dụng này dành cho người gửi,tuy nhiên trình điều khiển UART vẫn yêu cầu nó. Tiếp theo, chúng tôi khởi tạo phần cứng:

static void init_hw(void)
{
const uart_config_t uart_config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(UART_PORT, UART_BUFF_SIZE, 0, 0, NULL,
0);
uart_param_config(UART_PORT, &uart_config);
uart_set_pin(UART_PORT, TXD_PIN, RXD_PIN, UART_PIN_NO_
CHANGE, UART_PIN_NO_CHANGE);
}

Trong hàm init_hw, chúng ta xác định một biến cấu hình, uart_config, chứa cài đặt cần thiết cho giao tiếp UART. Hàm uart_driver_install dự trữ bộ điều khiển UART và bộ nhớ đệm RX / TX. Chúng ta chuyển 0 (không) làm kích thước bộ đệm cho TX, làm cho hàm truyền chặn tác vụ gọi cho đến khi tất cả dữ liệu được gửi đi. Điều đó là tốt cho các mục đích của chúng tôi trong ví dụ này. Sau đó, chúng ta thiết lập các tham số giao tiếp UART bằng cách gọi uart_param_config với biến uart_config, mà ta đã xác định trước đó. Cuối cùng, đặt các chân RX / TX với hàm uart_set_pin. Bây giờ, chúng ta đã có thể sẵn sàng gửi dữ liệu DHT11 tới ESP32 nhận qua UART:

static void read_dht11(void *arg)
{
int16_t humidity = 0, temperature = 0;
char buff[1];
while (1)
{
vTaskDelay(2000 / portTICK_PERIOD_MS);
dht_read_data(DHT_TYPE_DHT11, (gpio_num_t)DHT11_PIN,
&humidity, &temperature);
buff[0] = (char)(temperature / 10);
uart_write_bytes(UART_PORT, buff, 1);
}
}
void app_main()
{
init_hw();
xTaskCreate(read_dht11, "dht11", configMINIMAL_STACK_SIZE *
8, NULL, 5, NULL);
}

Trong read_dht11, ta đọc giá trị nhiệt độ từ DHT11 sau mỗi 2 giây. Chúngta cập nhật bộ đệm với giá trị nhiệt độ vừa được đọc và gọi uart_write_bytes với kênh UART, bộ đệm và kích thước bộ đệm làm tham số. Trong app_main, chúng ta chỉ cần gọi init_hw và tạo một tác vụ để chuyển điều khiển đến read_dht11. Đó là tất cả cho bên gửi. Bây giờ, chúng ta có thể chuyển sang bên nhận với ESP32-2:

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdint.h>
#include "driver/uart.h"
#include <stdio.h>
#define UART_PORT UART_NUM_2
#define TXD_PIN 17
#define RXD_PIN 16
#define UART_BUFF_SIZE 1024
static void init_hw(void)
{
const uart_config_t uart_config = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
uart_driver_install(UART_PORT, UART_BUFF_SIZE, 0, 0, NULL,
0);
uart_param_config(UART_PORT, &uart_config);
uart_set_pin(UART_PORT, TXD_PIN, RXD_PIN, UART_PIN_NO_
CHANGE, UART_PIN_NO_CHANGE);
}

Tương tự với bên gửi, điều quan trọng trong giao tiếp UART giữa hai ESP này là tốc độ truyền, bit chẵn lẻ, bit stop và bit dữ liệu phải giống nhau nếu không sẽ gây sai lệch dữ liệu khi nhận.

Tiếp theo, chúng ta triển khai một hàm đọc UART :

 

static void read_uart(void *arg)
{
uint8_t buff[UART_BUFF_SIZE];
while (1)
{
if (uart_read_bytes(UART_PORT, buff, UART_BUFF_SIZE,
2000 / portTICK_PERIOD_MS) > 0)
{
printf("temp: %dn", (int)buff[0]);
}
}
}

Trong hàm read_uart, chúng ta gọi uart_read_bytes với tham số buff mà dữ liệu nhận được sẽ được ghi vào. Hàm uart_read_bytes đợi trong 2 giây và nếu đã nhận được bất kỳ thứ gì, thì hàm này sẽ được in trên màn hình nối tiếp. Chúng ta có thể đặt giá trị thời gian chờ cho bất kỳ thứ gì; tuy nhiên, chúng ta biết rằng người gửi sẽ gửi kết quả đọc nhiệt độ cứ sau 2 giây, vì vậy giá trị thời gian chờ này phù hợp với bài toán. Trong hàm app_main, chúng ta chỉ cần khởi tạo phần cứng và bắt đầu tác vụ FreeRTOS với read_uart, như sau:

 

void app_main()
{
init_hw();
xTaskCreate(read_uart, "uart", configMINIMAL_STACK_SIZE *
8, NULL, 5, NULL);
}

Bây giờ chúng ta đã hoàn thành mã của chương trình và đã sẵn sàng để chạy. Khi chúng ta kết nối với bộ thu thông qua màn hình nối tiếp, chúng ta sẽ thấy rằng một số dữ liệu nhiệt độ được in trên màn hình sau mỗi 2 giây. Giao tiếp UART rất hữu ích khi chúng ta cần kết nối hai MCU khác nhau để trao đổi dữ liệu giữa chúng.Với những ứng dụng cao cấp hơn, nhiều khi ta phải đóng gói dữ liệu để gửi đi, và bên nhận sẽ phải giải mã bản tin nhận được để có được dữ liệu. Trong phần tiếp theo, chúng ta sẽ tìm hiểu cách thêm khả năng tạo file âm thanh vào các dự án ESP32 của chúng ta.

Chúc các bạn học tập thật tốt !!!

Series Navigation

<< Lập trình ESP-IDF cảm biến chạm sử dụng FreeRtosLập trình ESP-IDF giao tiếp với file âm thanh sử dụng giao thức I2S (P1) >>

Kết thúc
Ngoài các bài viết tin tức, bài báo hàng ngày của https://www.kythuatcodienlanh.com/, nguồn nội dung cũng bao gồm các bài viết từ các cộng tác viên chuyên gia đầu ngành về chuỗi kiến thức kỹ thuật điện, điện lạnh, điện tử, cơ khí,…,.. được chia sẽ chủ yếu từ nhiều khía cạnh liên quan chuỗi kiến thức này.
Bạn có thể dành thời gian để xem thêm các chuyên mục nội dung chính với các bài viết tư vấn, chia sẻ mới nhất, các tin tức gần đây từ chuyên gia và đối tác của Chúng tôi. Cuối cùng, với các kiến thức chia sẻ của bài viết, hy vọng góp phần nào kiến thức hỗ trợ cho độc giả tốt hơn trong hoạt động nghề nghiệp cá nhân!
* Ý kiến được trình bày trong bài viết này là của tác giả khách mời và không nhất thiết phải là SEMTEK. Nhân viên tác giả, cộng tác viên biên tập sẽ được liệt kê bên cuối bài viết.
Trân trọng,
Các chuyên mục nội dung liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button