Saya ingin berbagi pengalaman membuat tampilan LED 8x8 piksel, kombinasi warna 262k (18 bit), frame rate 180 FPS dan koneksi USB. Saya juga siap mendengarkan saran untuk pengoptimalan dan penyempurnaan. Di masa depan saya berencana untuk menggunakan praktik terbaik untuk membuat tampilan stasiun cuaca rumah.Kata Pengantar
Semuanya dimulai dengan skema kontrol paling sederhana untuk garis 8 LED melalui port LPT. Versi berikutnya adalah papan 5x8 LED tiga warna, yang juga terhubung ke LPT dan, pada kenyataannya, adalah array lima belas buffer 8-bit dengan decoder untuk pengalamatan mereka. Kemudian, setelah bertemu dengan mikrokontroler, saya berangkat untuk membuat tampilan yang serupa, tetapi dengan koneksi USB. Awalnya diperkirakan hanya menggunakan 8 warna. Selanjutnya, ia menemukan cara untuk mengontrol kecerahan masing-masing dioda menggunakan timer dengan analogi dengan PWM, dan setelah menyelesaikan bagian perangkat lunak, perangkat saat ini ternyata. Secara teoritis, Anda dapat bekerja dengan 16 juta warna, tetapi LED konvensional tidak cocok untuk mode ini dalam hal reproduksi warna dan pengulangan. Selain itu, masalah dengan warna dioda yang berbeda sudah terlihat pada konfigurasi saat ini.Deskripsi pekerjaan
Perangkat ini didasarkan pada mikrokontroler PIC18F4550 yang beroperasi pada frekuensi 48 MHz. Pengontrol USB bawaan dan pustaka siap pakai untuk bekerja dengannya digunakan, Timer0 dalam mode 8-bit, yang mengimplementasikan indikasi dinamis. Untuk menyimpan tiga warna dalam satu kolom, digunakan tiga pemicu 8-bit pada 74F374. Menggunakan buffer semacam itu memungkinkan untuk mengurangi waktu tampilan satu frame sebanyak 3 kali. Catatan: Ketika saya memilih buffer 74F374, saya tidak memperhatikan kabel kakinya, tapi saya mengerti ini hanya pada dudukan pemasangan, jadi saya harus menyulitkan papan secara signifikan. Lebih baik menggunakan analog yang lebih nyaman. Misalnya, 74HC574. LED terhubung melalui tombol ULN2803 dan UDN2982. Tahanan yang membatasi saat ini hanya ada di saluran merah, karena tegangan suplai mereka di bawah biru dan hijau. Untuk resistensi biru dan hijau tidak diinstal, karena cukup drop tegangan pada tombol. Catatan: Untuk reproduksi warna yang lebih akurat, lebih baik untuk memilih resistensi pembatas arus yang lebih akurat di setiap saluran. Mikrokontroler dalam siklus tanpa akhir menyurvei status USB dan, ketika sebuah paket data tiba, tergantung pada perintahnya, memulai / menghentikan tampilan atau menyiapkan data untuk ditampilkan. Karena keterbatasan ukuran satu paket hingga 64 byte, data untuk setiap warna ditransmisikan dalam paket terpisah 48 byte - 6 byte untuk masing-masing 8 kolom, yang menyandikan kecerahan setiap LED dalam kolom. Setelah menerima setiap paket, itu disalin dari memori USB ke array warnanya. Setelah perintah mulai indikasi diterima, MK mengaktifkan timer dalam mode 8-bit dan pembagi dengan 128. Timer menggunakan frekuensi operasi mikrokontroler sebagai pulsa clock. Peningkatan penghitung waktu terjadi setiap 4 langkah. Periode timer minimum adalah 10,6 μs (1/48 * 4 * 128), yang kira-kira 2,8 kali waktu pemrosesan interupsi (46 operasi, terhadap 128 sampel timer). Ketika timer meluap, interupsi vektor tinggi dilakukan. Interrupt handler menonaktifkan indikasi, memperbarui data dalam buffer, mentransfer 1 byte dari setiap array warna sesuai dengan kursor, kemudian menyalakan indikasi. Memasukkan nilai baru ke timer dari buffer sementara, menurunkan kursor, menggeser buffer sementara untuk timer. Jika buffer waktu melebihi nilai maksimum, mis. bergeser lebih dari 5 kali, buffer waktu diatur ulang ke nilai minimum dan penunjuk kolom yang dipilih digeser.Hasilnya, algoritma indikasi dinamis berikut diperoleh:- Kami mengambil kelompok pertama 3 byte dari tiga array dan dimasukkan ke dalam buffer setiap warna di kolom.
- Kami mengaktifkan timer dengan waktu tunda minimum 128 kutu.
- Kami mengambil kelompok berikutnya 3 byte dari tiga array dan dimasukkan ke dalam buffer masing-masing warna di kolom.
- Kami mengaktifkan timer dengan penundaan ganda relatif terhadap langkah sebelumnya.
- Ulangi sampel 4 kali lebih banyak dan gandakan waktu tunda setiap kali.
- Kami mengatur ulang timer dan mulai memproses kolom berikutnya dari langkah 1.
Dengan demikian, kita dapat mengatur 2 ^ 6 = 64 opsi kecerahan untuk setiap dioda dalam kolom. Menggabungkan kecerahan dari masing-masing tiga warna dasar, kita mendapatkan 64 * 64 * 64 = 262144 warna. Waktu pemrosesan untuk satu kolom adalah (2 ^ 6-1) * 10,6 μs = 672 μs. Waktu per frame dari 8 kolom adalah 672 * 8 = 5.4ms, yang kira-kira sama dengan 186 frame per detik.Komponen yang Digunakan
- PIC18F4550 - Mikrokontroler
- 74F374 - Pemicu untuk memegang nilai kolom saat ini
- ULN2803 - Kunci untuk kontrol katoda
- UDN2982 - Kunci untuk mengendalikan anoda
- LED RGB 4-pin dengan katoda umum (LED apa saja dapat digunakan)
Skema
Skema dalam format dsn - unduhBiaya
Gambar Lay6 - unduhFirmware
Sumber dan rakitan HEX dalam MPLABX X IDE v2.30 - unduhKode utama#ifndef MAIN_C
#define MAIN_C
#include "config.h"
#include "usb.h"
#include "HardwareProfile.h"
#include "usb_function_hid.h"
#include "genericHID.h"
#define UdnOn LATA&=0b11111110
#define UdnOff LATA|=0b00000001
#define UlnOn LATD
#define UlnOff LATD =0b00000000
#define LineBufer LATB
#define WriteR LATE|=0b00000001
#define WriteG LATE|=0b00000010
#define WriteB LATE|=0b00000100
#define WriteRst LATE =0b00000000
#define Columns 8
#define BrightLevels 6
#define BlockSize (Columns*BrightLevels)
#define MinBright 0b11111111
unsigned char cursor;
unsigned char bright;
unsigned char column;
unsigned char dataR[BlockSize];
unsigned char dataG[BlockSize];
unsigned char dataB[BlockSize];
void ProcessIO(void) {
unsigned char temp = BlockSize + 1;
if ((USBDeviceState < CONFIGURED_STATE) || (USBSuspendControl == 1)) return;
if (!HIDRxHandleBusy(USBOutHandle))
{
switch (ReceivedDataBuffer[0])
{
case 0x80:
while (--temp) dataR[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x81:
while (--temp) dataG[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x82:
while (--temp) dataB[temp-1] = ReceivedDataBuffer[temp];
break;
case 0x90:
column = 0b00000001;
cursor = BlockSize;
bright = MinBright;
TMR0ON = 1;
SWDTEN = 0;
break;
case 0x91:
UdnOff;
UlnOff;
TMR0ON = 0;
SWDTEN = 0;
break;
case 0x92:
UdnOff;
UlnOff;
TMR0ON = 0;
SWDTEN = 0;
SLEEP();
break;
}
USBOutHandle = HIDRxPacket(HID_EP, (BYTE*) & ReceivedDataBuffer, 64);
}
}
void main(void)
{
PCFG3 = 1;
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
PORTD = 0b00000000;
PORTE = 0b00000000;
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b00000000;
TRISD = 0b00000000;
TRISE = 0b00000000;
INTCON = 0b10100000;
T0CON = 0b01000110;
USBDeviceInit();
while(1)
{
USBDeviceTasks();
ProcessIO();
};
}
void interrupt tc_int()
{
UdnOff;
UlnOff;
LineBufer = dataR[cursor-1]; WriteR;
LineBufer = dataG[cursor-1]; WriteG;
LineBufer = dataB[cursor-1]; WriteB;
UdnOn;
UlnOn = column;
WriteRst;
TMR0L = bright;
if (!--cursor) cursor = BlockSize;
bright <<= 1;
asm("BTFSS _bright, 5, 0"); asm("RLNCF _column, 1, 0");
asm("BTFSS _bright, 5, 0"); bright = MinBright;
TMR0IF = 0;
}
#endif
Perangkat sedang beroperasi
Untuk kontrol, saya menggunakan pemutar radio Internet yang ditulis dalam C, yang didasarkan pada perpustakaan BASS.DLL. Demo gradien di seluruh palet warna yang tersedia berfungsi selama jeda, kecepatan refresh frame (paket yang dikirim ke perangkat) adalah 20 Hz. Saat memutar musik, visualisator bekerja menggunakan array FFT yang diperoleh BASS.DLL, kecepatan refresh frame (paket yang dikirimkan ke perangkat) dalam mode ini adalah 29 Hz.Visualizer
: Tape Five — Soulsalicious
: ( ) ( ). .. , .- ( UDN)
- USB
- smd
- 74F374 74HC574,
- 74F374
- 74HC138,
- 3 ULN, UDN