Vui lòng đọc tất cả bài trước đó trong tutorial Ma trận LED thì các bạn mới hiểu bài này
Tiếp tục bài này, mình sẽ demo hiển thị hỉnh bất kì lên tấm led ma trận P5 có độ phân giải 64×32 pixel. Các bạn chuẩn bị project như đã làm ở bài 15 nhé
Trong bài trước, mình đã giới thiêu cách tạo PWM qua kĩ thuật điều chế mã nhị phân ( hay còn gọi là BAM) bằng cách căn chỉnh thời gian tồn tại của các bit. Phương pháp này có 1 nhược điểm điểm là nếu cái hàm ngắt quét led kia chạy lâu quá thì nó sẽ ảnh hưởng tới các bit1 và bit0 vì chúng có thời gian tồn tại rất thấp. Mình đã thử dùng logic để đo và thấy hầy như bit0,bit1 đều có timing dài bằng bit2. Điều này khiến cho màu sắc thực tế chúng ta tạo ra bị sai lệch đi khá nhiều làm ảnh hưởng tới chất lượng hình ảnh
Bây giờ mình sẽ giới thiệu 1 phương pháp khác, thay vì tạo ra các thời gian tồn tại khác nhau ở mỗi bit, mình sẽ cho các khoảng thời gian ở mỗi bit đều như nhau nhưng thay đổi giá trị PWM đưa vào chân OE. Tức là:
Bit 0: Chân OE sẽ có điện áp X
Bit 1: Chân OE sẽ có điện áp 2X
Bit 2: Chân OE sẽ có điện áp 4X
Bit 4: Chân OE sẽ có điện áp 8X
Bit 5: Chân OE sẽ có điện áp 16X
……………..Tương tự………………….
Về cơ bản, chúng ta sẽ tạo 1 ngắt timer đều đặn và khi vào ngắt thì thay đổi giá trị pwm ở chân OE, khá đơn giản phải không
Demo hiển thị ảnh
Trong project này, mình sẽ sử dụng mảng ma trận 1 chiều thay vì mảng đa chiều vì mảng 1 chiều có tính linh hoạt hơn
Tạo 2 Buff quen thuộc
1 2 |
unsigned char Buffer_RGB[3*32*64]; uint8_t Buffer_GPIO[SCAN_TYPE*MAX_BIT*64]; |
Tạo thêm 1 array để chứa các giá trị pwm để nạp vào chân OE
Chương trình ngắt sẽ thay đổi 1 chút so với
1 |
const uint16_t scan_PWM_duty[]={2,4,8,16,32,64,128,256,512,1024}; //he so chia nạp vao time pwm chan OE |
Và chương trình ngắt quét led
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void ngatquetled(void) { __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_4,0); for(int i=0;i<64;i++) { data_PORT->ODR=Buffer_GPIO[scan_data[hang_led]*MAX_BIT*64 +vitri_bit*64 + i]; clk_P->BSRR=(1<<(clk+16));clk_P->BSRR=(1<<clk); } __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_4,scan_PWM_duty[vitri_bit]); scan16S(scan_data[hang_led]); Control_P->BSRR=(1<<LAT); // chot data Control_P->BSRR=(1<<(LAT+16)); vitri_bit++; if(vitri_bit==MAX_BIT){vitri_bit=0;hang_led++;if(hang_led==SCAN_TYPE)hang_led=0;} } |
Nói chung, chương trình chỉ thay đổi 1 chút xíu so với bài 15
Các bạn có thể tải FULL Project tại đây để tham khảo nhé !
https://drive.google.com/file/d/1Yz1m9uagFqZLKWiKq51uBFq5o_ym0jl4/view?usp=sharing
Trong ví dụ này, để hình ảnh hiện được đẹp nhất, mình đã nâng số bit pwm lên tới 8 bit. Điều này sẽ làm giảm tần số quét led đáng kể và trông sẽ hơi nháy 1 chút
Hiển ảnh
Lên mạng và tìm ảnh 1 em xinh tưới :P, mở ảnh bằng phần mềm vẽ Paint để cắt bớt ảnh và resize ảnh về 64×32 pixel nhé
Mở tool chuyển đổi ảnh thành max HEX mà mình đã chia sẻ ở bài 15 hoặc tải tại đây
Do mình sử dụng pwm 8bit nên mình chọn RGB24 và thông số gamma để là 255->255. Hệ số gamma để khoảng 2.3 tới 3.5 tùy các bạn nhé. Tích chọn OK gamma để sử dụng hiệu chỉnh gamma
Sau đó copy mã hex nhận được vào mảng Buffer RGB
Và đây là kết quả của mình
Đương nhiên với cái độ phân giải 64×32 pixel thì không thể cho ra 1 bức ảnh “nuột” được ! Trong các bài tiếp chúng ta sẽ nâng độ phân giải lên cao hơn !
There is an error in the google drive link.
I have updated the link
bạn có thể hướng dẫn cách đặt mã hex sau khi chuyển đổi hình ảnh vào buffer được không ạ