Bài 11: Lập trình STM32 với Giao thức UART

Giao thức UART với STM32

Lập trình STM32 với Giao thức UART sẽ cung cấp cho các bạn kiến thức

  • Giao thức UART là gì
  • Cách cấu hình giao thức UART STM32 trên Cube MX
  • Cách sử dụng giao thức UART trong lập trình

Bài 11 thuộc serie Học lập trình STM32 từ A tới Z

Giao thức UART là gì?

Khái quát về UART

UART tiếng anh là Universal Asynchronous Reciver/Transmister   một chuẩn giao tiếp không đồng bộ cho MCU và các thiết bị ngoại vi.

Chuẩn UART là chuẩn giao tiếp điểm và điểm, nghĩa là trong mạng chỉ có hai thiết bị đóng vai trò là transmister hoặc reciver.

h1 3

Cách hoạt động của giao thức UART

UART là giao thức truyền thông không đồng bộ, nghĩa là không có xung Clock, các thiết bị có thể hiểu được nhau nếu các Setting giống nhau

UART là truyền thông song công(Full duplex) nghĩa là tại một thời điểm có thể truyền và nhận đồng thời.

Trong đó quan trọng nhất là Baund rate (tốc độ Baund)  là khoảng thời gian dành cho 1 bit được truyền. Phải được cài đặt giống nhau ở gửi và nhận.

Sau đó là định dạng gói tin.

Định dạng gói tin như sau:

H2 1

Start – Bit

Start-bit còn được gọi là bit đồng bộ hóa được đặt trước dữ liệu thực tế. Nói chung, một đường truyền dữ liệu không hoạt động được điều khiển ở mức điện áp cao. Để bắt đầu truyền dữ liệu, truyền UART kéo đường dữ liệu từ mức điện áp cao (1) xuống mức điện áp thấp (0). UART thu được thông báo sự chuyển đổi này từ mức cao sang mức thấp qua đường dữ liệu cũng như bắt đầu hiểu dữ liệu thực. Nói chung, chỉ có một start-bit.

Stop – Bit

Bit dừng được đặt ở phần cuối của gói dữ liệu. Thông thường, bit này dài 2 bit nhưng thường chỉ sử dụng 1 bit. Để dừng sóng, UART giữ đường dữ liệu ở mức điện áp cao.

Partity Bit

Bit chẵn lẻ cho phép người nhận đảm bảo liệu dữ liệu được thu thập có đúng hay không. Đây là một hệ thống kiểm tra lỗi cấp thấp & bit chẵn lẻ có sẵn trong hai phạm vi như Chẵn lẻ – chẵn lẻ cũng như Chẵn lẻ – lẻ. Trên thực tế, bit này không được sử dụng rộng rãi nên không bắt buộc.

Data frame

Các bit dữ liệu bao gồm dữ liệu thực được truyền từ người gửi đến người nhận. Độ dài khung dữ liệu có thể nằm trong khoảng 5 & 8. Nếu bit chẵn lẻ không được sử dụng thì chiều dài khung dữ liệu có thể dài 9 bit. Nói chung, LSB của dữ liệu được truyền trước tiên sau đó nó rất hữu ích cho việc truyền.

Cấu hình giao thức UART STM32 trong Cube MX

Ở bài này chúng ta sẽ thực hành truyền UART từ bộ UART1 lên máy tính, sử dụng Baundrate = 9600, các setup khác để mặc định.
Trong chế độ sử dụng ngắt ta sẽ kiểm tra chuỗi gửi đến, nếu thấy kí tự Enter thì gửi ngược lại

Trong chế độ DMA ta sẽ sử dụng truyền thẳng vào Buffer để biết cách hoạt động của ngắt và DMA

Các bạn phải chuẩn bị bộ chuyển đổi UART to USB như Bài 1 mình giới thiệu, và phần mềm Hercules Terminal.

Xem hướng dẫn tại: Hướng dẫn sử dụng Hercules Terminal

