{"id":313973,"date":"2020-11-29T09:00:12","date_gmt":"2020-11-29T09:00:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=313973"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=313973","title":{"rendered":"\u0417\u0430\u0436\u0438\u0433\u0430\u0435\u043c \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u0443\u044e \u043b\u0435\u043d\u0442\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 WS2811 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u041f\u041b\u0418\u0421"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/17\/lx\/9c\/17lx9cl6md2cimivsmuceallq8s.jpeg\"><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u0423\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0434\u0432\u0430 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u044f \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u043b \u043d\u0430 aliexpress \u043a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439 \u043d\u0430\u0431\u043e\u0440, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u044b EasyFPGA A2.2, \u0441 Cyclone IV EP4CE6E22C8N \u043d\u0430 \u0431\u043e\u0440\u0442\u0443, \u0418\u041a \u043f\u0443\u043b\u044c\u0442\u0430 SE-020401, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u043e\u0440\u0430, \u043f\u0430\u0440\u044b USB \u043f\u0440\u043e\u0432\u043e\u0434\u043e\u0432 \u0438 \u0448\u043b\u0435\u0439\u0444\u043e\u0432. \u0414\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u0431\u0440\u043e \u043b\u0435\u0436\u0430\u043b\u043e \u0443 \u043c\u0435\u043d\u044f \u0431\u0435\u0437 \u0434\u0435\u043b\u0430, \u0442.\u043a. \u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043c\u043e\u0433 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0438 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u043e\u0439 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<p>  <\/p>\n<p>\u0415\u0449\u0435 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443 \u043d\u0430 \u0442\u043e\u043c-\u0436\u0435 aliexpress \u044f \u0437\u0430\u043a\u0430\u0437\u0430\u043b RGB \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u0443\u044e \u043b\u0435\u043d\u0442\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0432\u0441\u0435\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 WS2811 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c. \u041f\u0435\u0440\u0435\u0434 \u043f\u043e\u043a\u0443\u043f\u043a\u043e\u0439, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043e\u0431\u0437\u043e\u0440 \u0432 YouTube \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u044d\u0442\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c, \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f \u043d\u0438\u0445 \u043f\u043e\u0434 \u041f\u041b\u0418\u0421. \u0410 \u0442.\u043a. \u0432\u044b\u0448\u0435\u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0430\u044f \u043f\u043b\u0430\u0442\u0430 \u043d\u0430 \u0431\u043e\u0440\u0442\u0443 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0442\u043e\u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a, \u0442\u043e \u0435\u0449\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c\u044b \u043f\u0443\u043b\u044c\u0442\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u043e\u0439 \u0441\u0435\u0431\u0435 \u043f\u0440\u0435\u0434\u043d\u043e\u0432\u043e\u0433\u043e\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0434\u043d\u044f. <\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"rabota-s-ws2811\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 WS2811<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438, \u0438\u0437 \u0434\u0430\u0442\u0430\u0448\u0438\u0442\u0430 \u043d\u0430 WS2811 \u0432\u0438\u0434\u043d\u043e \u2014 \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442: \u043d\u0430 \u0432\u044b\u0432\u043e\u0434 DIN \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c\u044b \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c 24 \u0431\u0438\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0446\u0432\u0435\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 RGB888 MSB-first. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 24 \u0431\u0438\u0442\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c\u0430 \u043f\u0440\u043e\u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u0432\u044b\u0432\u043e\u0434\u0435 DOUT, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c WS2811 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0446\u0435\u043f\u043e\u0447\u043a\u0438: <\/p>\n<p>  <\/p>\n<p><em>\u0421\u0445\u0435\u043c\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f WS2811 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c:<\/em><br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ws\/80\/bt\/ws80bteheqa1q8cjkjjqn90h_fa.png\" alt=\"\u0421\u0445\u0435\u043c\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f WS2811 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c\"><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0430 \u0432\u044b\u0432\u043e\u0434\u0435 DIN \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043d\u0443\u043b\u044f \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0414\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0434\u0438\u043d \u2014 \u044d\u0442\u043e \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 1.2 \u00b5s \u0438 \u043d\u0438\u0437\u043a\u0438\u0439 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 1.3 \u00b5s, \u0430 \u0434\u043b\u044f \u043d\u0443\u043b\u044f \u2014 0.5 \u00b5s \u0438 2.0 \u00b5s \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0418\u0437 \u0447\u0435\u0433\u043e \u0432\u0438\u0434\u043d\u043e \u2014 \u0447\u0442\u043e \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0431\u0438\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u043e\u0431\u043e\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 2.5 \u00b5s. \u0414\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0438\u0437\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c 50 \u00b5s, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043a\u0432\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u0428\u0418\u041c \u043d\u0430 \u0432\u044b\u0432\u043e\u0434\u0430\u0445 OUTR ,OUTG \u0438 OUTB, \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043d\u043e\u0432\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0446\u0432\u0435\u0442\u0430. <\/p>\n<p>  <\/p>\n<p><em>\u0422\u0430\u0439\u043c\u0438\u043d\u0433\u0438 \u0434\u043b\u044f WS2811:<\/em><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/us\/bu\/g2\/usbug2otv0uo2hg8gwpnfh3ham0.png\" alt=\"\u0422\u0430\u0439\u043c\u0438\u043d\u0433\u0438 \u0434\u043b\u044f WS2811\"><\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya-ws2811-protokola-v-module-ws2811transmitter\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f WS2811 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 WS2811Transmitter<\/h2>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">WS2811Transmitter.sv<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vhdl\">module WS2811Transmitter # (     CLOCK_SPEED = 50_000_000 ) (     input clkIN,     input nResetIN,     input startIN,     input [23:0] dataIN,     output busyOUT,     output txOUT );  localparam DIVIDER_100_NS = 10_000_000; \/\/ 1 \/ 0.0000001 = 10000000  reg [4:0]  cnt100ns; reg [24:0] dataShift; reg busy; reg tx;  wire [24:0] dataShifted = (dataShift &lt;&lt; 1); wire clock100ns;  initial begin     busy = 0;     tx  = 0;     cnt100ns = 5'd0; end  assign busyOUT = busy; assign txOUT = tx;  ClockDivider #(.VALUE(CLOCK_SPEED \/ DIVIDER_100_NS)) clock100nsDivider (     .clkIN(clkIN),     .nResetIN(busy),     .clkOUT(clock100ns) );  always @(negedge clkIN or negedge nResetIN) begin     if (!nResetIN) begin         busy &lt;= 0;         tx  &lt;= 0;         cnt100ns &lt;= 5'd0;     end     else begin         if (startIN &amp;&amp; !busy) begin             busy &lt;= 1;             dataShift &lt;= {dataIN, 1'b1};             tx &lt;= 1;         end          if (clock100ns &amp;&amp; busy) begin             cnt100ns &lt;= cnt100ns + 5'd1;             if (cnt100ns == 5'd4 &amp;&amp; !dataShift[24]) begin                 tx &lt;= 0;             end             if (cnt100ns == 5'd11 &amp;&amp; dataShift[24]) begin                 tx &lt;= 0;             end             if (cnt100ns == 5'd24) begin                 cnt100ns &lt;= 5'd0;                 dataShift &lt;= dataShifted;                 if (dataShifted == 25'h1000000) begin                     busy &lt;= 0;                 end                 else begin                     tx &lt;= 1;                 end                      end         end     end end  endmodule<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0437\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u044f \u0437\u0430\u0432\u0435\u043b \u0441\u0447\u0435\u0442\u0447\u0438\u043a clock100nsDivider \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 \u0432 100 ns, \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u043c\u043f\u0443\u043b\u044c\u0441 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 clock100ns \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 cnt100ns \u043d\u0430 \u0435\u0434\u0438\u043d\u0438\u0446\u0443. \u041f\u0435\u0440\u0435\u0432\u0435\u0434\u044f \u0441\u0438\u0433\u043d\u0430\u043b startIN \u0432 1, \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c 1 \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0435 busyOUT. \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u0438\u0442\u0430 \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u043b\u0435 txOUT \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430, \u0430 \u043f\u043e\u0441\u043b\u0435 12 \u043e\u0442\u0441\u0447\u0435\u0442\u043e\u0432 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 cnt100ns \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0434\u0438\u043d \u0438\u043b\u0438 5 \u043e\u0442\u0441\u0447\u0435\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u043b\u044c \u2014 \u0441\u0438\u0433\u043d\u0430\u043b txOUT \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043d\u043e\u043b\u044c. \u041f\u043e\u0441\u043b\u0435 25 \u043e\u0442\u0441\u0447\u0435\u0442\u043e\u0432 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u0438\u0442\u0430, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 24 \u0431\u0438\u0442\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u0442 \u0441\u0438\u0433\u043d\u0430\u043b busyOUT \u0432 0. <\/p>\n<p>  <\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u2014 \u044d\u0442\u043e \u0442\u043e \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0437\u0430\u0434\u043d\u0435\u043c\u0443 \u0444\u0440\u043e\u043d\u0442\u0443 \u0442\u0430\u043a\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u043c\u043f\u0443\u043b\u044c\u0441\u0430. \u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u0443\u0436\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u0430\u043a\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 busyOUT. <\/p>\n<p>  <\/p>\n<p><em>\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 24 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0446\u0432\u0435\u0442\u0430 FF0055h \u0434\u043b\u044f WS2811Transmitter:<\/em><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/pz\/1t\/su\/pz1tsu74rhi7jyqib2enzreunno.png\" alt=\"\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 24 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0446\u0432\u0435\u0442\u0430 FF0055h \u0434\u043b\u044f WS2811Transmitter\"><\/p>\n<p>  <\/p>\n<h2 id=\"rabota-s-ik-pultom\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0418\u041a \u043f\u0443\u043b\u044c\u0442\u043e\u043c<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043d\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 NEC Infrared Transmission Protocol. \u041d\u043e\u043b\u044c \u0437\u0434\u0435\u0441\u044c \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043b\u0438\u0447\u0438\u0435\u043c \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 562.5\u00b5s \u0438 \u043f\u0430\u0443\u0437\u043e\u0439 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 562.5\u00b5s. \u0415\u0434\u0438\u043d\u0438\u0446\u0430 \u2014 562.5\u00b5s \u0438 1.6875ms \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041d\u0430\u0447\u0430\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 9ms \u0441\u0438\u0433\u043d\u0430\u043b \u0438 4.5ms \u043f\u0430\u0443\u0437\u0430. \u0410 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0438\u043c\u043f\u0443\u043b\u044c\u0441 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 562.5\u00b5s \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438. <\/p>\n<p>  <\/p>\n<p>\u0412\u0435\u0441\u044c \u043f\u0430\u043a\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437: \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (9ms \u0441\u0438\u0433\u043d\u0430\u043b \u0438 4.5ms \u043f\u0430\u0443\u0437\u0430), 8 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, 8 \u0431\u0438\u0442 \u2014 \u043f\u043e\u0431\u0438\u0442\u043e\u0432\u0430\u044f \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430, 8 \u0431\u0438\u0442 \u2014 \u043a\u043e\u043c\u0430\u043d\u0434\u0430, 8 \u0431\u0438\u0442 \u0435\u0435 \u043f\u043e\u0431\u0438\u0442\u043e\u0432\u0430\u044f \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044f \u0438 562.5\u00b5s \u0438\u043c\u043f\u0443\u043b\u044c\u0441 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438. \u0412\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 LSB-first. <\/p>\n<p>  <\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c NEC Infrared Transmission \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430:<\/em><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ym\/x-\/yb\/ymx-ybtlkznx77ereyzioztrggm.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c NEC Infrared Transmission \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\"><\/p>\n<p>  <\/p>\n<h2 id=\"realizaciya-nec-protokola-v-module-necirreceiver\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f NEC \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 NecIrReceiver<\/h2>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">NecIrReceiver.sv<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vhdl\">module NecIrReceiver # (     CLOCK_SPEED = 50_000 ) (     input clkIN,     input nResetIN,     input rxIN,     output dataReceivedOUT,     output [31:0] dataOUT );  localparam DIVIDER_281250_NS = 3556; \/\/ 562.5\u00b5s \/ 2 = 281.25\u00b5s; 1 \/ 0.00028125 \u2248 3556  reg [23:0] pulseSamplerShift; reg [33:0] dataShift; reg [31:0] dataBuffer; reg [1:0] rxState; reg rxPositiveEdgeDetect; reg clock281250nsParity; reg clock281250nsNReset;  wire clock281250ns; wire startFrameReceived; wire dataPacketReceived;  initial begin     rxState = 2'd0;     rxPositiveEdgeDetect = 0;     clock281250nsParity = 0;     clock281250nsNReset = 0;     pulseSamplerShift = 24'd0;     dataShift = 34'd0;     dataBuffer = 32'd0; end  assign dataReceivedOUT = rxState[0]; assign dataOUT = dataBuffer; assign dataPacketReceived = dataShift[32]; assign startFrameReceived = dataShift[33];  ClockDivider #(.VALUE(CLOCK_SPEED \/ DIVIDER_281250_NS)) clock281250nsDivider (     .clkIN(clkIN),     .nResetIN(clock281250nsNReset),     .clkOUT(clock281250ns) );  always @(posedge clkIN or negedge nResetIN) begin     if (!nResetIN) begin         rxState &lt;= 2'd0;         rxPositiveEdgeDetect &lt;= 0;         clock281250nsParity &lt;= 0;         clock281250nsNReset &lt;= 0;         pulseSamplerShift &lt;= 24'd0;         dataShift &lt;= 34'd0;         dataBuffer &lt;= 32'd0;     end     else begin         case ({dataPacketReceived, rxState[1:0]})             3'b100 : begin                 dataBuffer[31:0] &lt;= dataShift[31:0];                 rxState &lt;= 2'b11;             end             3'b111, 3'b110 : rxState &lt;= 2'b10;             default : rxState &lt;= 2'd0;         endcase          case ({rxIN, rxPositiveEdgeDetect})             2'b10 : begin                 rxPositiveEdgeDetect &lt;= 1;                 clock281250nsParity &lt;= 0;                 clock281250nsNReset &lt;= 0;                 pulseSamplerShift &lt;= 24'd0;                  case ({startFrameReceived, dataPacketReceived, pulseSamplerShift})                     26'h0ffff00 : dataShift &lt;= 34'h200000001;                     26'h2000002 : dataShift &lt;= {1'd1, dataShift[31:0], 1'd0};                     26'h2000008 : dataShift &lt;= {1'd1, dataShift[31:0], 1'd1};                     default : dataShift &lt;= 34'd0;                 endcase             end             2'b01 : rxPositiveEdgeDetect &lt;= 0;         endcase          if (clock281250nsNReset == 0) begin             clock281250nsNReset &lt;= 1;         end          if (clock281250ns) begin             clock281250nsParity &lt;= ~clock281250nsParity;              if (!clock281250nsParity) begin                 pulseSamplerShift &lt;= {pulseSamplerShift[22:0], rxIN};             end         end     end end  endmodule<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0442\u0430\u0439\u043c\u0438\u043d\u0433\u0438 \u0437\u0434\u0435\u0441\u044c \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 562.5\u00b5s. \u0417\u043d\u0430\u0447\u0438\u0442 \u0437\u0430\u0432\u0435\u0434\u0435\u043c \u0441\u0434\u0432\u0438\u0433\u043e\u0432\u044b\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 pulseSamplerShift \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0441\u044d\u043c\u043f\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 rxIN \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0436\u0434\u044b\u0435 562.5\u00b5s. \u0422.\u043a. \u0437\u0430\u0445\u0432\u0430\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u0435\u0433\u043e \u0444\u0440\u043e\u043d\u0442\u0430\u043c\u0438, \u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u044b ClockDivider \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u0432 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u043c\u0435\u043d\u044c\u0448\u0443\u044e \u2014 281.25\u00b5s. \u041f\u043e \u0438\u043c\u043f\u0443\u043b\u044c\u0441\u0443 \u043e\u0442 clock281250ns \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438 clock281250nsParity, \u0438 \u043d\u0430 \u0432\u0441\u0435 \u043d\u0435\u0447\u0435\u0442\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0437\u0430\u0445\u0432\u0430\u0442. \u0421\u0438\u0433\u043d\u0430\u043b\u043e\u043c rxPositiveEdgeDetect \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u0435\u0440\u0435\u0434\u043d\u0438\u0439 \u0444\u0440\u043e\u043d\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u0430, \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 pulseSamplerShift \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0433\u043e \u0438\u043c\u043f\u0443\u043b\u044c\u0441\u0430, \u043d\u043e\u043b\u044f \u0438\u043b\u0438 \u0435\u0434\u0438\u043d\u0438\u0446\u044b. <\/p>\n<p>  <\/p>\n<p><em>\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u0438\u0435\u043c\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 00FF0FF0h \u0434\u043b\u044f NecIrReceiver:<\/em><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/yn\/ez\/uj\/ynezujxs9dnxrst62d1jxhq3ox8.png\" alt=\"\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u043f\u0440\u0438\u0435\u043c\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 00FF0FF0h \u0434\u043b\u044f NecIrReceiver\"><\/p>\n<p>  <\/p>\n<h2 id=\"osnovnoy-modul-main\">\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044c Main<\/h2>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Main.sv<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"vhdl\">module Main (     input clkIN,     input nResetIN,     input rxIN,     output txOUT );  localparam IR_COMMAND_EQ   = 32'h00ff906f; localparam IR_COMMAND_PLAY = 32'h00ffc23d; localparam IR_COMMAND_PREV = 32'h00ff22dd; localparam IR_COMMAND_NEXT = 32'h00ff02fd; localparam IR_COMMAND_MINS = 32'h00ffe01f; localparam IR_COMMAND_PLUS = 32'h00ffa857;  localparam UNITS_NUMBER = 100; localparam PATTERN_COLORS_NUMBER = 128; localparam PATTERNS_NUMBER = 4; localparam CLOCK_SPEED = 50_000_000; localparam UPDATES_PER_SECOND = 20;  reg [$clog2(PATTERNS_NUMBER) - 1:0] patternIndex; reg [$clog2(PATTERN_COLORS_NUMBER) - 1:0] colorIndex; reg [$clog2(PATTERN_COLORS_NUMBER) - 1:0] colorIndexShift; reg colorIndexShiftDirection; reg [2:0] colorSwapIndex; reg [$clog2(UNITS_NUMBER) - 1:0] unitCounter; reg txStart; reg pause; reg beginTransmissionDelay;  wire ws2811Busy; wire beginTransmission; wire [23:0] colorData; wire [23:0] colorDataSwapped; wire [0:$clog2(PATTERNS_NUMBER * PATTERN_COLORS_NUMBER) - 1] colorIndexComputed; wire irCommandReceived; wire [31:0] irCommand; wire rxFiltered;  initial begin     patternIndex = 0;     colorIndex = 0;     colorIndexShift = 0;     colorIndexShiftDirection = 0;     colorSwapIndex = 0;     unitCounter = 0;     txStart = 0;     pause = 0;     beginTransmissionDelay = 0; end  assign colorIndexComputed = {patternIndex, (colorIndex + colorIndexShift)};  ROM1 rom(     .clock(clkIN),     .address(colorIndexComputed),     .q(colorData) );  ColorSwap colorSwapper (     .dataIN(colorData),     .swapIN(colorSwapIndex),     .dataOUT(colorDataSwapped) );  RXMajority3Filter rxInFilter (     .clockIN(clkIN),     .nResetIN(nResetIN),     .rxIN(rxIN),     .rxOUT(rxFiltered) );  NecIrReceiver #(.CLOCK_SPEED(CLOCK_SPEED))     necIrReceiver (     .clkIN(clkIN),     .nResetIN(nResetIN),     .rxIN(~rxFiltered),     .dataReceivedOUT(irCommandReceived),     .dataOUT(irCommand) );  ClockDivider #(.VALUE(CLOCK_SPEED \/ UPDATES_PER_SECOND))     beginTransmissionTrigger (     .clkIN(clkIN),     .nResetIN(nResetIN),     .clkOUT(beginTransmission) );  WS2811Transmitter #(.CLOCK_SPEED(CLOCK_SPEED))      ws2811tx (     .clkIN(clkIN),     .nResetIN(nResetIN),     .startIN(txStart),     .dataIN(colorDataSwapped),     .busyOUT(ws2811Busy),     .txOUT(txOUT) );  always @(posedge clkIN or negedge nResetIN) begin     if (!nResetIN) begin         patternIndex &lt;= 0;         colorIndex &lt;= 0;         colorIndexShift &lt;= 0;         colorIndexShiftDirection &lt;= 0;         colorSwapIndex &lt;= 0;         unitCounter &lt;= 0;         txStart &lt;= 0;         pause &lt;= 0;         beginTransmissionDelay &lt;= 0;     end     else begin         if (irCommandReceived) begin             case (irCommand)                 IR_COMMAND_PLAY : pause &lt;= ~pause;                 IR_COMMAND_EQ   : colorIndexShiftDirection &lt;= ~colorIndexShiftDirection;                 IR_COMMAND_NEXT : patternIndex &lt;= patternIndex + 1;                 IR_COMMAND_PREV : patternIndex &lt;= patternIndex - 1;                 IR_COMMAND_PLUS : colorSwapIndex &lt;= (colorSwapIndex == 3'd5) ? 0 : (colorSwapIndex + 1);                 IR_COMMAND_MINS : colorSwapIndex &lt;= (colorSwapIndex == 0) ? 3'd5 : (colorSwapIndex - 1);             endcase         end          if (beginTransmission) begin             unitCounter &lt;= UNITS_NUMBER;             colorIndex &lt;= 0;             case ({colorIndexShiftDirection, pause})                 2'b10 : colorIndexShift &lt;= colorIndexShift + 1;                 2'b00 : colorIndexShift &lt;= colorIndexShift - 1;             endcase             beginTransmissionDelay &lt;= 1;         end         else if (beginTransmissionDelay) begin             beginTransmissionDelay &lt;= 0;         end         else if (unitCounter != 0 &amp;&amp; !ws2811Busy) begin             colorIndex &lt;= colorIndex + 1;             unitCounter &lt;= unitCounter - 1;             txStart &lt;= 1;         end         else begin             txStart &lt;= 0;         end     end end  endmodule<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u201c\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b\u201d \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 beginTransmission \u0441\u0438\u0433\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u043d\u043e\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0446\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u0443\u044e \u043b\u0435\u043d\u0442\u0443. \u041f\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0443 irCommandReceived \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0440\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u043d\u044f\u0442\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043e\u0442 \u0418\u041a \u043f\u0443\u043b\u044c\u0442\u0430: \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0435\u0433\u0443\u0449\u0438\u0445 \u043e\u0433\u043d\u0435\u0439, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0431\u043e\u0440\u0430 \u0446\u0432\u0435\u0442\u043e\u0432 \u0438 \u0441\u043c\u0435\u043d\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u043d\u0438\u044f RGB \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 ColorSwap \u043c\u043e\u0434\u0443\u043b\u044f. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0431\u043e\u0440\u044b \u0446\u0432\u0435\u0442\u043e\u0432 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 EP4CE6E22C8N \u0447\u0438\u043f\u0430, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0439 M9K Memory Blocks. \u042d\u0442\u0438 \u0431\u043b\u043e\u043a\u0438, \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043a\u0430\u043a ROM, \u0438 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d\u044b 24-\u0445 \u0431\u0438\u0442\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0444\u0430\u0439\u043b \u0444\u043e\u0440\u043c\u0430\u0442\u0430 .mif \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 ROM Megafunction \u0432 Quartus \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d ROM.v \u043c\u043e\u0434\u0443\u043b\u044c. \u041f\u0440\u0438 \u0441\u0438\u043d\u0442\u0435\u0437\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 .mif \u0444\u0430\u0439\u043b\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 .sof \u0444\u0430\u0439\u043b, \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0432 \u0447\u0438\u043f \u043d\u0430 \u0441\u0442\u0430\u0434\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u044d\u043d\u0435\u0440\u0433\u043e\u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u041f\u041b\u0418\u0421. <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0431\u043e\u0440\u0430 \u0446\u0432\u0435\u0442\u043e\u0432 \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 color_patterns_generator.js \u043f\u043e\u0434 Node.js, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 rom.mif \u0444\u0430\u0439\u043b: <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">color_patterns_generator.js<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">fs = require(&quot;fs&quot;);  const MODE_REPEAT = &quot;repeat&quot;; const MODE_STRETCH = &quot;stretch&quot;; const MODE_GRADIENT_STRETCH = &quot;gradient-stretch&quot;;  const ROM_FILE_NAME = &quot;rom.mif&quot;; const COLORS_NUM = 128; const COLORS_PATTERNS = [{         mode: MODE_GRADIENT_STRETCH,         colors: [             0xff0000,             0xff0000,             0xff00ff,             0xff00ff,             0x0000ff,             0x0000ff,             0xff00ff,             0xff00ff,             0xffff00,             0xffff00,             0x00ffff,             0x00ffff,             0x00ff00,             0x00ff00,             0xff0000,         ]     }, {         mode: MODE_STRETCH,         colors: [             0xff0000,             0xff0000,             0xff00ff,             0xff00ff,             0x0000ff,             0x0000ff,             0xff00ff,             0xff00ff,             0xffff00,             0xffff00,             0x00ffff,             0x00ffff,             0x00ff00,             0x00ff00,         ]     }, {         mode: MODE_REPEAT,         colors: [             0xff0000,             0xff0000,             0xff0000,             0xff0000,             0xff0000,             0xff0000,             0xff0000,             0xffffff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xffffff,             0x0000ff,             0x0000ff,             0x0000ff,             0x0000ff,             0x0000ff,             0x0000ff,             0x0000ff,             0xffffff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0xffffff,             0xffff00,             0xffff00,             0xffff00,             0xffff00,             0xffff00,             0xffff00,             0xffff00,             0xffffff,             0x00ffff,             0x00ffff,             0x00ffff,             0x00ffff,             0x00ffff,             0x00ffff,             0x00ffff,             0xffffff,             0x00ff00,             0x00ff00,             0x00ff00,             0x00ff00,             0x00ff00,             0x00ff00,             0x00ff00,             0xffffff,         ]     }, {         mode: MODE_REPEAT,         colors: [             0xff0000,             0xff0000,             0x00ff00,             0x00ff00,             0xffff00,             0xffff00,             0xff0000,             0xff0000,             0xff0000,             0x00ff00,             0x00ff00,             0x00ff00,             0xffff00,             0xffff00,             0xffff00,             0xff00ff,             0xff00ff,             0xff00ff,             0xff00ff,             0x00ff00,             0x00ff00,             0x00ff00,             0x00ff00,             0xffff00,             0xffff00,             0xffff00,             0xffff00,         ]     } ];  function getRed(color) {     return ((color &gt;&gt; 16) &amp; 0xff) } function getGreen(color) {     return ((color &gt;&gt; 8) &amp; 0xff) } function getBlue(color) {     return ((color) &amp; 0xff) } function toHex(d) {     let result = Number(d).toString(16).toUpperCase();     return result.length % 2 ? &quot;0&quot; + result : result; } function generate() {     let result = &quot;&quot;;     let byteAddress = 0;      result += &quot;WIDTH = 24;                   -- The size of data in bits\\n&quot;;     result += &quot;DEPTH = &quot; + (COLORS_NUM * COLORS_PATTERNS.length) + &quot;;                   -- The size of memory in words\\n&quot;;     result += &quot;ADDRESS_RADIX = HEX;          -- The radix for address values\\n&quot;;     result += &quot;DATA_RADIX = HEX;             -- The radix for data values\\n&quot;;     result += &quot;CONTENT                       -- start of (address : data pairs)\\n&quot;;     result += &quot;BEGIN\\n&quot;;      let red;     let green;     let blue;      for (let pattern of COLORS_PATTERNS) {         for (let i = 0; i &lt; COLORS_NUM; i++) {             if (pattern.mode === MODE_GRADIENT_STRETCH) {                 let index = i * (pattern.colors.length - 1) \/ COLORS_NUM;                 let colorA = pattern.colors[Math.floor(index)];                 let colorB = pattern.colors[Math.floor(index) + 1];                 let colorBValue = index % 1;                 let colorAValue = 1 - colorBValue;                  red = Math.round(getRed(colorA) * colorAValue + getRed(colorB) * colorBValue);                 green = Math.round(getGreen(colorA) * colorAValue + getGreen(colorB) * colorBValue);                 blue = Math.round(getBlue(colorA) * colorAValue + getBlue(colorB) * colorBValue);             } else if (pattern.mode === MODE_STRETCH) {                 let index = Math.floor(i * pattern.colors.length \/ COLORS_NUM);                 let color = pattern.colors[index];                  red = getRed(color);                 green = getGreen(color);                 blue = getBlue(color);             } else if (pattern.mode === MODE_REPEAT) {                 let index = i % pattern.colors.length;                 let color = pattern.colors[index];                  red = getRed(color);                 green = getGreen(color);                 blue = getBlue(color);             }              result +=                 toHex(i + byteAddress) + &quot; : &quot; +                 toHex(red) +                 toHex(green) +                 toHex(blue) + &quot;;\\n&quot;;         }          byteAddress += COLORS_NUM;     }      result += &quot;END;&quot;;     return result; }  try {     fs.writeFileSync(ROM_FILE_NAME, generate());     console.log(&quot;Success&quot;); } catch (err) {     console.log(&quot;Failed\\n&quot;, err); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0418 \u0432\u043e\u0442 \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e: <\/p>\n<p>  <\/p>\n<div class=\"oembed\"><iframe id=\"5fc233bf905dc4e15aeed80d\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/5fc233bf905dc4e15aeed80d\"><\/iframe><\/div>\n<p>  <\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043f\u0438\u0440\u043e\u0433\u0438 \ud83d\ude42 <\/p>\n<p>  <\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 <a href=\"https:\/\/github.com\/Hypnotriod\/ep4ce6e22c8n-ws2811-fpga-driver\" rel=\"nofollow\">GitHub<\/a><\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/530358\/\"> https:\/\/habr.com\/ru\/post\/530358\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/17\/lx\/9c\/17lx9cl6md2cimivsmuceallq8s.jpeg\"><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u0423\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0434\u0432\u0430 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u044f \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u043b \u043d\u0430 aliexpress \u043a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439 \u043d\u0430\u0431\u043e\u0440, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u043e\u0439 \u043f\u043b\u0430\u0442\u044b EasyFPGA A2.2, \u0441 Cyclone IV EP4CE6E22C8N \u043d\u0430 \u0431\u043e\u0440\u0442\u0443, \u0418\u041a \u043f\u0443\u043b\u044c\u0442\u0430 SE-020401, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u043e\u0440\u0430, \u043f\u0430\u0440\u044b USB \u043f\u0440\u043e\u0432\u043e\u0434\u043e\u0432 \u0438 \u0448\u043b\u0435\u0439\u0444\u043e\u0432. \u0414\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u0431\u0440\u043e \u043b\u0435\u0436\u0430\u043b\u043e \u0443 \u043c\u0435\u043d\u044f \u0431\u0435\u0437 \u0434\u0435\u043b\u0430, \u0442.\u043a. \u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043c\u043e\u0433 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0438 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u043e\u0439 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. <\/p>\n<p>  <\/p>\n<p>\u0415\u0449\u0435 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0433\u043e\u0434\u0443 \u043d\u0430 \u0442\u043e\u043c-\u0436\u0435 aliexpress \u044f \u0437\u0430\u043a\u0430\u0437\u0430\u043b RGB \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043d\u0443\u044e \u043b\u0435\u043d\u0442\u0443 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0432\u0441\u0435\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 WS2811 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c. \u041f\u0435\u0440\u0435\u0434 \u043f\u043e\u043a\u0443\u043f\u043a\u043e\u0439, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0432 \u043e\u0431\u0437\u043e\u0440 \u0432 YouTube \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u044d\u0442\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u0441\u0445\u0435\u043c, \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0434\u043b\u044f \u043d\u0438\u0445 \u043f\u043e\u0434 \u041f\u041b\u0418\u0421. \u0410 \u0442.\u043a. \u0432\u044b\u0448\u0435\u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0430\u044f \u043f\u043b\u0430\u0442\u0430 \u043d\u0430 \u0431\u043e\u0440\u0442\u0443 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0442\u043e\u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a, \u0442\u043e \u0435\u0449\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0449\u0435\u043b\u043a\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c\u044b \u043f\u0443\u043b\u044c\u0442\u0438\u043a\u043e\u043c \u0438\u0437 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u043e\u0439 \u0441\u0435\u0431\u0435 \u043f\u0440\u0435\u0434\u043d\u043e\u0432\u043e\u0433\u043e\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0434\u043d\u044f. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-313973","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/313973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=313973"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/313973\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=313973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=313973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=313973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}