Bỏ qua điều hướng, tới nội dung chính
Học C
Bài 48.426 phút đọc

Đọc datasheet

Sau bài này bạn sẽ làm được

  • Phân biệt datasheet, reference manual, errata và application note
  • Đi theo quy trình tám bước để cấu hình một ngoại vi mới
  • Tra bảng ánh xạ chức năng thay thế cho một chân
  • Biết vì sao errata là tài liệu không được bỏ qua

Reference manual của STM32F4 dài 1750 trang. Không ai đọc hết, và cũng không cần. Kỹ năng thật là biết tra đúng chỗ trong năm phút thay vì mò mẫm trong ba giờ.

#Năm loại tài liệu

Tài liệuĐộ dàiChứa gìTra khi nào
Datasheet150 tới 250 trangSơ đồ chân, đặc tính điện, dòng tiêu thụ, dải nhiệt độ, bảng chức năng thay thếThiết kế mạch, chọn chân, kiểm mức điện áp
Reference manual1000 tới 2000 trangChi tiết mọi thanh ghi của mọi ngoại vi, sơ đồ khối, thuật toán cấu hìnhViết mã, tra bit, hiểu ngoại vi
Errata sheet20 tới 60 trangLỗi phần cứng đã biết và cách néNgay khi bắt đầu dự án, và khi gặp lỗi khó hiểu
Application note20 tới 100 trang mỗi bàiHướng dẫn dùng một ngoại vi cho một việc cụ thểKhi làm một thứ mới, ví dụ nạp chương trình qua UART
Programming manual150 tới 250 trangTập lệnh của lõi Cortex-M, thanh ghi lõi, NVIC, SysTickViết hợp ngữ, xử lý ngoại lệ, tối ưu ở tầng lệnh

#Quy trình tám bước

  1. Tìm chương của ngoại vi trong reference manual

    Mục lục có một chương cho mỗi ngoại vi. Với STM32F401 thì GPIO là chương 8, USART là chương 19, TIM là chương 12 tới 14.

  2. Đọc sơ đồ khối của ngoại vi

    Trang đầu mỗi chương có một sơ đồ khối. Nó cho biết dữ liệu đi từ đâu tới đâu, và khối nào cần bật trước khối nào. Bỏ qua bước này là nguyên nhân chính của việc cấu hình sai thứ tự.

  3. Tra bảng bản đồ bộ nhớ để lấy địa chỉ nền

    Có một bảng chung ở đầu reference manual, thường ở chương về bố cục bộ nhớ.

  4. Tra bản đồ thanh ghi ở cuối chương

    Mỗi chương kết thúc bằng một bảng liệt kê mọi thanh ghi kèm độ dời và giá trị sau reset. Đây là bảng bạn sẽ nhìn nhiều nhất.

  5. Đọc mô tả từng bit của các thanh ghi cần dùng

    Chú ý ký hiệu quyền truy cập: rw đọc ghi được, r chỉ đọc, w chỉ ghi, rc_w1 đọc được và ghi 1 để xóa.

  6. Tra bảng chức năng thay thế nếu dùng chân đặc biệt

    Bảng này ở trong datasheet, không phải reference manual. Đây là chỗ người mới hay tìm nhầm chỗ nhất.

  7. Bật clock cho ngoại vi trong RCC

    Bước bị quên nhiều nhất, xem Bài 47.4. Tra chương RCC để biết ngoại vi nằm trên bus nào và bit nào bật nó.

  8. Cấu hình theo thứ tự tài liệu chỉ, bật khối sau cùng

    Nhiều thanh ghi cấu hình chỉ ghi được khi khối đang tắt. Bật khối là bước cuối, không phải bước đầu.

Ví dụ áp dụng: bật ADC
/* Reference manual muc 11.3.1 "ADC on-off control" ghi ro:

     1. Set ADON bit -> ADC ra khoi che do ngu
     2. CHO t_STAB truoc khi bat dau chuyen doi
     3. Set ADON lan NUA hoac set SWSTART -> bat dau chuyen doi

   Va bang dac tinh trong DATASHEET cho biet t_STAB = 3 micro giay.

   Bo qua buoc 2 thi lan doc dau tien cho gia tri sai. */

ADC1->CR2 |= (1u << 0);      /* buoc 1: ADON */

tre_us(3u);                  /* buoc 2: cho on dinh */

ADC1->CR2 |= (1u << 30);     /* buoc 3: SWSTART */