Đầu tiên các bạn mở CubeMX lên, Chọn chip STM32F103C8, trong SYS debug chọn Serial Wire. Mình đã nói rõ trong Bài 3 nhé.

Trong Tab UART chọn UART1

H3 8

Mode: Asynchronous  (không đồng bộ)

Hard ware: Disable

NVIC Setting Tick vào bật ngắt UART

H4 7

Đặt tên chọn tool chain rồi Gen code

H5 8

Lập trình giao thức UART trên Keil C

Mở project trong main.c cấu hình như sau.

Khởi tạo 2 Buffer để truyền nhận dữ liệu

1 biến nhận Rx data

1 biến lưu giá trị con trỏ ghi vào Rx Buffer

1 Cờ báo nhận thành công để gửi TX

H6 8

Tìm hàm RxCpltCallback sau đó cấu hình như sau

H7 10

Nếu u8_RxData nhận được là khác kí tự Enter (giá trị 13 trong bảng ASCII), ghi giá trị u8_RxData vào u8_RxBuf sau đó tăng giá trị _RxIndex

Nếu RxData là kí tự Enter, xóa biến _RxIndex về 0 và bật cờ Tx

Gọi hàm HAL_UART_Receive_IT(&huart1, &u8_RxData, 1); để tiếp tục nhận dữ liệu nếu có dữ liệu truyền qua.

Trước main chúng ta gửi UART dữ liệu ban đầu trong u8_TxBuff  là Hello anh em!!!

Sau đó bật nhận dữ liệu bằng Ngắt

H8 8

Trong while(1)

Kiểm tra cờ truyền UART nếu được bật lên.

Sao chép giá trị RxBuff cho TxBuff, sau đó truyền đi và xóa cờ TX

Nhấn F7 Build và nạp chương trình vào chip.

Kết nối STM32 vào UART to USB

H9

Sau đó bật Hercules terminal lên, kiểm tra cổng kết nối với UART to USB bằng cách nhấn chuột phải vào biểu tượng My computer -> manager

H10 7

Mở tab Device -> Ports ta thấy rằng port đang sử dụng là COM4 với driver là CH340

H11 7

Trong Terminal, chuyển Tab Serial –  Name chọn cổng com bạn đang dùng với mình là COM4

Baud set là 9600, còn lại để mặc định rồi ấn vào Open

H12 6

Nhấn Reset trên mạch để mạch chạy từ đầu. Ta sẽ thấy mạch gửi kí tự đầu tiên. Nhập tin nhắn bạn cần gửi lên mạch và kết thúc là <CR> (kí tự Enter trong ASCII), mạch sẽ gửi lại đúng tin nhắn đó.

H13 4

Truyền nhận dữ liệu bằng DMA

Để truyền nhận dữ liệu sử dụng DMA các bạn làm như sau

Trong CubeMX , Tab UART1 Config-> DMA Settings

Các bạn nhấn Add, DMA request chọn USART1_RX, Mode Circular (chỉ cần gọi 1 lần sẽ truyền liên tục từ ngoại vi về bộ nhớ), Data Width là Byte

H14 4

Nhấn Gen Code và Close

Trong KeilC sẽ báo Reload lại file, bạn nhấn ok

H15 2

Trong hàm callback ta comment hết các hàm trước, viết lại hàm Transmit

H16 2

Trong main() ta gọi hàm Recive_DMA thay cho Recive_IT, và comment toàn bộ While (1)

H17 2

Build và nạp chương trình và xem kết quả.

H18 1

Ta thấy rằng, chỉ khi nhấn đủ 20 giá trị = Độ dài của Rx_Buffer thì chương trình mới nhảy vào ngắt. và truyền dữ liệu lại. Vì vậy truyền UART nên sử dụng các frame có độ dài cố định.

Kết luận

Giao thức UART được sử dụng rất nhiều trong các sản phẩm nhúng. Việc lập trình giao thức này cũng không quá khó khăn, chỉ cần bạn đọc kĩ phần hướng dẫn, chắc chắn sẽ làm được.

