Title Image

Blog Logo

🌱 STM32 - 3. Cấu hình module Clock RCC

🌱 STM32 - 3. Cấu hình module Clock RCC

    Trước khi học cách cấu hình các thanh ghi trong vi điều khiển STM32, chúng ta cần phải nắm được địa chỉ của chúng trong Vi điều khiển. Sau đó đưa ra các define tương ứng với từng địa chỉ để dễ sử dụng.

    👉 Để nắm được địa chỉ các thanh ghi, chúng ta cần tham khảo 2 nguồn tài liệu. Một là bản đồ bộ nhớ - Memory Map trong Vi điều khiển STM32 và hai là Reference Manual của Vi điều khiển.

    Theo Memory Map thì vùng nhớ cho Peripheral sẽ bắt đầu từ địa chỉ 0x4000.000, và đó cũng chính là địa chỉ của bus APB1. Bus AHB1 có offset là 0x0002.0000 so với APB1 bus. 

STM32

    Vì vậy, có thể define các địa chỉ của các bus như hình trên. Khối RCC và GPIOA được cấp clock từ bus AHB1, vì vậy, địa chỉ offset sẽ theo base của bus AHB1, tương ứng offset là 3800 và 0000.
     👉 Bây giờ, để define địa chỉ của các thanh ghi RCC cấu hình Clock, các bạn tham khảo tài liệu RM. Ví dụ, thanh ghi quan trọng nhất để cấu hình chọn Clock nội hay ngoại là thanh ghi RCC_CR

Clock

    Thanh ghi này có offset là 0x00 so với địa chỉ Base của RCC mà chúng ra define ở trên. Vì vậy, có thể định nghĩa địa chỉ của thanh ghi này là:
#define RCC_CR    RCC_BASE_ADDR
    Tương tự với những thanh ghi khác, khi đã có địa chỉ Base và Address Offset thì chỉ cần cộng 2 giá trị địa chỉ này lại với nhau ta sẽ có địa chỉ thanh ghi.

    👉 Sau khi có địa chỉ của thanh ghi, bây giờ chúng ta có thể cấu hình chúng theo mong muốn.

    💬 Example 1: Cấu hình HSE làm System Clock

    Cần lưu ý 2 thanh ghi là thanh ghi RCC_CR ở trên (offset là 0x00), và thanh ghi RCC_CFGR (offset là 0x08).



    Đối với thanh ghi RCC_CR, chúng ta cần lưu ý đến 2 bit liên quan đến HSE là bit[16] và bit[17]:
  • bit[16] - HSEON: set lên 1 để chọn HSE.
  • bit[17] - HSERDY: Khi External Clock (thạch anh) được cấp ổn định thì bit này tự động set lên 1 bằng phần cứng.

    Đối với thanh ghi RCC_CFGR, chúng ta cần lưu ý đến 2 bit cấu hình system clock là bit[1] và bit[0]:


    👉 Vậy, để cấu hình HSE làm system clock, chúng ta cần trải qua các bước sau:
  1. Đầu tiên cần định nghĩa địa chỉ của các thanh ghi liên quan:


  2. Tiếp theo cần tạo các biến đại diện cho các thanh ghi này (thanh ghi RCC_CR và RCC_CFGR):


  3. Enable HSE bằng bit[16] thanh ghi RCC_CR và đợi Clock ổn định:


  4. Chọn HSE làm System Clock bằng cách đặt 2 bit [1] và [0] của thanh ghi RCC_CFGR là 01.
     
    OK, vậy là chúng ta đã cấu hình xong HSE làm System Clock.

    💬 Example 2: Cấu hình cấp Clock cho ngoại vi GPIOA

    Để cấu hình Clock cho một ngoại vi, chúng ta cần nắm được ngoại vi đó được cấp clock từ đường bus nào (AHB/APB). Các bạn tham khảo trong bài Bus Protocol & Bus Interface hoặc tham khảo RM để biết được ngoại vi kết nối với bus nào. 
    Ở đây mình lấy ví dụ ngoại vi GPIOA, được kết nối với bus AHB1.
    Vì vậy, mình cần cấu hình clock cho GPIOA bằng thanh ghi RCC_AHB1ENR (Xem trong bài STM 2: RCC Overview & Registers). 


    Xem trong RM thì thanh ghi này có offset là 0x30, vì vậy mình có thể dễ dàng define địa chỉ của thanh ghi đó:


    Với RCC_BASE_ADDR đã được define trong ví dụ ở trên.
    👉 Tiếp theo chúng ra tạo một biến (con trỏ) để đại diện cho thanh ghi RCC_AHB1ENR và cấu hình cấp Clock cho ngoại vi GPIOA (bit[0]).
    

    OK, vậy là GPIOA đã được cấp Clock và bây giờ chúng ta có thể sử dụng nó để phục vụ cho bài sau về GPIO. Các bạn cũng có thể cấu hình cấp Clock cho các ngoại vi khác theo cách tương tự.

>>>= Follow ngay =<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊

Chúc các bạn học tập tốt 😊

                                        

Đăng nhận xét

11 Nhận xét

  1. cho em hỏi phần clock configuration chỗ (uin32_t*) là gì vậy ạ

    Trả lờiXóa
    Trả lời
    1. Đây là ép kiểu sang uint32_t * nha em, thanh ghi anh đang định nghĩa kiểu con trỏ uint_32

      Xóa
    2. Nhận xét này đã bị tác giả xóa.

      Xóa
    3. Sao em code trên con f103c8 như thế mà nó có lỗi No section matches selector ạ

      Xóa
    4. Cái define là một address, em muốn đọc giá trị của address này thì phải gán cho define này là một con trỏ (địa chỉ) => bằng cách ép kiểu nó sang (uint_32*)

      Xóa
    5. Các địa chỉ trên anh đang lấy từ con STM32F401, nếu dùng con F1 thì em phải xem lại địa chỉ nhé. Mỗi con có các địa chỉ khác nhau mà

      Xóa
    6. Em đổi hết sang địa chỉ của f1 rồi ạ

      Xóa
    7. Cái địa chỉ base + offset nữa, nếu đổi chuẩn thì code ok rồi nha e

      Xóa
  2. Nhận xét này đã bị tác giả xóa.

    Trả lờiXóa
  3. a cho em hỏi là lúc em chọn HSE làm system clock,lúc em debug em thấy chỗ HSE bit 16 17 lên 1 rồi,nhưng chỗ HSI nó cũng là 1 có ảnh hưởng gì không a? mình có cần clear 2 bit HSI ko a?

    Trả lờiXóa
    Trả lời
    1. STM32 có thanh ghi RCC_CFGR - trường bit SW (System Clock Switch) đó em. Chọn dùng clock nào.

      Xóa