Bagaimana cara kerja alamat strip dipimpin?


Mungkin pertanyaan ini "bagaimana cara kerjanya" tampaknya konyol bagi banyak orang. Jawabannya hampir jelas: strip LED yang dapat dialamatkan terdiri dari sejumlah "smart LED" yang dihubungkan secara seri. Ini dapat dilihat hanya dengan melihat perangkat rekaman. Anda dapat melihat masing-masing sirkuit mikro disolder ke kabel yang fleksibel, Anda dapat melihat sambungannya: sirkuit mikro terhubung secara seri dengan hanya tiga kabel, dan dua di antaranya adalah daya dan ground. Hanya satu kawat mentransmisikan data warna piksel. Bagaimana itu? Apa itu LED pintar?

Selanjutnya, saya akan berbicara tentang protokol transfer data yang digunakan dalam strip LED berdasarkan WS2812B, dan, lebih lanjut, saya hampir akan membuat "chip strip LED" saya sendiri dalam chip FPGA.

Jadi, rekaman itu menggunakan transmisi serial melalui sinyal data tunggal.

Bit nol ditransmisikan sebagai impuls positif pendek dan jeda, yang kira-kira dua kali lebih lebar dari denyut nadi. Unit bit ditransmisikan sebagai impuls positif lebar dan jeda singkat:



Jika tidak ada transmisi lebih dari 50 mikrodetik, pita kembali ke keadaan semula, siap menerima piksel mulai dari yang pertama.

Setiap 24 bit secara berurutan adalah 3 byte untuk tiga warna RGB. Dan faktanya urutannya adalah GRB. Bit G7 yang tinggi diutamakan.

Urutan 24 bit pertama adalah satu piksel, yang akan menerima LED pertama dalam rekaman itu. Sampai LED pertama jenuh, itu tidak mentransfer data lebih jauh ke LED berikutnya. Setelah LED pertama menerima bagiannya dari 24x RGB bits, ia membuka transmisi ke yang berikutnya. Secara primitif, orang dapat membayangkan urutan LED sebagai riam kendi yang berturut-turut diisi dengan air: Yang



pertama, kemudian yang kedua, kemudian yang ketiga, dan seterusnya, akan terisi.

Jadi, saya percaya bahwa protokol transfer telah disortir.

Apakah mungkin untuk mencoba merancang "LED pintar" seperti itu sendiri? Tentu saja, ini masuk akal praktis, tetapi untuk pendidikan diri dan memperluas wawasan seseorang, ini adalah tugas yang menarik. Mari kita coba untuk menggambarkan logika chip dalam bahasa pemrograman Verilog HDL. Tentu saja, ini bukan desain chip nyata, akan ada batasan. Salah satu batasan paling penting - saya akan memerlukan jam eksternal untuk sirkuit mikro saya. Dalam LED cerdas nyata, generator seperti itu juga ada, tetapi sudah terintegrasi ke dalam chip.

Mari kita mulai modul Verilog seperti ini:

module WS2812B(
	input wire clk,
	input wire in,
	output wire out,
	output reg r,
	output reg g,
	output reg b
);

Saya pikir semuanya jelas di sini: frekuensi clock clk, sinyal input dan output dari "LED pintar" masuk dan keluar, dan, tentu saja, sinyal output r, g, b di mana saya akan mengontrol LED eksternal nyata merah, hijau dan biru.

Saya akan menangkap sinyal input dalam register geser dua-bit dan dari keadaan saat ini dalam bit yang ditangkap ini, saya dapat menentukan awal dari tepi positif sinyal di:

reg [1:0]r_in = 0;
always @( posedge clk )
	r_in <= { r_in[0],in };

