Title Image

Blog Logo

STM 13. USART: Cấu hình Baudrate

🌱 STM 13. USART: Cấu hình Baudrate

    Ở những post trước mình đã giới thiệu về giao thức USART và các thanh ghi được sử dụng với ngoại vi USART trong vi điều khiển STM32F401. Trong khi tìm hiểu về ngoại vi này, có hai vấn đề nổi lên mà các bạn thường thắc mắc: Thứ nhất là vấn đề tính Baudrate như thế nào? Và thứ hai là vấn đề về Parity hoạt động như thế nào? Vậy ở post này mình sẽ chia sẻ những hiểu biết của mình về vấn đề thứ nhất: USART Baudrate.

    👉 USART Baudrate in STM32

    Về cơ bản thì tốc độ Baudrate của ngoại vi USART được cấu hình bằng thanh ghi USART_BRR (Cần cấu hình trước khi Enable ngoại vi bằng các bit TE/RE):
    

  • Các bit[11:0] - DIV_Mantissa: là thành phần đứng trước dấu phẩy.
  • Các bit[3:0] - DIV_Fraction: là thành phần đứng sau dấu phẩy.
    👉 Công việc cần làm là tính toán giá trị nạp vào các bit này, bằng cách tính USARTDIV.
    👉 Khi thực hành với ngoại vi USART, các bạn có 2 cách để chọn Baudrate:
  1. Các thứ nhất đó là tra bảng (Vi điều khiển nào thì cũng sẽ có những bảng có sẵn cấu hình cần thiết cho các Baudrate thường dùng, cùng với đó là tần số Clock thông dụng).
    Vi điều khiển STM32 cũng cung cấp cho người dùng các bảng tính toán sẵn Baudrate trong chương về ngoại vi USART (với STMF401 là chương 19, các bảng từ 74).
    Ví dụ về một bảng tính toán trong Reference Manual

    UART

    Có thể thấy, tốc độ Baudrate sẽ phụ thuộc vào tần số Clock, bit OVER8 của thanh ghi USART_CR1.
  2. Các thứ hai đó là tính theo công thức được cung cấp bởi Reference Manual. Cùng chương USART cũng cung cấp cho người dùng để có thể tự tính toán Baudrate.

    UART

    Công thức Equation 1 là công thức mà chúng ta sẽ sử dụng, nó cũng phụ thuộc vào bit OVER8 cũng như tần số xung Clock.
    👉 Đối với công thức ở phần 2 cần lưu ý:
  • Bit[15] - OVER8 để chọn hệ số chia
    OVER8 = 1, tức là chia cho 8, tương ứng với công thức ở trên thì dưới mẫu là 8.
    OVER8 = 0, tức là chia cho 16, tương ứng với công thức ở trên thì dưới mẫu là 16.
  • Tần số xung clock của mỗi ngoại vi là khác nhau, trong STM32F401 có 6 ngoại vi USART:
    USART1/6 được kết nối với bus APB2 (PCLK2).
    USART2/3/4/5 được kết nối với bus APB1 (PCLK1).

    Sau khi có tần số clock fCLK và bit OVER8, theo công thức trên có thể tính được USARTDIV rồi.
    👉 Vậy làm cách nào từ USARTDIV có thể tính ra giá trị nạp vào thanh ghi USART_BRR, mà cụ thể là 2 phần DIV_Mantissa DIV_Fraction?
    Cụ thể cách tính đơn giản sẽ là như sau:
  • DIV_Mantissa phần nguyên của USARTDIV, vậy ta chỉ cần lấy phần nguyên của USARTDIV là xong.
    DIV_Mantissa = [ USARTDIV ]
    💬 Ví dụ, ta tính ra/hoặc tra bảng có USARTDIV là 52,0625, thì DIV_Mantissa = 52 = 0x34.
  • DIV_Fraction phần thập phân của USARTDIV, ở đây phụ thuộc vào hệ số chia của bit OVER8.
    Nếu bit OVER8 = 1, hệ số chia là 8, tức là DIV_Fraction sẽ bằng phần thập phân của USARTDIV nhân với 8.
    Nếu bit OVER8 = 0, hệ số chia là 16, tức là DIV_Fraction sẽ bằng phần thập phân của USARTDIV nhân với 16.
    DIV_Fraction = { USARTDIV } * 8 / (2 - OVER8)
    💬 Ví dụ, ta tính ra/hoặc tra bảng có USARTDIV là 52,0625
    Với OVER8 = 0 thì DIV_Fraction = 0,0625 * 8 = 1 = 0x01. 
    Trường hợp này nếu OVER8 = 1 thì DIV_Fraction = 0,5, hơi vô lý vì thực tế nếu OVER8 = 1 thì chúng ta sẽ không tính ra USARTDIV lẻ như thế, các bạn có thể tham khảo bảng giá trị trên để biết thêm).

    👉 Ví dụ tính toán

    Ví dụ mình đang muốn cấu hình tần số Baudrate là 9600, và không có sai số. Mình sẽ tính toán giá trị nạp vào thanh ghi USART_BRR theo các bước sau.
  1. Vậy mình sẽ thử tra bảng ở trên (bảng 74). Mình thấy việc sử dụng tần số PCLK = 12MHz thì đem lại việc sai nhỏ 0% nên mình chọn PCLK = 12MHz (Cái này còn phụ thuộc vào tần số thạch anh, cấu hình tần số cho bus ngoại vi của bạn, ở đây ví dụ mẫu nên mình cố định luôn là tra bảng này).
  2. OK, sau khi có tần số PCLK, mình sẽ có 2 bảng, với 2 giá trị khác nhau của bit OVER8. Ở đây mình lấy luôn giá trị ở bảng 74, tức là OVER8 = 0 (hệ số chia là 16). 
  3. Như vậy tương ứng trong bảng 74, chúng ta có USARTDIV = 78.125. Cái này mình hoàn toàn tính tay được bằng công thức sau: 

    UART

  4. Sau đó ta tính 2 thành phần của thanh ghi USART_BRR:
    DIV_Mantissa = [ USARTDIV ] = 78 = 0x04E (vì thành phần này chiếm 12 bit).
    DIV_Fraction = { USARTDIV } * 8 * (2 - OVER8) = 0.125 * 16 = 2 = 0x2.
  5. Cuối cùng ta có thể cấu hình giá trị thanh ghi USART_BRR = 0x0000.04E2.
   Chúc các bạn học tập tốt 😊 

Xem Bài STM 12                 Xem Bài STM 14

Đăng nhận xét

0 Nhận xét