CẨM NANG STM32 CĂN BẢN CẦN BIẾT – USART – API USART và FreeRTOS

API USART

Để tham khảo, dưới đây là danh sách API (Application Programming Interface: Giao diện Lập trình Ứng dụng) được sử dụng trong chương này và ghi lại các đối số của nó. Ngoài ra, các hàm API nâng cao được bao gồm để lưu tham chiếu ở một nơi.

Đối với các hàm được liệt kê, một số đối số cần các giá trị đặc biệt, được cung cấp bởi các macro libopencm32 được định nghĩa. Chúng được liệt kê trong Bảng 6-1 đến 6-7. Chú thích bảng liệt kê tên đối số mà các giá trị tham chiếu đến. Ví dụ, Bảng 6-2 liệt kê các tên macro hợp lệ cho đối số parity.

Bảng 6-1 Liệt kê các USART khác nhau có sẵn cho thiết bị STM32F103C8T6. Các chân mặc định được liệt kê cho từng hàm. Ví dụ, USART2 nhận trên chân PA3 theo mặc định trừ khi cấu hình chức năng thay thế I/O đã được áp dụng.

Bảng 6-1. USARTS Có sẵn cho STM32F103C8T6 (Đối số usart)

USARTMacro5VTXRXCTSRTS
1USART1YesPA9PA10PA11PA12
2USART2NoPA2PA3PA0PA1
3USART3YesPB10PB11PB14PB12

Bảng 6-2. Macro Chẵn-lẻ USART (Đối số Parity)

MacroMô tả
USART_PARITY_NONEKhông parity
USART_PARITY_EVENParity chẵn
USART_PARITY_ODDParity lẻ
USART_PARITY_MASKMask

Bảng 6-3. Macro Chế độ Hoạt động USART (Đối số Mode)

MacroMô tả
USART_MODE_RXChỉ Nhận
USART_MODE_TXChỉ Truyền
USART_MODE_TX_RXTruyền và Nhận
USART_MODE_MASKMask

Bảng 6-4. Macro Bit Dừng USART (Đối số Stopbit)

MacroMô tả
USART_STOPBITS_0_50.5 stop bits
USART_STOPBITS_11 stop bit
USART_STOPBITS_1_51.5 stop bits
USART_STOPBITS_22 stop bits

Bảng 6-5. Macro Điều khiển Luồng

MacroMô tả
USART_FLOWCONTROL_NONEKhông điều khiển luồng phần cứng (HFC)
USART_FLOWCONTROL_RTSRTS HFC
USART_FLOWCONTROL_CTSCTS HFC
USART_FLOWCONTROL_RTS_CTSRTS và CTS HFC
USART_FLOWCONTROL_MASKMask

Bảng 6-6. Bit Dữ liệu USART (Đối số Bits)

Giá trịBit Data (không Parity)Bit Data (có Parity)
887
998

Bảng 6-7. Bit Cờ Trạng thái USART (Đối số Flag)

MacroMô tả Cờ
USART_SR_CTSCờ Clear to Send
USART_SR_LBDCờ LIN break-detection
USART_SR_TXEBộ đệm truyền dữ liệu trống
USART_SR_TCHoàn tất truyền
USART_SR_RXNEThanh-ghi Đọc Dữ liệu không trống
USART_SR_IDLEPhát hiện đường truyền nghỉ (idle)
USART_SR_ORELỗi truyền tràn
USART_SR_NECờ lỗi nhiễu
USART_SR_FELỗi Framing
USART_SR_PELỗi Parity

=> Bài viết được trích từ sách : Cẩm nang STM32 (tập 1)

File include

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>

Xung (Clock)

rcc_periph_clock_enable(RCC_GPIOx);
rcc_periph_clock_enable(RCC_USARTn);

Cấu hình

void usart_set_mode(uint32_t usart, uint32_t mode);
void usart_set_baudrate(uint32_t usart, uint32_t baud);
void usart_set_databits(uint32_t usart, uint32_t bits);
void usart_set_stopbits(uint32_t usart, uint32_t stopbits);
void usart_set_parity(uint32_t usart, uint32_t parity);
void usart_set_flow_control(uint32_t usart, uint32_t flowcontrol);
void usart_enable(uint32_t usart);
void usart_disable(uint32_t usart);

DMA

void usart_enable_rx_dma(uint32_t usart);
void usart_disable_rx_dma(uint32_t usart);
void usart_enable_tx_dma(uint32_t usart);
void usart_disable_tx_dma(uint32_t usart);

Ngắt

void usart_enable_rx_interrupt(uint32_t usart);
void usart_disable_rx_interrupt(uint32_t usart);
void usart_enable_tx_interrupt(uint32_t usart);
void usart_disable_tx_interrupt(uint32_t usart);
void usart_enable_error_interrupt(uint32_t usart);
void usart_disable_error_interrupt(uint32_t usart);

Input/Output/Status

bool usart_get_flag(uint32_t usart, uint32_t flag)
void usart_send(uint32_t usart, uint16_t data)
uint16_t usart_recv(uint32_t usart)

=> xem thêm : Lập trình Arm STM32

Các bước chuẩn bị