wire in_pos_edge; assign in_pos_edge = (r_in==2'b01);

Selain itu, penting untuk menentukan status reset pita ketika pengontrol kontrol berhenti sebelum memulai transmisi baru:

localparam reset_level = 3000;
reg [15:0]reset_counter = 0;
always @( posedge clk )
	if( r_in[0] )
		reset_counter <= 0;
	else
	if( reset_counter<reset_level )
		reset_counter <= reset_counter+1;

wire reset; assign reset = (reset_counter==reset_level);

Selanjutnya, dari sisi positif in_pos_edge, Anda perlu menahan beberapa jeda untuk mendapatkan momen memperbaiki bit baru:

localparam fix_level   = 50;
reg [7:0]bit_length_cnt;
always @( posedge clk )
	if( in_pos_edge )
		bit_length_cnt <= 0;
	else
	if( bit_length_cnt<(fix_level+1) && !pass )
		bit_length_cnt <= bit_length_cnt + 1;

wire bit_fix; assign bit_fix = (bit_length_cnt==fix_level);

Jumlah bit yang sudah diterima dalam chip dianggap sebagai berikut:

reg pass = 0;
reg [5:0]bits_captured = 0;

always @( posedge clk )
	if( reset )
		bits_captured <= 1'b0;
	else
	if( ~pass && bit_fix )
		bits_captured <= bits_captured+1'b1;

Sinyal lulus penting diperkenalkan di sini, yang hanya menentukan pengalihan aliran input ke output. Setelah menerima bit 24x piksel, sinyal lulus diatur ke satu:

always @( posedge clk )
	if( reset )
		pass <= 1'b0;
	else
	if( bits_captured==23 && bit_fix )
		pass <= 1'b1;
		
reg pass_final;
always @( posedge clk )
	if( reset )
		pass_final <= 1'b0;
	else
	if( r_in!=2'b11 )
		pass_final <= pass;
		
assign out = pass_final ? in : 1'b0;

Input out adalah multiplexed ke output ketika sinyal pass_final adalah satu.

Yah, tentu saja, kita perlu register geser, tempat 24 bit piksel yang diterima terakumulasi:

reg [23:0]shift_rgb;
always @( posedge clk )
	if( bit_fix )
		shift_rgb <= { in, shift_rgb[23:1] };

reg [23:0]fix_rgb;
always @( posedge clk )
	if( bits_captured==23 && bit_fix )
		fix_rgb <= { in, shift_rgb[23:1] };

Setelah menerima semua 24 bit, mereka juga disalin ke register 24 bit terakhir.

Sekarang masalahnya tetap kecil. Penting untuk menerapkan sinyal PWM (Latitudinal Pulse Modulation) untuk mengirimkan kecerahan ke LED eksternal nyata sesuai dengan byte RGB yang diterima:

wire [7:0]wgreen; assign wgreen = { fix_rgb[0 ], fix_rgb[1 ], fix_rgb[2 ], fix_rgb[3 ], fix_rgb[4 ], fix_rgb[5 ], fix_rgb[6 ], fix_rgb[7 ] };
wire [7:0]wred;   assign wred   = { fix_rgb[8 ], fix_rgb[9 ], fix_rgb[10], fix_rgb[11], fix_rgb[12], fix_rgb[13], fix_rgb[14], fix_rgb[15] };
wire [7:0]wblue;  assign wblue  = { fix_rgb[16], fix_rgb[17], fix_rgb[18], fix_rgb[19], fix_rgb[20], fix_rgb[21], fix_rgb[22], fix_rgb[23] };

reg [7:0]pwm_cnt;

always @( posedge clk )
begin
	pwm_cnt <= pwm_cnt+1;
	r <= pwm_cnt<wred;
	g <= pwm_cnt<wgreen;
	b <= pwm_cnt<wblue;
end

Sepertinya hanya itu saja.

Detail kecil tetap - bagaimana mengalami semuanya?

Saya mengambil beberapa motherboard sederhana dengan FPGA MAX II (ini adalah kartu seri Mars rover) dan mem-flash semuanya dengan proyek dengan kode Verilog ini. Sudah ada 8 LED di papan, tapi semuanya berwarna kuning. Pada masing-masing papan, saya mengganti 3 LED dengan R, G, B. Saya menghubungkan papan secara seri dan, apalagi, menghubungkannya ke strip LED nyata. Jadi, saya memperpanjang rekaman nyata dengan LED buatan saya.

Koneksi ini berubah seperti ini:



Pada kenyataannya, terlihat seperti ini:



Sekarang, menerapkan gambar tertentu ke kaset, saya melihat bahwa "LED pintar" saya berperilaku persis sama dengan yang asli dari rekaman itu:


Ternyata logika yang saya implementasikan dalam FPGA berfungsi penuh! Sebagai perkiraan pertama, saya bisa melakukan sesuatu yang mirip dengan chip LED pintar nyata.

Sebenarnya, saya suka strip LED. Atas dasar mereka, setiap orang dapat menciptakan sesuatu sendiri: pencahayaan cerdas, layar, efek ambilight. Suatu kali saya bahkan menerapkan musik berwarna pada pita LED yang menjalankan FPGA. Tapi itu cerita lain .

All Articles