5/5 - (1 bình chọn)
0 0 đánh giá
Đánh giá bài viết
Theo dõi
Thông báo của
guest

24 Góp ý
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất
Phản hồi nội tuyến
Xem tất cả bình luận
Nguyễn văn công
Nguyễn văn công
2 năm trước

Mình muốn nhờ chút có cách nào đọc mã giao tiếp giữa 2 con stm32 nối với nhau theo chuẩn uart không, mình đã dùng một mạch USB TTL uart nối song song với dây nối giữa 2 mạch giao đọc bằng máy tính mà mã truyền của nó không đúng.

Manh Duc
Manh Duc
2 năm trước

Em hỏi chút ạ, có cách nào để giao tiếp uart giữa stm32 với esp8266 không. Vì e truyền từ stm32 sang esp8266 1 chuỗi mà n không nhận.

Khoa Đỗ
Khoa Đỗ
2 năm trước
Trả lời  Khuê Nguyễn

Thế e muốn STM đọc ADC rồi UART qua ESP thì làm sao ạ?

Dũng nguyễn
Dũng nguyễn
2 năm trước

Anh ơi cho em hỏi chút với ạ . Cái chỗ Kết nối STM32 vào UART to USB là phải có cái mạch chuyển UART USB mới dùng được cái hercules terminal hả anh.

quang
quang
2 năm trước

vậy để truyền dữ liệu thay đổi( ví dụ nhiệt độ, tốc độ) qua uart thì phải làm ntn ạ

dong tran
dong tran
2 năm trước

Cho em hỏi: Em dùng DMA để nhận dữ liệu, nhưng khi mảng dữ liệu nhận, tràn. Thì nó không ghi đè lên, hay xóa đi các kí tự cũ đi, là sao vậy anh?

Bao.N
Bao.N
2 năm trước

anh ơi cho em hỏi uart giữa stm32 với module R305 có giống với cách anh hướng dẫn không anh

nguyễn tú
nguyễn tú
2 năm trước

cho em hỏi. Truyền một gói tin từ máy tính xuống STM32 có định dạng như sau:
*|X|Data|#( bao gồm 3 byte, trong đó “*” là kí tự bắt đầu,”#” là ký tự kết thúc,”X”( X=1->16) là byte khai báo kích thước của data;” data” là các ký tự, có kích thước từ 1 đến 16byte.
khi nhận đúng định dạng gói tin: hiển thị nội dung gói tin lên LCD 16×2 đồng thời truyền trở về máy tính chữ”OK” thông qua UART. KHi nhận sai gói định dạng: không thay đổi nội dung LCD, đồng thời truyền trở về máy tính chữ” ERROR” thông qua UART

Trường kelvin
Trường kelvin
2 năm trước

anh ơi cho em hỏi làm thế nào để sau khoảng 1-3s thì data truyền sau sẽ ghi đè lên data truyền trc ạ???

Tú Huỳnh
Tú Huỳnh
2 năm trước

bài này anh làm ví dụ hay hơn những người khác lắm luôn.

huy
huy
2 năm trước

lập trình gửi dữ liệu từ Herculus qua protues và
hiển thị dữ liệu lên LCD 16×2 .. thì làm thêm code gì nửa anh ạ

Ngọc
Ngọc
2 năm trước

Anh ơi, nếu em dùng UART từ vi điều khiển qua RS 485 rồi mới vào máy tihs thì cũng làm tương tự đúng không hả anh?
Em cảm ơn ạ!

huynh khanh
huynh khanh
11 tháng trước

anh ơi cho em hỏi là em giao tiếp giữa stm32f411 với máy tình qua con ft232 thì khi nhận dữ liệu nó bị lỗi, em xem baudrate rồi mà vẫn bị

Thắng
Thắng
1 tháng trước

em có làm như a hướng dẫn, nhưng nó chỉ nhận được dữ liệu từ STM32 truyền sang máy tính, nhưng em gửi từ máy tính về STM32 thì nó k hiện lên kí tự