Bài viết hướng dẫn cấu hình và sử dụng ngoại vi UART trên Raspberry Pi bằng lệnh trong cửa sổ terminal
Xác định ngoại vi UART và chân GPIO tương ứng trên Raspberry Pi
Các dòng Raspberry Pi khác nhau có thể có số lượng ngoại vi UART và vị trí chân GPIO khác nhau. Tuy nhiên việc cấu hình UART về cơ bản là giống nhau về cú pháp, chỉ khác nhau về vị trí chân GPIO.
Để đơn giản mình sẽ lấy ví dụ về cấu hình UART trên Raspberry Pi 4. Trên raspberry Pi 4 hỗ trợ 5 UART, nhiều bài viết hướng dẫn chỉ nhắc đến UART mặc định là UART0, tuy nhiên mình sẽ hướng dẫn các bạn có thể sử dụng tối đa số lượng UART mà Raspberry Pi 4 hỗ trợ.
Cấu hình UART sử dụng câu lệnh trong cửa sổ terminal
Đăng nhập vào Raspberry Pi
Các bạn có thể kết nối SSH từ máy tính cá nhân đến Raspberry Pi hoặc thao tác trực tiếp trên Raspberry Pi để mở cửa sổ terminal. Ở đây mình sẽ kết nối SSH từ máy tính cá nhân với Raspberry Pi để mở cửa sổ terminal. Sau khi kết nối và đăng nhập được vào Raspberry Pi, cửa sổ terminal sẽ có dạng như hình bên dưới:
Các bước cấu hình UART
Bước 1: Mở tệp config.txt để tiến hành chỉnh sửa, cấu hình UART
Nhập lệnh: sudo nano /boot/config.txt hoặc sudo nano /boot/firmware/config.txt
Sau khi nhập lệnh trên, bạn sẽ thấy nội dung file config.txt chứa các thông tin về cấu hình của các ngoại vi trên Raspberry Pi.
Bước 2: Kéo xuống cuối tệp và sau đó thêm vào đoạn nội dung sau:
enable_uart=1
dtoverlay=uart1
dtoverlay=uart4,txd0_pin=8,rxd0_pin=9
dtoverlay=uart3,txd0_pin=4,rxd0_pin=5
dtoverlay=uart5,txd0_pin=12,rxd0_pin=13
Ý nghĩa của 3 dòng lệnh trên:
- Dòng lệnh thứ 1 sử dụng để Raspberry Pi biết nội dung bên dưới là cấu hình các ngoại vi UART
- Dòng lệnh thứ 2 là enable uart0 (là uart mặc định của Raspberry Pi với TX tương ứng là GPIO14, RX tương ứng là GPIO 15)
- Dòng lệnh thứ 3 là enable uart4, với TX là GPIO8, RX là GPIO9
- Dòng lệnh thứ 4 là enable uart3, với TX là GPIO4, RX là GPIO5
- Dòng lệnh thứ 5 là enable uart5, với TX là GPIO12, RX là GPIO13
Bước 3: nhấn Ctrl S để lưu và nhấn Ctrl X để thoát khỏi tệp và dùng lệnh sudo poweroff để khởi động lại raspberry pi.
Các bạn có thể kiểm tra xem mình cấu hình đã đúng chưa bằng cách nhập lệnh raspi-gpio get. Lúc này trên màn hình sẽ hiển thị chi tiết các chân GPIO được sử dụng cho mục đích gì. Ở đây các bạn có thể thấy đã kích hoạt thành công UART0 và UART3 và các chân GPIO tương ứng
Bước 4: kiểm tra tên của uart bằng cách vào lệnh ls /dev/ | grep tty
Lúc này màn hình sẽ hiện ra kiểu ttyS0, ttyAMA3, ttyAMA4, ttyAMA5 v.v.. Đây là tên của các UART bạn vừa khởi tạo tương ứng với uart0, uart3, uart4, uart5
Bước 5: thêm người dùng hiện tại vào nhóm dialout để có quyền truy cập vào thiết bị tty bằng cách vào lệnh: sudo usermod -aG dialout $USER
Bước 6: Cấu hình baudrate
Trước hết xem cấu hình hiện tại, ví dụ UART mình muốn xem là: stty -F /dev/ttyAMA3 -a
Sau đó bạn có thể cấu hình tốc độ mong muốn, ví dụ baudrate là 9600: stty -F /dev/ttyAMA3 115200
Kiểm tra lại xem cấu hình thành công chưa bằng lệnh: stty -F /dev/ttyAMA3 -a
Bước 7: Kết nối UART với máy tính bằng USB to COM (CH340, FT232 hoặc CP2102…v.v) và hập lệnh: echo “Hello, UART!” > /dev/ttyAMA3, chuỗi “Hello, UART!” sẽ được gửi đến máy tính của bạn.
Chương trình giao tiếp UART bằng ngôn ngữ Python và C
Sau khi các bạn bật các ngoại vi UART xong, tiếp theo mình sẽ làm ví dụ minh họa cách viết chương trình giao tiếp UART trên Raspberry Pi bằng ngôn ngữ lập trình Python và C
Python:
import serial
import time
# Cấu hình UART
ser = serial.Serial('/dev/ttyAMA3', 115200, timeout=1)
time.sleep(2) # Chờ kết nối ổn định
# Gửi dữ liệu
ser.write(b'Hello from Raspberry Pi!\n')
print("Data sent: Hello from Raspberry Pi!")
# Nhận dữ liệu
while True:
data = ser.readline().decode().strip()
if data:
print(f"Received: {data}")
ser.close()
C:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#define UART_PORT "/dev/ttyAMA3" // Cổng UART trên Raspberry Pi
int main() {
int uart0_filestream = open(UART_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
if (uart0_filestream == -1) {
printf("Error - Unable to open UART\n");
return -1;
}
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
// Gửi dữ liệu
char tx_buffer[] = "Hello from C program!\n";
int count = write(uart0_filestream, tx_buffer, strlen(tx_buffer));
if (count < 0) {
printf("UART TX error\n");
} else {
printf("Sent: %s", tx_buffer);
}
// Nhận dữ liệu
char rx_buffer[256];
while (1) {
int rx_length = read(uart0_filestream, rx_buffer, 255);
if (rx_length > 0) {
rx_buffer[rx_length] = '\0';
printf("Received: %s\n", rx_buffer);
}
}
close(uart0_filestream);
return 0;
}
Chúc các bạn thành công!