Title Image

Blog Logo

🌱 DMA Register Programming - Memory to Memory

🌱 DMA Register Programming - Memory to Memory

    Bài viết trước: DMA - Direct Memory Access

    Mình đã giới thiệu về DMA và tổng quan về các tính năng của bộ DMA trong Vi điều khiển STM32. Để lập trình DMA, chúng ta có thể demo qua các ví dụ như transfer data từ các Peripheral sang Memory, từ Memory sang Peripheral hoặc từ Memory sang Memory. Ở bài viết này, mình sẽ giới thiệu với các bạn lập trình DMA truyền Data từ Memory sang Memory, bằng cách access trực tiếp đến thanh ghi.

    👉 Phần cứng sử dụng: STM32F401RE - NUCLEO Board.

    👉 Phần mềm sử dụng: STM32CubeIDE ⇒ Xem hướng dẫn sử dụng.

    👉 Các bước lập trình DMA - STM32

    Để lập trình sử dụng trực tiếp các thanh ghi DMA, các bạn có thể làm theo các bước sau:

  1. Define các thanh ghi DMA.

    Phần này rất đơn giản, chỉ cần mở tài liệu Reference Manual của Vi điều khiển mà các bạn sử dụng, sau đó define địa chỉ Base của các DMA, và struct thanh ghi của DMA.
    Dưới đây mình Define cho Vi điều khiển STM32F401.

    DMA
  2. Viết Hàm cấu hình DMA - DMA_Init().

    Các bạn đặt tên gì tùy ý - ở đây mình đặt theo chuẩn chung thôi. Quan trọng nhất là nội dung của hàm này, đó là để cấu hình các chế độ của DMA khi sử dụng. Hàm này sẽ chủ yếu làm việc với thanh ghi DMA_SxCR - DMA Stream x Control Register. Cụ thể cần cấu hình gì mình sẽ nêu chi tiết ở bên dưới nhé!
  3. Viết Hàm Transfer DMA.

    Hàm này có tác dụng, định địa chỉ truyền và địa chỉ nhận dữ liệu, Kích thước dữ liệu cần truyền, và tiến hành truyền dữ liệu (Có thể viết 1 hàm riêng cũng được).

    👉 Các bước cấu hình DMA

    Nội dung trong hàm DMA_Init và cấu hình địa chỉ trước khi truyền Data sẽ tuân theo flow sau:

  • Cấu hình Clock cho DMA sử dụng.
  • Chọn Channel DMA tương ứng với Stream sử dụng, bằng các bit CHSEL trong thanh ghi CR.
  • Cấu hình các ngắt DMA (Optional nếu sử dụng ngắt), sử dụng các bit TCIF, HTIF, TEIF, DMEIR ... trong thanh ghi CR.
  • Chọn Data Direction (Mem to Mem, Peripheral to Mem or Mem to Peripheral), sử dụng các bit DIR trong thanh ghi CR.
  • Cấu hình Enable hoặc Disable Circular Mode (Bit CIRC thanh ghi CR).
  • Cấu hình Enable hoặc Disable Memory/Peripheral Increment (Bit PINC/CIRC thanh ghi CR).
  • Set Memory/Peripheral Data Size, sử dụng các bit MSIZE/PSIZE trong thanh ghi CR.
  • Set Priority Level (Mức độ ưu tiên) cho Channel (Các bit PL thanh ghi CR). 
    Khi truyền Data:

  • Cấu hình Data Size bằng thanh ghi NDTR.
  • Cấu hình Start Address của Source và Destination, Phần địa chỉ nguồn và đích sẽ phụ thuộc vào Data Direction mà chúng ta chọn ở trên, các bạn có thể tham khảo bảng phụ thuộc đó trong RM, như dưới đây:

    DMA

  • Sau đó cấu hình Start Address cho Source và Destination vào các thanh ghi như trên. Ở đây mình truyền Mem-to-Mem nên sẽ dùng 2 thanh ghi là DMA_SxPAR và thanh ghi DMA_SxM0AR.
    Bước cuối cùng sau khi đảm bảo mọi thứ đã được cấu hình xong, chúng ta có thể bắt đầu transfer bằng cách Enable DMA bằng bit EN trong thanh ghi CR.

    Mọi thứ Done! 

    Các bước trên đây có thể sẽ khó hiểu cho các bạn lần đầu làm về DMA, các bạn có thể follow theo các bước trên để tự viết, tham khảo Reference Manual hoặc ở đâu đó trên mạng - tùy!

    👉 Mình để lại Video sau để các bạn tham khảo nhé!

    Các bạn thấy Video hữu ích có thể cho mình xin 1 Like + 1 Subcribe nhé 💗

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

Xem Bài DMA 1                   Xem Bài Flash

Đăng nhận xét

0 Nhận xét