#Đọc bảng thanh ghi

Một mục thanh ghi điển hình
8.4.1  GPIO port mode register (GPIOx_MODER)

Address offset: 0x00
Reset value:    0xA800 0000 for port A
                0x0000 0280 for port B
                0x0000 0000 for other ports

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
+-----+-----+-----+-----+-----+-----+-----+-----+
|MODER15 |MODER14 |MODER13 |MODER12 |MODER11 |...
+-----+-----+-----+-----+-----+-----+-----+-----+
| rw rw | rw rw | rw rw | rw rw | rw rw | ...

Bits 2y:2y+1  MODERy[1:0]: Port x configuration bits (y = 0..15)
              These bits are written by software to configure
              the I/O direction mode.
                00: Input (reset state)
                01: General purpose output mode
                10: Alternate function mode
                11: Analog mode
Ký hiệuNghĩaVí dụ
rwĐọc và ghi bình thườngGPIO MODER, USART CR1
rChỉ đọc, ghi vào không tác dụngGPIO IDR, USART SR bit RXNE
wChỉ ghi, đọc ra không xác địnhGPIO BSRR
rc_w1Đọc được, ghi 1 để xóaEXTI PR, DMA cờ ngắt
rc_w0Đọc được, ghi 0 để xóaTIM SR
rc_rĐọc được, và chính phép đọc xóa nóVài cờ của ADC
tChỉ đổi được bằng cách ghi giá trị đối lậpHiếm gặp
Res.Dành riêng, phải giữ nguyên giá trị resetNhiều thanh ghi

#Bảng chức năng thay thế

Chức năng thay thế
Mỗi chân GPIO nối được vào tối đa mười sáu ngoại vi khác nhau, đánh số AF0 tới AF15. Đặt MODER thành 10 chỉ nói rằng chân không còn là GPIO thường, còn chọn ngoại vi nào thì nằm ở thanh ghi AFR.
Bảng trong datasheet
Table 9. Alternate function mapping

Port | AF0  | AF1   | AF2   | AF4    | AF5   | AF6   | AF7      | AF9
-----+------+-------+-------+--------+-------+-------+----------+------
PA0  | -    | TIM2  | TIM5  | -      | -     | -     | USART2   | -
     |      | _CH1  | _CH1  |        |       |       | _CTS     |
PA2  | -    | TIM2  | TIM5  | -      | -     | -     | USART2   | -
     |      | _CH3  | _CH3  |        |       |       | _TX      |
PA5  | -    | TIM2  | -     | -      | SPI1  | -     | -        | -
     |      | _CH1  |       |        | _SCK  |       |          |
PA6  | -    | TIM1  | TIM3  | -      | SPI1  | -     | -        | -
     |      | _BKIN | _CH1  |        | _MISO |       |          |
PA9  | -    | TIM1  | -     | I2C3   | -     | -     | USART1   | -
     |      | _CH2  |       | _SMBA  |       |       | _TX      |
PA10 | -    | TIM1  | -     | -      | -     | -     | USART1   | -
     |      | _CH3  |       |        |       |       | _RX      |
doc-bang-af.c
/* Muon dung PA6 lam PWM tu TIM3 kenh 1.
   Tra bang: dong PA6, cot AF2 -> TIM3_CH1. Vay can AF2. */

/* AFR[0] lo chan 0 toi 7, AFR[1] lo chan 8 toi 15.
   Moi chan bon bit. */
static inline void gpio_dat_af(GPIO_TypeDef *cong, uint8_t chan, uint8_t af)
{
    uint8_t  chi_so = (uint8_t)(chan >> 3);          /* 0 hoac 1 */
    uint8_t  vi_tri = (uint8_t)((chan & 7u) * 4u);   /* 0, 4, 8, ... 28 */
    uint32_t r      = cong->AFR[chi_so];

    r &= ~(0xFu << vi_tri);
    r |=  ((uint32_t)(af & 0xFu) << vi_tri);

    cong->AFR[chi_so] = r;
}

void pwm_chan_khoi_tao(void)
{
    RCC->AHB1ENR |= (1u << 0);

    gpio_dat_af(GPIOA, 6u, 2u);                      /* AF2 = TIM3_CH1 */

    GPIOA->MODER &= ~(3u << (6 * 2));
    GPIOA->MODER |=  (2u << (6 * 2));                /* 10 = che do thay the */
}

Công cụ tự sinh mã cấu hình chân

