Nội Dung Bài Viết
Bài viết này hướng dẫn chi tiết cách lập trình STM32 thanh ghi để cấu hình bộ nhớ Flash trên vi điều khiển STM32F103RCT6 (dòng STM32F103 phổ biến với 256KB Flash). Việc cấu hình đúng thanh ghi FLASH_ACR là rất quan trọng khi chạy hệ thống ở tần số cao (tối đa 72 MHz), giúp tránh lỗi đọc Flash và tối ưu hiệu suất.
Define struct thanh ghi FLASH cho lập trình STM32 thanh ghi
Flash access control register
Dựa trên RM0008, Section 3.3.3 (trang 54-60):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // Flash access control register typedef union { struct { // Structure for bit fields __IOM uint32_t LATENCY : 3; // Bit 0-2: Latency __IOM uint32_t HLFCYA : 1; // Bit 3: Flash half cycle access enable __IOM uint32_t PRFTBE : 1; // Bit 4: Prefetch buffer enable __IM uint32_t PRFTBS : 1; // Bit 5: Prefetch buffer status uint32_t reserved0 : 26; // Bit 6-31: Reserved }; __IOM uint32_t reg; // Access entire register } FLASH_ACR_Type; typedef struct { FLASH_ACR_Type ACR; __IO uint32_t KEYR; __IO uint32_t OPTKEYR; __IO uint32_t SR; __IO uint32_t CR; __IO uint32_t AR; __IO uint32_t RESERVED; __IO uint32_t OBR; __IO uint32_t WRPR; } FLASH_TypeDef; #define FLASH ((FLASH_TypeDef *)0x40022000UL) |
Địa chỉ thanh ghi FLASH: 0x4002 2000
Giới thiệu FLASH và cấu hình FLASH trong STM32F103
Giới thiệu khối FLASH trong STM32F103
Bộ nhớ Flash trên STM32F103RCT6 dùng để lưu trữ:
- Code chương trình (firmware)
- Hằng số (const data)
- Và có thể lưu dữ liệu cấu hình (EEPROM giả lập)
CPU lấy lệnh trực tiếp từ Flash, do đó khi tần số hệ thống cao (ví dụ 72 MHz), Flash cần được cấu hình phù hợp để tránh lỗi khi đọc lệnh.
Việc truy cập Flash có thể yêu cầu thời gian chờ (wait state), phụ thuộc vào tần số xung nhịp hệ thống (SYSCLK), nhằm đảm bảo dữ liệu được đọc chính xác. Đây là phần rất quan trọng trong lập trình STM32 bằng thanh ghi.
Thanh ghi FLASH_ACR (Flash Access Control Register)
Thanh ghi FLASH_ACR (Flash Access Control Register) trong vi điều khiển STM32F103RCT6 được sử dụng để cấu hình các tham số liên quan đến truy cập bộ nhớ Flash, chẳng hạn như:
- Thời gian chờ (latency)
- Bật/tắt bộ đệm prefetch
- Các tính năng liên quan đến hiệu suất truy cập Flash

Thanh ghi FLASH_ACR nằm trong khối FLASH Interface của STM32F103, cho phép cấu hình các tham số:
- LATENCY: Số chu kỳ chờ (wait states) khi CPU truy cập Flash
- PRFTBE: Bật/tắt bộ đệm prefetch (Prefetch Buffer)
- PRFTBS: Trạng thái bộ đệm prefetch (chỉ đọc)
- Một số bit khác liên quan đến chế độ Half-cycle access (không được sử dụng trong tất cả các dòng STM32F103)
Cấu hình FLASH->ACR
PRFTBE (Prefetch Buffer Enable)
- PRFTBE (Prefetch Buffer Enable) là bit trong thanh ghi FLASH_ACR dùng để bật bộ đệm prefetch
- Bộ đệm prefetch là cơ chế tối ưu hóa hiệu suất, cho phép Flash dự đoán và đọc trước dữ liệu hoặc lệnh mà CPU có thể cần trong các chu kỳ tiếp theo
- Điều này giúp giảm thời gian chờ khi CPU truy cập Flash, đặc biệt khi hệ thống chạy ở tần số cao
Cấu hình:
Nếu không bật prefetch, hiệu suất truy cập Flash có thể giảm do CPU phải chờ lâu hơn để lấy lệnh
LATENCY
- LATENCY (bit 2:0 trong FLASH_ACR) xác định số chu kỳ chờ (wait states) khi CPU truy cập bộ nhớ Flash
- Wait state là số chu kỳ xung nhịp mà CPU phải chờ để đọc dữ liệu từ Flash, phụ thuộc vào tần số hệ thống (SYSCLK) và tốc độ truy cập của Flash
Số chu kỳ chờ cần được cấu hình phù hợp:
- 0 wait state: SYSCLK ≤ 24 MHz
- 1 wait state: 24 MHz < SYSCLK ≤ 48 MHz
- 2 wait states: 48 MHz < SYSCLK ≤ 72 MHz
Cấu hình:
Thiết lập này được sử dụng khi SYSCLK cấu hình ở tần số cao (ví dụ 72 MHz với HSE + PLL).
Tại sao cần cấu hình FLASH_ACR?
- Tần số hệ thống cao: Khi SYSCLK tăng (ví dụ 72 MHz), thời gian truy cập Flash (~35 ns) không đủ nhanh để cung cấp dữ liệu ngay lập tức cho CPU
- Tối ưu hiệu suất: Bật prefetch buffer giúp giảm thời gian chờ bằng cách đọc trước dữ liệu
- Tính ổn định: Cấu hình sai LATENCY (quá ít wait state) có thể dẫn đến lỗi đọc Flash và gây crash chương trình
Code cấu hình FLASH và System Clock
Link Github: Download code cấu hình FLASH STM32F103RCT6
Output – Kiểm tra thanh ghi FLASH
- Mở Keil uVision
- Chọn Peripherals → System Viewer → FLASH

- Kiểm tra giá trị:
- LATENCY
- PRFTBE
Đảm bảo các giá trị trong FLASH->ACR đúng với cấu hình đã thiết lập.

Kết luận
Trong quá trình lập trình STM32 bằng thanh ghi, việc cấu hình FLASH là bước bắt buộc khi hệ thống hoạt động ở tần số cao, đặc biệt với STM32F103RCT6 chạy 72 MHz. Thanh ghi FLASH_ACR cho phép cấu hình số chu kỳ chờ (LATENCY) và bật Prefetch Buffer, giúp đảm bảo việc truy cập Flash diễn ra chính xác và ổn định.
Nếu LATENCY không được thiết lập đúng, CPU có thể đọc sai lệnh từ Flash, dẫn đến lỗi chương trình hoặc treo vi điều khiển. Ngược lại, việc bật Prefetch Buffer giúp cải thiện hiệu suất truy cập Flash, giảm thời gian chờ khi thực thi lệnh.
Vì vậy, khi cấu hình system clock bằng HSE + PLL, cần luôn cấu hình FLASH_ACR trước khi chuyển SYSCLK sang PLL. Đây là nguyên tắc quan trọng trong lập trình STM32F103 thanh ghi, giúp hệ thống hoạt động ổn định và đúng theo thiết kế phần cứng.
