使用Uart串口控制LED灯闪烁

通过串口调试助手,使用串口发送电脑指令到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控制模块编写如下:

`timescale 1ns / 1ps

module uart_cmd(
    clk      ,
    rst      ,
    rx_data  ,
    rx_done  ,
    Time     ,
    ctrl     
    );
input                clk          ;  
input                rst          ;  
input[7:0]           rx_data      ;  
input                rx_done      ;  
output[31:0]         Time         ;  
output[7:0]          ctrl         ;
   
reg[7:0]             data_str[7:0];
reg[31:0]            r_Time       ;
reg[7:0]             r_ctrl       ; 
assign               Time =r_Time ;    
assign               ctrl =r_ctrl ;

always@(posedge clk ,negedge rst)begin
    if(!rst)begin
        data_str[0] <= 0;
        data_str[1] <= 0;
        data_str[2] <= 0;
        data_str[3] <= 0;
        data_str[4] <= 0;
        data_str[5] <= 0;
        data_str[6] <= 0;
        data_str[7] <= 0;
    end
    else if(rx_done)begin
        data_str[0] <= rx_data;
        data_str[1] <= data_str[0];
        data_str[2] <= data_str[1];
        data_str[3] <= data_str[2];
        data_str[4] <= data_str[3];
        data_str[5] <= data_str[4];
        data_str[6] <= data_str[5];
        data_str[7] <= data_str[6];
    end
    else begin
        data_str[0] <= data_str[0];
        data_str[1] <= data_str[1];
        data_str[2] <= data_str[2];
        data_str[3] <= data_str[3];
        data_str[4] <= data_str[4];
        data_str[5] <= data_str[5];
        data_str[6] <= data_str[6];
        data_str[7] <= data_str[7];
    end
end
        
always@(posedge clk ,negedge rst)begin
    if(!rst)begin
        r_Time <= 32'd0;
        r_ctrl <= 8'd0;
    end
    else if((data_str[0] == 8'hf0) && (data_str[6]==8'h05) && (data_str[7]==8'h55))begin
        r_Time <= {data_str[5],data_str[4],data_str[3],data_str[2]};
        r_ctrl <= data_str[1];
    end
    else begin
        r_Time <= 32'd0;
        r_ctrl <= 8'd0;
    end
end
endmodule

 顶层模块调用

`timescale 1ns / 1ps

module uart_ctrl_led(
    clk     ,
    rst     ,
    uart_rx ,
    led
    );
input                clk    ;
input                rst    ;
input                uart_rx;
output               led    ;

wire[7:0]            data   ;
wire                 rx_done;
wire[31:0]           Time   ;
wire[7:0]            ctrl   ;

uart_rx_byte  uart_rx_byte_u0(
    .clk             ( clk    ),
    .rst             ( rst    ),
    .baud_set        ( 7      ),
    .uart_rx         ( uart_rx),
    .data            ( data   ),
    .rx_done         (rx_done )
    );

uart_cmd uart_cmd_u0(
    .clk             (  clk   ),
    .rst             (  rst   ),
    .rx_data         (  data  ),
    .rx_done         ( rx_done),
    .Time            (  Time  ),
    .ctrl            (  ctrl  )
);

led_ctrl_time led_ctrl_time_u0(
    .clk             ( clk  ),
    .rst             ( rst  ),
    .Ctrl            ( ctrl ),
    .Time            ( Time ),
    .led             ( led  )
);
endmodule

tb文件