terminal
# STM32CubeMX sinh mã khởi tạo từ giao diện chọn chân
stm32cubemx
Chon chip -> chon chan -> chon ngoai vi -> Generate Code

Sinh ra:
  Core/Src/main.c
  Core/Src/stm32f4xx_hal_msp.c
  Core/Src/gpio.c
# Công cụ này cũng cảnh báo khi chọn chân xung đột
(giao dien)
Warning: PA9 already used by USART1_TX
Cannot assign I2C3_SMBA to PA9

#Errata, tài liệu không được bỏ qua

Errata sheet
Danh sách các lỗi phần cứng đã được xác nhận trong một lô sản xuất cụ thể, kèm mô tả điều kiện xảy ra và cách né. Nhà sản xuất cập nhật nó suốt vòng đời sản phẩm.
Một mục errata điển hình
2.1.6  Delay after an RCC peripheral clock enabling

Description
  A delay between an RCC peripheral clock enable and the effective
  peripheral enabling should be taken into account in order to manage
  the peripheral read/write to registers.

  This delay depends on the peripheral mapping:
    - If the peripheral is mapped on AHB: the delay is 2 AHB cycles
    - If the peripheral is mapped on APB: the delay is 2 APB cycles

Workaround
  Use a dummy read of the peripheral register after enabling
  its clock, or add a delay of 2 cycles.
Loại errata thường gặpVí dụCách né điển hình
Cần độ trễ sau một thao tácBật clock ngoại vi, thoát chế độ ngủĐọc lại thanh ghi, hoặc chèn lệnh rỗng
Cờ trạng thái đặt sai thời điểmCờ ADC bật trước khi dữ liệu sẵn sàngĐọc thêm một lần nữa, hoặc chờ cờ khác
Ngoại vi khóa trong điều kiện hiếmI2C treo khi có nhiễu trên busThủ tục cứu bus, xem Bài 47.7
Kết hợp hai tính năng không hoạt độngDMA cùng chế độ ngủ sâuKhông dùng đồng thời
Thông số điện khác datasheetDòng rò cao hơn công bố ở nhiệt độ caoThiết kế mạch với biên an toàn lớn hơn

Ghi lại những gì đã tra

Chú thích kèm nguồn
/* Cấu hình ADC1 kênh 0.
   RM0368 muc 11.3.1: sau khi set ADON phai cho t_STAB.
   DS9716 bang 67: t_STAB = 3 us cho STM32F401.
   ES0255 muc 2.4.2: khong dung ADC cung DMA o che do quet
                     tren revision A.                        */
void adc_khoi_tao(void)
{
    ...
}

/* Ba dong chu thich nay tiet kiem cho nguoi doc sau, ke ca chinh ban,
   khoang mot gio tra cuu. Chung cung la thu duy nhat noi cho nguoi
   bao tri biet vi sao co dong tre_us(3) tuong nhu vo nghia kia. */

Tự làm thử

  1. Tải đủ năm loại tài liệu cho một chip bạn có, và ghi lại mã tài liệu của từng cái.
  2. Tra địa chỉ nền, độ dời và ý nghĩa từng bit của thanh ghi USART1->CR1, rồi viết header đặt tên cho chúng.
  3. Tra bảng chức năng thay thế và liệt kê mọi chân dùng được cho SPI1_SCK trên chip của bạn.
  4. Đọc giá trị reset của GPIOA->MODER trong tài liệu, rồi đọc giá trị thật bằng trình gỡ lỗi và so.
  5. Đọc lướt errata của chip bạn dùng và ghi lại mọi mục liên quan tới ngoại vi trong dự án hiện tại.

Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.

Tóm tắt

  • Datasheet cho sơ đồ chân và đặc tính điện, reference manual cho chi tiết thanh ghi. Tra nhầm chỗ là lãng phí thời gian phổ biến nhất.
  • Quy trình tám bước, và bước bật clock trong RCC bị quên nhiều nhất, bước bật khối phải là bước cuối.
  • Mỗi mục thanh ghi cho bốn thông tin: độ dời, giá trị reset, quyền truy cập từng bit, và ý nghĩa từng giá trị.
  • Bảng chức năng thay thế nằm trong datasheet, và phải tra trước khi thiết kế mạch chứ không phải sau khi hàn xong.
  • Errata phải đọc lướt ngay khi bắt đầu dự án. Nó giải thích những dòng mã trông vô nghĩa như đọc lại thanh ghi sau khi bật clock.