Ngoại trừ các ngắt và DMA, sau đây là tóm tắt các bước phải được tuần tự chuẩn bị để ngoại vi UART của bạn hoạt động:

  1. Bật xung nhịp GPIO thích hợp cho tất cả các chân I/O liên quan: rcc_periph_clock_enable(RCC_GPIOx).
  2. Kích hoạt xung nhịp cho thiết bị ngoại vi UART đã chọn của bạn: rcc_periph_clock_enable(RCC_USARTn).
  3. Cấu hình chế độ của các chân I/O bằng gpio_set_mode().
  1. Với các chân output, cho đối số thứ ba, chọn GPIO_CNF_OUTPUT_ALTFN_PUSHPULL (lưu ý ALTFN).
  2. Đối với input, hãy chọn GPIO_CNF_INPUT_PULL_UPDOWN hoặc GPIO_CNF_INPUT_FLOAT.
  1. usart_set_baudrate()
  2. usart_set_databits()
  3. usart_set_stopbits()
  4. usart_set_mode()
  5. usart_set_parity()
  6. usart_set_flow_control()
  7. usart_enable()

FreeRTOS

Trong chương này, chúng ta đã sử dụng một số hàm API FreeRTOS mà chúng ta đã thấy trước đây. Chúng sẽ được tóm tắt ở đây nhằm thuận tiện cho bạn.

Tác vụ

Sau đây là các hàm FreeRTOS liên quan đến tác vụ mà chúng ta đã sử dụng để tạo các tác vụ, bắt đầu lập lịch biểu và thực thi delay, tương ứng:

BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode,   // function ptr
    const char * const pcName,   // string name
    unsigned short usStackDepth, // stack size in words
    void *pvParameters,          // Pointer to argument
    uBaseType_t uxPriority,      // Task priority
    TaskHandle_t *pxCreatedTask  // NULL or pointer to task handle
); // Returns: pdPass or errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY
void vTaskStartScheduler(void);  // Start the task scheduler
void vTaskDelay(TickType_t xTicksToDelay);
void taskYIELD();

Giá trị con trỏ pvTaskCode chỉ là một con trỏ chỉ đến một hàm có dạng như sau:

void my_task(void *args)

Giá trị được cung cấp cho args đến từ pvParameters trong hàm gọi xTaskCreate(). Nếu không được yêu cầu, giá trị này có thể được cung cấp với NULL. Kích thước ngăn xếp (stack) tính theo word (mỗi word 4 byte).

Mỗi tác vụ có một ưu tiên liên quan và được cung cấp bởi đối số uxPriority. Nếu bạn đang chạy tất cả các tác vụ có cùng mức độ ưu tiên, hãy cung cấp giá trị configMAX_PRIORITIES-1, hoặc chỉ sử dụng giá trị 1. Trừ khi bạn cần các mức độ ưu tiên khác nhau, hãy đặt tất cả chúng thành cùng một giá trị (xem Chương 21, “Khắc phục sự cố”). Lưu ý rằng bạn có thể tạo nhiều tác vụ hơn sau khi vTaskStartScheduler() đã được gọi, khi cần thiết.

Một macro thường được sử dụng cho vTaskDelay() là như sau:

pdMS_TO_TICKS(ms)     // Macro: convert ms to ticks

Macro này chuyển đổi mili-giây thành nhịp (tick) để thuận tiện cho lập trình.

Hàng đợi

Các hàm API hàng đợi được sử dụng trong chương này bao gồm:

QueueHandle_t xQueueCreate(
    UBaseType_t uxQueueLength,  // Max # of items
    UBaseType_t uxItemSize      // Item size (bytes)
);                              // Returns: handle else NULL
BaseType_t xQueueSend(
    QueueHandle_t xQueue,       // Queue handle
    const void *pvItemToQueue,  // pointer to item
    TickType_t xTicksToWait     // 0, ticks or portMAX_DELAY
);                              // Returns: pdPASS or errQUEUE_FULL
BaseType_t xQueueReceive(
    QueueHandle_t xQueue,       // Queue handle
    void *pvBuffer,             // Pointer to receiving item buffer
    TickType_t xTicksToWait     // 0, ticks or portMAX_DELAY
);

Hàm xQueueCreate() phân bổ lưu trữ cho hàng đợi đã tạo, và xử lý được trả về. Đối số uxQueueLength cho biết số lượng tối đa các mục có thể được giữ trong hàng đợi. Giá trị uxItemSize chỉ định kích thước của từng mục.

Hàm xQueueSend() thêm một mục vào hàng đợi. Mục được trỏ tới bởi pvItemToQueue được sao chép vào bộ nhớ của hàng đợi. Ngược lại, xQueueReceive() lấy một mục từ hàng đợi và sao chép nó vào bộ nhớ của người gọi tại địa chỉ pvBuffer. Bộ đệm này phải có kích thước ít nhất bằng với kích thước được cho bởi uxItemSize, nếu không sẽ gây tràn bộ nhớ. Nếu không có mục nào được nhận, hàm gọi sẽ chặn theo xTicksToWait.

=> Sách Arduino, ESP8266, STM32 : Sách tự động hóa

Tóm tắt

Chương này đã trình bày hướng dẫn chung cho việc cấu hình và kích hoạt USART ở chế độ không đồng bộ. Điều này cho phép Blue Pill gửi dữ liệu đến máy tính để gỡ lỗi hoặc bất kỳ báo cáo nào khác.

Đồng thời, một ví dụ minh họa của các tác vụ FreeRTOS và hàng đợi tin nhắn đã được cung cấp. Cách tiếp cận này chia các bên gửi và nhận của ứng dụng thành các nhiệm vụ riêng biệt của chúng. Điều này đơn giản hóa việc lập trình vì mỗi chương trình chỉ cần quan tâm đến chính nó với hoạt động riêng của nó. Hàng đợi tin nhắn cung cấp đường dẫn cho giao tiếp giữa các tác vụ ứng dụng.