当前位置:   article > 正文

使用Uart串口控制LED灯闪烁_uart串口指令控制

uart串口指令控制

通过串口调试助手,使用串口发送电脑指令到fpga开发板,来控制led灯的工作状态。

通过三个模块来实现 串口控制led闪烁:

1.uart的数据接收模块:将用户数据通过串口调试助手发到fpga

2.串口命令模块:将uart接受模块的数据通过该模块,通过一个自定义协议来发送led灯所需的控制信号

3.led工作状态的控制模块:闪烁时间和闪烁状态由用户指定(Time,Ctrl[on/off])

自定义协议如下:

 类似于起始位和停止位的判定,通过数据的移位和比较,最后实现中间命令模块的编写,从而实现串口控制led灯(uart_rx模块和led_ctrl_time模块见前面所写)

PS:代码中Time的发送,是先发的高位再发的低位。

uart_cmd控制模块编写如下:

  1. `timescale 1ns / 1ps
  2. module uart_cmd(
  3. clk ,
  4. rst ,
  5. rx_data ,
  6. rx_done ,
  7. Time ,
  8. ctrl
  9. );
  10. input clk ;
  11. input rst ;
  12. input[7:0] rx_data ;
  13. input rx_done ;
  14. output[31:0] Time ;
  15. output[7:0] ctrl ;
  16. reg[7:0] data_str[7:0];
  17. reg[31:0] r_Time ;
  18. reg[7:0] r_ctrl ;
  19. assign Time =r_Time ;
  20. assign ctrl =r_ctrl ;
  21. always@(posedge clk ,negedge rst)begin
  22. if(!rst)begin
  23. data_str[0] <= 0;
  24. data_str[1] <= 0;
  25. data_str[2] <= 0;
  26. data_str[3] <= 0;
  27. data_str[4] <= 0;
  28. data_str[5] <= 0;
  29. data_str[6] <= 0;
  30. data_str[7] <= 0;
  31. end
  32. else if(rx_done)begin
  33. data_str[0] <= rx_data;
  34. data_str[1] <= data_str[0];
  35. data_str[2] <= data_str[1];
  36. data_str[3] <= data_str[2];
  37. data_str[4] <= data_str[3];
  38. data_str[5] <= data_str[4];
  39. data_str[6] <= data_str[5];
  40. data_str[7] <= data_str[6];
  41. end
  42. else begin
  43. data_str[0] <= data_str[0];
  44. data_str[1] <= data_str[1];
  45. data_str[2] <= data_str[2];
  46. data_str[3] <= data_str[3];
  47. data_str[4] <= data_str[4];
  48. data_str[5] <= data_str[5];
  49. data_str[6] <= data_str[6];
  50. data_str[7] <= data_str[7];
  51. end
  52. end
  53. always@(posedge clk ,negedge rst)begin
  54. if(!rst)begin
  55. r_Time <= 32'd0;
  56. r_ctrl <= 8'd0;
  57. end
  58. else if((data_str[0] == 8'hf0) && (data_str[6]==8'h05) && (data_str[7]==8'h55))begin
  59. r_Time <= {data_str[5],data_str[4],data_str[3],data_str[2]};
  60. r_ctrl <= data_str[1];
  61. end
  62. else begin
  63. r_Time <= 32'd0;
  64. r_ctrl <= 8'd0;
  65. end
  66. end
  67. endmodule

 顶层模块调用

  1. `timescale 1ns / 1ps
  2. module uart_ctrl_led(
  3. clk ,
  4. rst ,
  5. uart_rx ,
  6. led
  7. );
  8. input clk ;
  9. input rst ;
  10. input uart_rx;
  11. output led ;
  12. wire[7:0] data ;
  13. wire rx_done;
  14. wire[31:0] Time ;
  15. wire[7:0] ctrl ;
  16. uart_rx_byte uart_rx_byte_u0(
  17. .clk ( clk ),
  18. .rst ( rst ),
  19. .baud_set ( 7 ),
  20. .uart_rx ( uart_rx),
  21. .data ( data ),
  22. .rx_done (rx_done )
  23. );
  24. uart_cmd uart_cmd_u0(
  25. .clk ( clk ),
  26. .rst ( rst ),
  27. .rx_data ( data ),
  28. .rx_done ( rx_done),
  29. .Time ( Time ),
  30. .ctrl ( ctrl )
  31. );
  32. led_ctrl_time led_ctrl_time_u0(
  33. .clk ( clk ),
  34. .rst ( rst ),
  35. .Ctrl ( ctrl ),
  36. .Time ( Time ),
  37. .led ( led )
  38. );
  39. endmodule

tb文件

  1. `timescale 1ns / 1ps
  2. module uart_ctrl_led_tb();
  3. reg clk ;
  4. reg rst ;
  5. reg uart_rx ;
  6. wire led ;
  7. uart_ctrl_led uart_ctrl_led_1(
  8. .clk ( clk ),
  9. .rst ( rst ),
  10. .uart_rx ( uart_rx ),
  11. .led ( led )
  12. );
  13. initial clk = 0;
  14. always #10 clk = ~clk;
  15. initial begin
  16. rst = 0;
  17. #201;
  18. rst = 1;
  19. #200;
  20. uart_tx_byte(8'h55);
  21. #90000; //@(posedge rx_done);
  22. #5000;
  23. uart_tx_byte(8'h05);
  24. #90000;
  25. #5000;
  26. uart_tx_byte(8'h12);
  27. #90000;
  28. #5000;
  29. uart_tx_byte(8'h34);
  30. #90000;
  31. #5000;
  32. uart_tx_byte(8'h56);
  33. #90000;
  34. #5000;
  35. uart_tx_byte(8'h78);
  36. #90000;
  37. #5000;
  38. uart_tx_byte(8'h9a);
  39. #90000;
  40. #5000;
  41. uart_tx_byte(8'hf0);
  42. #90000;
  43. #5000;
  44. $stop;
  45. end
  46. task uart_tx_byte;
  47. input [7:0]tx_data;
  48. begin
  49. uart_rx = 1;
  50. #20;
  51. uart_rx = 0;
  52. #8680;
  53. uart_rx = tx_data[0];
  54. #8680;
  55. uart_rx = tx_data[1];
  56. #8680;
  57. uart_rx = tx_data[2];
  58. #8680;
  59. uart_rx = tx_data[3];
  60. #8680;
  61. uart_rx = tx_data[4];
  62. #8680;
  63. uart_rx = tx_data[5];
  64. #8680;
  65. uart_rx = tx_data[6];
  66. #8680;
  67. uart_rx = tx_data[7];
  68. #8680;
  69. uart_rx = 1;
  70. #8680;
  71. end
  72. endtask
  73. endmodule

仿真图

在此基础上,生成了bit流,上班运行:

实现0.5s传输一个数据,即Time = 25,000,000  对应的16进制数为01 7D 78 40 这样边设置完成了TIme[31:0]的设置,再将Ctrl ==AA(1010_1010)来控制led灯一亮一灭。

即串口发送 55 05 01 7D 78 40 A0 f0  ,这样便完成了串口控制led闪烁。

但是!!实际工程上板之后发现等了好久led灯才开始闪烁,在闪烁之后,再将ctrl== 1111_0000,使得led闪烁变慢,最后rst复位,都能够直接实现。

通过小梅哥的视频讲解得知:

所以在led闪烁的控制中,我们将计数器的清零条件由== 变为 >= ,这样就解决了这样的问题。!!!赞

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/760039
推荐阅读
  

闽ICP备14008679号