`timescale 1ns / 1ps


module uart_ctrl_led_tb();
reg            clk      ;
reg            rst      ;
reg            uart_rx  ;
wire           led      ;


uart_ctrl_led uart_ctrl_led_1(
    .clk          ( clk     ),
    .rst          ( rst     ),
    .uart_rx      ( uart_rx ),
    .led          ( led     )
    );

initial clk = 0;
always #10 clk = ~clk;

initial begin
  rst = 0;
  #201;
  rst = 1;
  #200;
  uart_tx_byte(8'h55);
  #90000; //@(posedge rx_done);
  #5000;
  uart_tx_byte(8'h05);
  #90000;
  #5000;
  uart_tx_byte(8'h12);
  #90000;
  #5000;
  uart_tx_byte(8'h34);
  #90000;
  #5000;
  uart_tx_byte(8'h56);
  #90000;
  #5000;
  uart_tx_byte(8'h78);
  #90000;
  #5000;
  uart_tx_byte(8'h9a);
  #90000;
  #5000;
  uart_tx_byte(8'hf0);
  #90000;
  #5000;
  $stop;
end
task uart_tx_byte;
    input [7:0]tx_data;
    begin
        uart_rx = 1;
        #20;
        uart_rx = 0;
        #8680;
        uart_rx = tx_data[0];
        #8680;
        uart_rx = tx_data[1];
        #8680;
        uart_rx = tx_data[2];
        #8680;
        uart_rx = tx_data[3];
        #8680;
        uart_rx = tx_data[4];
        #8680;
        uart_rx = tx_data[5];
        #8680;
        uart_rx = tx_data[6];
        #8680;
        uart_rx = tx_data[7];
        #8680;
        uart_rx = 1;
        #8680;
    end
endtask
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闪烁的控制中,我们将计数器的清零条件由== 变为 >= ,这样就解决了这样的问题。!!!赞

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: FPGA(现场可编程门阵列)是一种可使用户定制硬件功能的集成电路芯片。UART(通用异步收发传输器)是一种在计算机和外部设备之间传输数据的串行通信协议。 串口控制LED流水是一种利用FPGA控制LED的方式。流水是一种 LED 条,其上的 LED 依次亮起或熄灭,给人一种流动的效果。 使用FPGA来实现UART串口控制LED流水,首先需要通过FPGA的引脚连接到UART串口模块。然后,根据串口通信协议,通过FPGA的逻辑电路将串口数据传输到LED流水控制部分。 在流水控制部分,通过设置FPGA的逻辑电路,可以实现LED闪烁、亮度调节、流动速度调节等功能。对于串口数据,FPGA可以解析其中的指令,根据指令控制LED的状态和效果。 例如,当收到特定的指令时,FPGA可以使得LED流水按照设定的亮度和速度流动。当收到其他指令时,FPGA可以使得LED流水停止流动或改变流动方向。 通过FPGA UART串口控制LED流水,可以实现灵活、可定制的LED条效果。用户可以通过发送不同的指令,改变LED的亮度、流动速度,与外设进行交互,实现更丰富的应用场景。这种方式充分利用了FPGA的可编程性和UART串口的通信能力,为LED控制提供了一种高效、可定制的解决方案。 ### 回答2: FPGA是一种可编程逻辑器件,可以根据设计人员的需求进行灵活的编程控制UART是一种通用异步收发传输接口,用于串行数据的传输。而LED流水是一种LED串联连接的电路,可以实现光的流水效果。 要使用FPGA控制LED流水,首先需要设计一个适当的电路。可以使用FPGA的数字逻辑单元和可编程的I/O引脚,将UART接口与LED串口控制连接起来。 在FPGA中,通过编程的方式,配置UART的工作模式和传输参数,例如波特率、数据位数、校验等。接收到来自外部设备的串行数据后,通过逻辑单元进行解析和处理,将数据转换为相应的控制信号。 在LED流水方面,可以通过FPGA的I/O引脚输出控制信号,控制LED流水的亮灭。根据UART接收到的控制数据,FPGA可以实现不同的流水模式,例如顺序流水、倒序流水、闪烁等。 通过编程控制UART接收数据和LED流水控制信号的传输和处理,就可以实现FPGAUART串口控制LED流水的功能。 总之,FPGA是一种具有灵活性的电路设备,可以通过编程对UART串口进行控制,实现LED流水控制效果。这种方法可以根据需求自定义串口传输和LED控制的参数和模式,具有很大的灵活性和可扩展性。 ### 回答3: FPGA是可重新配置的硬件,它可以实现各种数字电路设计的功能。UART是串行通信接口的一种标准,可用于在电路板之间进行数据传输。LED流水是一种LED效果,LED在不同的时间间隔内依次点亮。 要实现FPGA UART串口控制LED流水,需要进行以下步骤: 1. 首先,在FPGA上创建或导入所需的UART通信模块。该模块应支持常用的串口通信协议,如UART通信协议的发送和接收功能。 2. 在FPGA上创建或导入LED控制模块。该模块应支持控制LED的亮灭,以及按照一定的顺序和时间间隔点亮LED的功能。 3. 在FPGA上实现UARTLED控制模块之间的数据传输。通过UART通信模块,FPGA可以接收来自其他设备(如电脑或微控制器)发送的指令,以控制LED流水的效果。 4. 设计指令协议,以使来自UART指令能够正确地被LED控制模块识别和执行。指令可以设定光的点亮顺序、时间间隔以及其他特效。 5. 配置和连接FPGA的输入和输出引脚。UART模块应与外部设备(如电脑或其他微控制器)的串口通信引脚连接,而LED控制模块应与LED控制引脚连接。 最终,当FPGA通过UART接收到来自外部设备的指令时,LED控制模块会根据指令的要求,按照预设的顺序和时间间隔点亮LED。这样就实现了FPGA UART串口控制LED流水的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值