设为首页收藏本站帮助中心
查看: 536|回复: 3
收起左侧

Quartus Verilog HDL/FPGA 驱动圆环24位级联WS2812B灯珠并演示RGB全彩循环旋转流水灯

[复制链接]
发表于 2023-4-7 08:06:03 | 显示全部楼层 |阅读模式
main.png
  1. `define ws2812_num         8'd23                //WS2812B级联数量+1 (7表示级联8颗,最大256颗,以此类推)

  2. module rgb_array(                        //RGB颜色数组模块
  3.         input inc,                                //异步上升沿指针+1
  4.         input clr,                                //异步上升沿指针=0
  5.         input [7:0] num,                //[8位宽] 灯珠级联数量:1~256 (8颗输入7,以此类推)
  6.         input [7:0] pc2,                //[8位宽] 指针偏移量
  7.         output [7:0] red,                //[8位宽] 红色值:0~255
  8.         output [7:0] green,        //[8位宽] 绿色值:0~255
  9.         output [7:0] blue                //[8位宽] 蓝色值:0~255
  10. );

  11. reg [7:0] r = 8'd0;
  12. reg [7:0] g = 8'd0;
  13. reg [7:0] b = 8'd0;
  14. reg [7:0] pc = 8'd0;
  15. wire max = #
  16. assign {red,green,blue} = {r,g,b};

  17. always @(posedge inc or posedge clr) begin
  18.         if(clr) begin
  19.                 pc = 8'd0;
  20.         end else begin
  21.                 pc = pc + 8'd1;
  22.                 if(!max && pc > num) begin
  23.                         pc = 0;
  24.                 end
  25.         end
  26. end

  27. always @(*) begin
  28.         case(max ? (pc + pc2) : (pc+pc2) % (num+8'd1))
  29.                 8'd0:{r,g,b} = 24'hD42A00;
  30.                 8'd1:{r,g,b} = 24'hAA5500;
  31.                 8'd2:{r,g,b} = 24'h7F7F00;
  32.                 8'd3:{r,g,b} = 24'h55AA00;
  33.                 8'd4:{r,g,b} = 24'h2AD400;
  34.                 8'd5:{r,g,b} = 24'h00FF00;                        //绿色 #00FF00
  35.                 8'd6:{r,g,b} = 24'h00D42A;
  36.                 8'd7:{r,g,b} = 24'h00AA55;
  37.                 8'd8:{r,g,b} = 24'h007F7F;
  38.                 8'd9:{r,g,b} = 24'h0055AA;
  39.                 8'd10:{r,g,b} = 24'h002AD4;
  40.                 8'd11:{r,g,b} = 24'h0000FF;                //蓝色 #0000FF
  41.                 8'd12:{r,g,b} = 24'h2A2AD4;
  42.                 8'd13:{r,g,b} = 24'h5555AA;
  43.                 8'd14:{r,g,b} = 24'h7F7F7F;
  44.                 8'd15:{r,g,b} = 24'hAAAA55;
  45.                 8'd16:{r,g,b} = 24'hD4D42A;
  46.                 8'd17:{r,g,b} = 24'hFFFF00;                //黄色 #FFFF00
  47.                 8'd18:{r,g,b} = 24'hFFD400;
  48.                 8'd19:{r,g,b} = 24'hFFAA00;
  49.                 8'd20:{r,g,b} = 24'hFF7F00;
  50.                 8'd21:{r,g,b} = 24'hFF5500;
  51.                 8'd22:{r,g,b} = 24'hFF2A00;
  52.                 8'd23:{r,g,b} = 24'hFF0000;                //红色 #FF0000
  53.                 default:{r,g,b} = 24'h000000;        //黑色 #000000 (灭灯)
  54.         endcase
  55. end

  56. endmodule

  57. module ws2812b(                        //WS2812B全彩RGB LED灯驱动模块
  58.         input clk,                                //50Mhz 时钟输入
  59.         input start,                        //同步上升沿刷新显示
  60.         input [7:0] num,                //[8位宽] 灯珠级联数量:1~256 (8颗输入7,以此类推)
  61.         input [7:0] red,                //[8位宽] 灯珠红色值:0~255
  62.         input [7:0] green,        //[8位宽] 灯珠绿色值:0~255
  63.         input [7:0] blue,                //[8位宽] 灯珠蓝色值:0~255
  64.         output reg inc,                //异步上升沿指针+1,读取下一个灯珠颜色
  65.         output reg clr,                //异步上升沿指针=0,读取第一个灯珠颜色
  66.         output reg run,                //刷新显示开始置1,完成后清0
  67.         output reg dout                //接ws2812b的din (第一颗灯珠的dout接第二颗灯珠的din,以此类推)
  68. );

  69. initial {inc,clr,run,dout} = 4'b0;
  70. wire [0:23] rgb = {green,red,blue};
  71. reg [11:0] delay = 12'd0;
  72. reg [2:0] state = 3'd0;
  73. reg [4:0] i = 5'b0;
  74. reg [7:0] pc = 8'd0;
  75. reg s = 1'b0;
  76. reg q = 1'b0;
  77. always @(posedge clk) begin
  78.         s <= start;
  79.         if(start && !s) begin
  80.                 run <= 1'b1;
  81.                 q <= 1'b0;
  82.         end
  83.         if(run) begin
  84.                 if(|delay) begin                                //有延时
  85.                         delay <= delay - 12'd1;
  86.                 end else begin                //没有延时
  87.                         case(state)
  88.                                 3'd0:begin
  89.                                         if(q) begin
  90.                                                 inc <= 1'b1;
  91.                                         end else begin
  92.                                                 clr <= 1'b1;
  93.                                         end
  94.                                         delay <= 12'd1;
  95.                                         state <= 3'd1;
  96.                                 end
  97.                                        
  98.                                 3'd1:begin
  99.                                         if(q) begin
  100.                                                 inc <= 1'b0;
  101.                                         end else begin
  102.                                                 clr <= 1'b0;
  103.                                                 q <= 1'b1;
  104.                                         end
  105.                                         delay <= 12'd1;
  106.                                         state <= 3'd2;
  107.                                 end
  108.                                        
  109.                                 3'd2:begin                //高电平时间
  110.                                         dout <= 1'b1;
  111.                                         delay <= rgb[i] ? 12'd43 : 12'd20;
  112.                                         state <= 3'd3;                               
  113.                                 end
  114.                                        
  115.                                 3'd3:begin                //低电平时间
  116.                                         dout <= 1'b0;
  117.                                         delay <= rgb[i] ? 12'd20 : 12'd43;
  118.                                         i = i + 5'd1;
  119.                                         if(i >= 5'd24) begin
  120.                                                 i = 0;
  121.                                                 pc <= pc + 8'd1;
  122.                                                 if(pc >= num) begin
  123.                                                         pc <= 8'd0;
  124.                                                         state <= 3'd4;
  125.                                                 end else begin
  126.                                                         state <= 3'd0;
  127.                                                 end
  128.                                         end else begin
  129.                                                 state <= 3'd2;
  130.                                         end
  131.                                 end
  132.                                        
  133.                                 3'd4:begin                                                //帧复位信号
  134.                                         dout <= 1'b0;
  135.                                         delay <= 12'd2500;                //延时50us
  136.                                         state <= 3'd5;                               
  137.                                 end
  138.                                 default:begin
  139.                                         run <= 1'b0;
  140.                                         state <= 3'd0;
  141.                                         q <= 1'b0;
  142.                                 end
  143.                         endcase
  144.                 end
  145.         end
  146. end
  147. endmodule

  148. module main(
  149.         input clk,                        //50Mhz Pin17
  150.         output dout                        //接WS2812B的din Pin40
  151. );

  152. reg [7:0] pc2 = 8'd0;        //灯珠副指针 (控制颜色旋转角度与偏移量)
  153. reg start = 1'b0;
  154. reg spin = 1'b0;                //旋转方向 1:顺时针 0:逆时针
  155. reg revolve = 1'b0;        //是否旋转 1:是 0:否

  156. wire [7:0] red;
  157. wire [7:0] green;
  158. wire [7:0] blue;

  159. wire run;
  160. wire inc;
  161. wire clr;

  162. ws2812b ws2812b(
  163.         .clk(clk),                        //50Mhz 时钟
  164.         .start(start),
  165.         .num(`ws2812_num),                //级联灯珠数量
  166.         .red(red),                //红色值
  167.         .green(green),        //绿色值
  168.         .blue(blue),        //蓝色值
  169.         .inc(inc),
  170.         .clr(clr),
  171.         .run(run),
  172.         .dout(dout)                //ws2812b 时序信号输出
  173. );

  174. rgb_array rgb_array(
  175.         .inc(inc),
  176.         .clr(clr),
  177.         .num(`ws2812_num),
  178.         .pc2(pc2),
  179.         .red(red),
  180.         .green(green),
  181.         .blue(blue)
  182. );

  183. integer t = 0;
  184. always @(posedge clk) begin
  185.         t = t + 1;
  186.         if(t >= 50000000/2/(`ws2812_num+1)) begin                //1秒转1圈
  187.                 t = 0;
  188.                 start <= !start;
  189.         end
  190. end

  191. integer l = 0;
  192. always @(posedge clk) begin                //停2秒,逆时针转2秒,停2秒,顺时针转2秒,以此类推
  193.         l = l + 1;
  194.         if(l >= 100000000) begin                //1亿个时钟即为2秒
  195.                 l = 0;
  196.                 {spin,revolve} <= {spin,revolve} + 2'd1;
  197.         end
  198. end

  199. always @(negedge run) begin                //灯珠颜色旋转控制
  200.         if(revolve) begin                //颜色旋转开启
  201.                 if(spin) begin                //顺时针旋转
  202.                         pc2 = pc2 - 8'd1;
  203.                         if(&pc2) begin
  204.                                 pc2 = `ws2812_num;
  205.                         end
  206.                 end else begin                //逆时针旋转
  207.                         pc2 = pc2 + 8'd1;
  208.                         if(pc2 > `ws2812_num) begin
  209.                                 pc2 = 8'd0;
  210.                         end
  211.                 end
  212.         end
  213. end
  214. endmodule
复制代码

相关帖子

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则