[Matrix LED] Bài 20: Quét led bằng DMA

dma scan led matrix

Yêu cầu: Nắm vững phương pháp quét led bằng timer mà mình đã hướng dẫn trong suốt tutorial

Trong toàn bộ tutorial, chúng ta đã quá quen với kĩ thuật quét led matrix sử dụng ngắt timer, nhược điểm của phương pháp này là làm hao tốn nhiều thời gian xử lí của chip vì phải thường xuyên nhảy vào chương trình ngắt, bản thân chương trình ngắt lại thực hiện khá lâu do phải truyền data dưới dạng nối tiếp vào các thanh ghi dịch

DMA là 1 cơ chế bơm dữ liệu tự động, chúng ta sẽ giảm tải cho CPU bằng cách nhờ DMA truyền dữ liệu ra cho các thanh ghi dịch

DMA chỉ có khả năng bơm dữ liệu chứ không tính toán dữ liệu hộ CPU được, do vậy cần có 1 bộ nhớ đệm do CPU chuẩn bị sẵn từ trước để DMA thực hiện truyền, do vậy nhược điểm khi sử dụng DMA là sẽ tốn RAM

Quay trở lại hàm ngắt quét led mà mình hay xài ở các bài trước

Trong hàm ngắt quét led này, đoạn code mà mình tô vuông chính là đoạn truyền dữ liệu ra led và là nơi mà CPU mất thời gian xử lí nhất. Khi bảng led nối tiếp càng nhiều tấm thì đoạn code này thực thi càng lâu hơn nữa, trong khi các dòng code còn lại thì hầu như không đáng kể. Do vậy chúng ta sẽ “nhờ” DMA thực hiện giúp đoạn code tô vuông đó. Sau khi DMA thực hiện xong việc truyền data thì 1 hàm callback sẽ được gọi để chúng ta thực thi các dòng code còn lại bên dưới

Tóm lại, phương pháp thống thường thì như này

Còn dùng DMA sẽ như này

Nhờ có DMA chúng ta sẽ tiết kiệm được cho hàm main rất nhiều thời gian

Thiết kế bộ đệm cho DMA

Do mình thiết kế các chân R1G1B1 R2G2B2 đề nối vào PORTA nên DMA sẽ tự lấy dự liệu trong bộ đệm để ghi vào PORTA của ic STM32F103C8T6

Do mỗi lần truyền một bit data thì phải có 1 xung clock (theo nguyên tắc của thanh ghi dịch) nên mình cho chân clk của module led chung port với các chân dữ liệu RGB. Sau khi truyền xong 1 bit dữ liệu ra các chân RGB thì mình tiếp tục truyền dữ liệu đó 1 lần nữa nhưng ở vị trí của chân CLK sẽ đảo để tạo ra xung dịch. Điều này dẫn tới việc phải gấp đôi bộ nhớ ram lên

Lập trình

Tiếp tục project ở bài 16, tuy nhiên chân kết nối sẽ khác 1 chút ở chân CLK, mình sẽ đưa chân này về PORTA.0

STM32F103C8HUB75D
A2R1
A3G1
A4B1
A5R2
A6G2
A7B2
A0CLK
B1A
B2D
B10C
B11OE
B12LAT
B14B

Đối với bạn nào dùng mạch Clock P5 của mình thì hãy gỡ con biến trở ra và hàn câu dây chân CLK vào chân A0 nhé

Khởi tạo CUBE MX

Mình sẽ sử dụng DMA TIM4_UP của timer4 để truyền data tự động ra PORTA

Chuyển sang tab cấu hình DMA, add TIM4_UP vào và cài đặt như hình nhé

Chúng ta cần 1 ngắt timer để quét led nữa, nhiệm vụ của timer này chỉ đơn giản là kích hoạt cho DMA bắt đầu truyền. Mình sẽ dùng timer3, tần số ngắt này sẽ quyết định tần số làm tươi của màn hình LED, như cài đặt của mình ở dưới thì nó sẽ quét khoảng 400Hz (khá cao, thực chất chỉ cần 60hz là đủ nhìn rồi )

Đừng quên chuyển sang tab NIVC để kích hoạt cho phép ngắt

Bây giờ tiếp tục khởi tạo timer2 chanel 4 để tạo 1 kênh PWM vào chân OE, hệ số chia để 1 hoặc 0 tùy các bạn, cứ tạo pwm càng mịn càng tốt, còn Couter Period không cần quan tâm vì ta sẽ chỉnh nó trong code

Đừng quên cấu hình các chân GPIO

Tạo code bằng phần mềm lập trình mà bạn thích, như ở đây mình xài KeilC V5

Do phải gấp đôi bộ đệm GPIO nên mình sẽ chỉ tạo pwm 4bit, bộ đệm GPIO cho tấm led P5 64x32px và bộ đệm RGB sẽ như này

Nếu dùng 8bit pwm thì không đủ RAM nên project này mình sẽ quét với 6bit pwm

Hàm chuyển đổi bộ đệm RGB sang bộ đệm GPIO sẽ được viết lại 1 chút do phải nhồi các byte clk vào giữa

Chương trình ngắt timer quét led chỉ dơn giản là kích hoạt cho DMA bắt đầu truyền

Và chương trình callback sau khi DMA truyền xong

Trong hàm main chúng ta sẽ khởi động timer, phát pwm, cấu hình DMA …

Hàm HAL_DMA_RegisterCallback dùng để đăng kí hàm callback sẽ được gọi khi DMA truyền xong, các hàm còn lại dùng để kích hoạt DMA, timer, pwm bắt đầu hoạt động

Bây giờ dùng ứng dụng Image To Data Convert để tạo mã hex cho buffer RGB để hiển thị thử 1 hình ảnh như này nhé

Phần mềm này mình đã share ở các bài trước rồi. Sau khi lấy mã mình sẽ dán thẳng nó vào chỗ khởi tạo bộ đệm RGB luôn

Đừng gọi hàm display() để cập nhật dữ liệu từ bộ đệm RGB sang GPIO

Download

Tải source và file cấu hình cubemx tại đây
Tóm lại với mỗi phương pháp đều có ưu nhược điểm riêng, bản thân cách quét dùng dma mình đã chia sẻ này cũng chưa phải là tối ưu các bạn tự nghiên cứu các thuật toán hay hơn và chia sẻ cho mọi người nhé

Tag: PWM HUB 75 SCAN LED MATIX DMA SCAN LED TIMER TRIGGER DMA STM32 LED MATRIX

 

Từ tác giả:

Nếu có bất kì thắc mắc nào trong bài viết, vui lòng để lại comment dưới mỗi bài ! Mình sẽ không trả lời thắc mắc của các bạn ở facebook hay email !

Nếu trong phần code bạn nhìn thấy nhưng thứ kiểu như &amp; thì đó là lỗi hiển thị, cụ thể 3 kí tự < > & bị biến đổi thành như thế
&amp; là &
&lt;  là <
&gt; là >

Giới thiệu Đào Nguyện 80 bài viết
DIY,chế cháo, viết blog chia sẽ kiến thức về lập trình,điện tử - IoT. Rất mong được giao lưu, kết bạn với các bạn cùng đam mê. Địa chỉ Facebook: https://www.facebook.com/nguyendao207

3 bình luận

  1. trên chân PB2 của stm32 bluepill nó nối tiếp với 1 con trở 100k thì để chạy được code này em có cần thông trở 100k đó không ạ

Đã đóng bình luận.