FPGA- 红外遥控(附代码)

2023-11-13

目录

1. 理论学习

2. 实操

2.1 整体说明

2.2 红外接收模块

2.2.1 模块框图

2.2.2 状态机

2.2.3 波形图绘制

2.2.4  RTL代码

2.3 LDE灯控制模块

2.3.1 模块框图

2.3.2 波形绘制

2.3.3 RTL代码

2.3.4 仿真代码

2.4 顶层模块

2.4.1 模块框图 

2.4.2 RTL代码

3.上板验证

4. 总结

1. 理论学习

 红外遥控简介:

      红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点, 被诸多电子设备特别是家用电器广泛采用。本文讲述如何使用FPGA技术实现红外信息的编码以及接收到红外信息后的解码方式。

    红外线遥控是利用近红外光传送遥控指令的,波长为 0.76um~1.5um。用近红外作为遥控光源,是因为目前红外发射器件(红外发光管)与红外接收器件(光敏二极管、三极管及光电池)的发光与受光峰值波长一般为 0.8um~0.94um, 在近红外光波段内,二者的光谱正好重合,能够很好地匹配,可以获得较高的传输效率及较高的可靠性。

 红外遥控系统组成:

     由上图可知系统分为三部分:发射部分、接收部分、FPGA解码部分。

 红外遥控的编码协议:   

        红外遥控的编码协议种类繁多,如: NEC、 Philips RC-5、 Philips RC-6、 Sony SIRC
等,而使用最多的是 NEC 协议。NEC 协议采用的是  PPM(Pulse Position Modulation,脉冲位置调制)进行编码。当我们按下遥控器的一个按键时,会发送一帧的数据。这一帧数据由引导码、地址码、地址反码、数据码、数据反码以及一位结束位(可忽略)组成。地址码、地址反码、数据码、数据反码都是8位二进制数使用逻辑“0”和逻辑“1”表示,低位在前高位在后,如下图所示。 

    下面介绍逻辑“0”和逻辑“1”以及一直按着按键不放的重复码的编码方式。

 逻辑“0”和逻辑“1”编码方式

       由上图可知:逻辑“1”和逻辑“0”是根据脉冲之间的时间间隔来区分的。 逻辑“1”由 560us 的高脉冲加上1.69ms 的低电平组成,而逻辑“0”由 560us 的高脉冲加上 560us 的低电平组成。


       长按时,先发送数据,然后每隔 110ms 会发送一个重复码,重复码由9ms 的高电平和2.25ms 的低电平以及 560us 的高电平(结束标志)组成。

      由于使用的是一体化接收头(HS0038B)接收到信号后输出到 FPGA 的波形刚好与发送的波形相反。发送高电平,接收后输出就为低电平;发送低电平,接收后输出就为高电平。 FPGA 芯片接收的波形如下图所示,以下的波形的持续时间是判断红外输入数据是否是按照 NEC 协议发送的关键。

    引导码接收波形图

 “1” /“0”数据接收波形图

 重复码接收波形图

综上,红外遥控按下时发送的数据的顺序是

2. 实操

       实验目标当按下红外遥控器时,对应按键的键值可以稳定显示在数码管上。另外如果一直按住按键,则小灯闪烁一次。

2.1 整体说明

 红外遥控系统框图

       本实验工程包括 4 个模块,其中 seg_dynamic 模块可直接调用,之前写过。

     红外遥控实验的工作流程:一体化接收头接收到红外遥控发来的红外信息后,将红外信息传入 FPGA 芯片内使用红外接收模块( infrared_rcv)进行解码,若接收的信息与协议一致,则让接收到的数据传入数码管显示模块显示数据,若接收到重复码,则让重复码使能信号传入 led 控制模块让 led 闪烁。

2.2 红外接收模块

2.2.1 模块框图

       红外接收模块功能:判断红外输入数据是否是按照 NEC 协议发送的,如果是按照协议进行发送的,则输出发送的数据码和重复码使能信号。NEC 协议就是前面讲的数据由引导码、地址码、地址反码、数据码、数据反码以及一位结束位(可忽略)组成的,其数据之间间隔时间是不同的。

2.2.2 状态机

       由于数据组成较为复杂,使用状态机来标记其各个过程。

2.2.3 波形图绘制

2.2.4  RTL代码

`timescale  1ns/1ns

module  infrared_rcv
(
    input   wire        sys_clk     ,  
    input   wire        sys_rst_n   ,  
    input   wire        infrared_in ,   //红外接受信号

    output  reg         repeat_en   ,   //重复码使能信号
    output  reg [19:0]  data            //接收的控制码
);

parameter   CNT_0_56MS_L  =   20000 ,  
            CNT_0_56MS_H  =   35000 ,
            CNT_1_69MS_L  =   80000 ,  
            CNT_1_69MS_H  =   90000 ,
            CNT_2_25MS_L  =   100000,  
            CNT_2_25MS_H  =   125000,
            CNT_4_5MS_L   =   175000,  
            CNT_4_5MS_H   =   275000,
            CNT_9MS_L     =   400000,  
            CNT_9MS_H     =   490000;
//state
parameter   IDLE        =   5'b0_0001,  //空闲状态
            S_T9        =   5'b0_0010,  //监测同步码低电平
            S_JUDGE     =   5'b0_0100,  //判断重复码和同步码高电平
            S_IFR_DATA  =   5'b0_1000,  //接收数据
            S_REPEAT    =   5'b1_0000;  //重复码


wire            ifr_in_rise ; 
wire            ifr_in_fall ; 

reg         infrared_in_d1  ; 
reg         infrared_in_d2  ; 
reg [18:0]  cnt             ; 
reg         flag_0_56ms     ; 
reg         flag_1_69ms     ; 
reg         flag_2_25ms     ; 
reg         flag_4_5ms      ; 
reg         flag_9ms        ; 
reg [4:0]   state           ; 
reg [5:0]   data_cnt        ; 
reg [31:0]  data_tmp        ; 

//检测红外信号的上升沿和下降沿
assign  ifr_in_rise = (~infrared_in_d2) & (infrared_in_d1) ;
assign  ifr_in_fall = (infrared_in_d2) & (~infrared_in_d1) ;

//对infrared_in信号打拍
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            infrared_in_d1  <=  1'b0;
            infrared_in_d2  <=  1'b0;
        end
    else
        begin
            infrared_in_d1  <=  infrared_in;
            infrared_in_d2  <=  infrared_in_d1;
        end

//cnt
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <=  19'd0;
    else
        case(state)
            IDLE:   cnt <=  19'd0;
            S_T9:   if((ifr_in_rise==1'b1) && (flag_9ms==1'b1))
                        cnt <=  19'd0;
                    else
                        cnt <=  cnt + 1;
            S_JUDGE:if((ifr_in_fall==1'b1) && (flag_2_25ms==1'b1 || flag_4_5ms==1'b1))
                        cnt <=  19'd0;
                    else
                        cnt <=  cnt + 1;
            S_IFR_DATA: if((flag_0_56ms == 1'b1) && (ifr_in_rise==1'b1))
                            cnt <=  19'd0;
                        else    if(((flag_0_56ms==1'b1) || (flag_1_69ms==1'b1)) && (ifr_in_fall==1'b1))
                            cnt <=  19'd0;
                        else
                            cnt <=  cnt + 1;
            default:cnt <=  19'd0;
        endcase

//flag_0_56ms:计数到0.56ms范围拉高标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_0_56ms <=  1'b0;
    else    if((state == S_IFR_DATA) && (cnt >= CNT_0_56MS_L) && (cnt <= CNT_0_56MS_H))
        flag_0_56ms <=  1'b1;
    else
        flag_0_56ms <=  1'b0;

//flag_1_69ms:计数到1.69ms范围拉高标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_1_69ms <=  1'b0;
    else    if((state == S_IFR_DATA) && (cnt >= CNT_1_69MS_L) && (cnt <= CNT_1_69MS_H))
        flag_1_69ms <=  1'b1;
    else
        flag_1_69ms <=  1'b0;

//flag_2_25ms:计数到2.25ms范围拉高标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_2_25ms <=  1'b0;
    else    if((state == S_JUDGE) && (cnt >= CNT_2_25MS_L) && (cnt <= CNT_2_25MS_H))
        flag_2_25ms <=  1'b1;
    else
        flag_2_25ms <=  1'b0;

//flag_4_5ms:计数到4.5ms范围拉高标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_4_5ms <=  1'b0;
    else    if((state == S_JUDGE) && (cnt >= CNT_4_5MS_L) && (cnt <= CNT_4_5MS_H))
        flag_4_5ms <=  1'b1;
    else
        flag_4_5ms <=  1'b0;

//flag_9ms:计数到9ms范围拉高标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_9ms <=  1'b0;
    else    if((state == S_T9) && (cnt >= CNT_9MS_L) && (cnt <= CNT_9MS_H))
        flag_9ms <=  1'b1;
    else
        flag_9ms <=  1'b0;

//状态机:状态跳转
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        state   <=  IDLE;
    else
        case(state)
    //若检测到红外信号下降沿到来跳转到S_T9状态
        IDLE:
            if(ifr_in_fall == 1'b1)
                state   <=  S_T9;
            else    //若没检测到红外信号的下降沿,则让其保持在IDLE状态
                state   <=  IDLE;
        S_T9:   //若检测到红外信号上升沿到来,则判断flag_9ms是否为1
                //若检测到时间接近9ms,则跳转到S_judje状态
            if((ifr_in_rise == 1'b1) && (flag_9ms ==  1'b1))
                state   <=  S_JUDGE;
            else    if((ifr_in_rise == 1'b1) && (flag_9ms ==  1'b0))
                state   <=  IDLE;
            else
                state   <=  S_T9;
        S_JUDGE:  //若检测到红外信号下降沿到来,则判断flag_2_25ms是否为1
                  //若检测到时间接近2.25ms,则跳转重复码状态
            if((ifr_in_fall == 1'b1) && (flag_2_25ms == 1'b1))
                state   <=  S_REPEAT;
            else    if((ifr_in_fall == 1'b1) && (flag_4_5ms == 1'b1))
                state   <=  S_IFR_DATA;
            else    if((ifr_in_fall == 1'b1) && (flag_2_25ms == 1'b0) && (flag_4_5ms == 1'b0))
                state   <=  IDLE;
            else
                state   <=  S_JUDGE;
        S_IFR_DATA:
            //若上升沿到来,低电平保持时间不满足编码协议,则回到空闲状态
            if(ifr_in_rise == 1'b1 && flag_0_56ms == 1'b0)
                state   <=  IDLE;
            //若下降沿到来,高电平保持时间不满足编码0或1,则回到空闲状态
            else    if(ifr_in_fall == 1'b1 && (flag_0_56ms == 1'b0 &&
                                                    flag_1_69ms == 1'b0))
                state   <=  IDLE;
            //数据接收完毕之后回到空闲状态,等待下一个指令的到来
            else    if(ifr_in_rise == 1'b1 && data_cnt == 6'd32)
                state   <=  IDLE;
        S_REPEAT:
            /*若上升沿到来,无论时间是否到了0.56ms,
            状态机都跳回IDLE状态等待下一数据码或重复码的到来*/
            if(ifr_in_rise == 1'b1)
                state   <=  IDLE;
            else
                state   <=  S_REPEAT;
        default:
                state   <=  IDLE;
        endcase

//data_tmp
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_tmp    <=  32'b0;
    else    if(state == S_IFR_DATA && ifr_in_fall == 1'b1 &&
                                                    flag_0_56ms  == 1'b1)
        data_tmp[data_cnt]  <=  1'b0;
    else    if(state == S_IFR_DATA && ifr_in_fall == 1'b1 &&
                                                    flag_1_69ms  == 1'b1)
        data_tmp[data_cnt]  <=  1'b1;
    else
        data_tmp    <=  data_tmp;

//data_cnt
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_cnt    <=  1'b0;
    else    if(ifr_in_rise == 1'b1 && data_cnt == 6'd32)
        data_cnt    <=  1'b0;
    else    if(ifr_in_fall == 1'b1 && state == S_IFR_DATA)
        data_cnt    <=  data_cnt + 1'b1;
    else
        data_cnt    <=  data_cnt;

//repeat_en
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        repeat_en  <=  1'b0;
    else    if(state == S_REPEAT && (data_tmp[23:16] == 
                                        ~data_tmp[31:24]))
        repeat_en  <=  1'b1;
    else
        repeat_en  <=  1'b0;

always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data    <=  20'b0;
    //数据接收完之后若数据校验正确,则输出数据码的数据
    else    if(data_tmp[23:16] == ~data_tmp[31:24] && data_tmp[7:0] ==
                                    ~data_tmp [15:8] && data_cnt==6'd32)
        data   <=  {12'b0,data_tmp[23:16]};

endmodule

2.3 LDE灯控制模块

2.3.1 模块框图

 

       模块功能:使用红外接收模块产生的重复码使能信号去对 led 进行0.5ms点亮。

2.3.2 波形绘制

       为什么不直接在repent_en高电平时同时拉高LED信号?因为repent_en高电平时间只有560us,低电平时间有11ms左右效果是不明显的。

2.3.3 RTL代码

`timescale  1ns/1ns

module  led_ctrl
(
    input   wire    sys_clk     ,   
    input   wire    sys_rst_n   ,   
    input   wire    repeat_en   ,   //重复码使能信号
    
    output  reg     led             //输出led灯信号
);

parameter   CNT_MAX =   2500_000;

//wire  define
wire    repeat_en_rise  ;   //重复码使能信号上升沿

//reg   define
reg         repeat_en_d1;   //重复码使能信号打一拍
reg         repeat_en_d2;   //重复码使能信号打两拍
reg         cnt_en      ;   //计数器使能信号
reg [21:0]  cnt         ;   //计数器

//获得repeat_en上升沿信号
assign  repeat_en_rise  =   repeat_en_d1 &  ~repeat_en_d2;

//对reeat_en打两拍
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            repeat_en_d1    <=  1'b0;
            repeat_en_d2    <=  1'b0;
        end
    else
        begin
            repeat_en_d1    <=  repeat_en;
            repeat_en_d2    <=  repeat_en_d1;
        end

//当重复码使能信号上升沿来到,拉高计数器使能信号,计到50ms后拉低
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
            cnt_en <=  1'b0;
    else    if(cnt == CNT_MAX - 1)
            cnt_en <=  1'b0;
    else    if(repeat_en_rise == 1'b1)
            cnt_en <=  1'b1;
            
//当计数器使能信号为高时让计数器开始计数,为低时计数器清零
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
            cnt <=  22'b0;
    else    if(cnt_en == 1'b1)
            cnt <=  cnt + 1;
    else
            cnt <=  22'b0;

//当计数器大于0时,点亮led灯,也就是当使能信号到来,led灯会亮50ms
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        led <=  1'b1;
    else    if(cnt > 0)
        led <=  1'b0;
    else
        led <=  1'b1;

endmodule

2.3.4 仿真代码

`timescale  1ns/1ns

module  tb_top_infrared_rcv();

wire            led    ;
wire    [5:0]   sel    ;
wire    [7:0]   seg    ;

reg     sys_clk     ;
reg     sys_rst_n   ;
reg     infrared_in ;

initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
        infrared_in <=  1'b1;
        #100
        sys_rst_n   <=  1'b1;
//引导码
        #1000
        infrared_in <=  1'b0; #9000000
        infrared_in <=  1'b1; #4500000
//地址码(发送地址码8’h99)
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//地址反码(地址反码为8’h66)
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据码(发送数据码8’h22)
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据反码(数据反码为8’hdd)
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据0
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #560000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//数据1
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #1690000
//重复码
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1; #42000000
        infrared_in <=  1'b0; #9000000
        infrared_in <=  1'b1; #2250000
        infrared_in <=  1'b0; #560000
        infrared_in <=  1'b1;
    end

//clk:产生时钟
always  #10 sys_clk <=  ~sys_clk;


top_infrared_rcv    top_infrared_rcv_inst
(
    .sys_clk     (sys_clk    ),   
    .sys_rst_n   (sys_rst_n  ),   
    .infrared_in (infrared_in),   
    
    .sel         (sel        ),   
    .seg         (seg        ),   
    .led         (led        )    

);

endmodule

2.4 顶层模块

2.4.1 模块框图 

2.4.2 RTL代码

`timescale  1ns/1ns

module  top_infrared_rcv
(
    input   wire            sys_clk     ,   
    input   wire            sys_rst_n   ,   
    input   wire            infrared_in ,   //红外接收信号

    output  wire    [5:0]   sel ,   
    output  wire    [7:0]   seg ,   
    output  wire            led     
);

wire            repeat_en   ;   //重复码使能信号
wire    [19:0]  data        ;   //接收的控制码

infrared_rcv    infrared_rcv_inst
(
    .sys_clk     (sys_clk    ),   
    .sys_rst_n   (sys_rst_n  ),   
    .infrared_in (infrared_in),   

    .repeat_en   (repeat_en  ),   
    .data        (data       )    
);

led_ctrl    led_ctrl_inst
(
    .sys_clk     (sys_clk  ) ,   
    .sys_rst_n   (sys_rst_n) ,   
    .repeat_en   (repeat_en) ,   

    .led         (led      )
);


seg_dynamic seg_dynamic_inst
(
    .sys_clk     (sys_clk  ), 
    .sys_rst_n   (sys_rst_n), 
    .data        (data     ), 
    .point       (6'd0     ), 
    .seg_en      (1'b1     ), 
    .sign        (1'b0     ), 

    .sel         (sel      ), 
    .seg         (seg      )  

);

endmodule

3.上板验证

4. 总结

 *1. 实验核心部分在于红外接收模块,要理解何时进行状态跳转以及判断其跳转的条件。

*2. 代码编写上有些新的知识点,注意学习。

说明:

本人使用的是野火家Xilinx Spartan6系列开发板及配套教程,以下内容如有疑惑或错误欢迎评论区指出。

开发软件:ise14.7     仿真:modelsim 10.5 

如需上述资料私信或留下邮箱!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FPGA- 红外遥控(附代码) 的相关文章

  • FPGA设计篇之流水线思想

    FPGA设计篇之流水线思想 一 写在前面 二 正文开始 2 1举个栗子 2 2 1情况一 组合逻辑 2 1 2情况二 流水线设计 2 1 4 小总结 2 2举第二个栗子 写在最后 一 写在前面 流水线 大家好 我是富土康三号流水线的张全蛋
  • 8x8LED点阵

    点量这个只需要把9高电平 13低电平就可以了 共阳极点阵 行线是led的正极 列线是led的列线 左上角点亮 显示多个灯是动态扫描的 一个一个显示的 然后间隔速度要快就可以造成显示 点阵由两篇74Hc595级联在一起驱动的 只需要三个io口
  • 基于单光子探测的多脉冲周期符合远距离测距

    激光测距技术通过发射主动激光信号对目标进行探测 接收由目标漫反射回来的回波信号并进行统计 处理及换算 从而得到目标的距离 速度信息 实现对目标距离信息的探测 凭借其系统简单 操作灵活 高精度等特点 被广泛运用于民用 科研及军事等各类场合 基
  • HDLBits — Verilog Practice(每日一题)

    HDLBits Verilog Practice 每日一题 一 Getting Started 1 Getting Started 一 Getting Started 1 Getting Started 问题描述 Build a circu
  • 手把手教你Modelsim仿真【2020.4版本】

    首先新建一个文件夹 test5 打开Modelsim 依次选择 File gt Change Directory 把目录选择到创建的 test5 文件夹 创建库 依次选择 File gt New gt Library 一般我们选择第三个 库
  • FPGA的基本设计流程

    FPGA开发主要包括系统设计 设计输入 功能仿真 综合优化 综合后仿真 实现与布局布线 时序方针与验证 板级方针与验证 芯片编程与调试等9个部分 如下图所示 1 电路设计 在系统设计之前 首先要进行的是方案论证 系统设计和FPGA芯片选择等
  • 上拉电阻和下拉电阻

    一 定义 上拉电阻 将一个不确定的信号 通过一个电阻与电源VCC相连 固定在高电平 下拉电阻 将一个不确定的信号 通过一个电阻与地GND相连 固定在低电平 二 作用 提高输出信号驱动能力 确定输入信号电平 防干扰 限流 阻抗匹配 抗回波干扰
  • 握手2倍速率进,一倍速率出[verilog]

    module two to one parameter WORD LEN 33 input clk input arst input 2 WORD LEN 1 0 i din input i din valid output o din r
  • 八、RISC-V SoC外设——GPIO接口 代码讲解

    前几篇博文中注释了RISC V的内核CPU部分 从这篇开始来介绍RISC V SoC的外设部分 另外 在最后一个章节中会上传额外添加详细注释的工程代码 完全开源 如有需要可自行下载 目录 0 RISC V SoC注解系列文章目录 1 结构
  • 吃透Chisel语言.18.Chisel模块详解(五)——Chisel中使用Verilog模块

    Chisel模块详解 五 Chisel中使用Verilog模块 上一篇文章讲述了用函数实现轻量级模块的方法 可以大幅度提升编码效率 Chisel中也提供了一些好用的函数 方便我们编写代码 也方便Chisel编译器优化生成的硬件电路 在Chi
  • xilinx xdma PCIe中断bug

    xilinx xdma PCIe中断存在bug bug1 此中断虽然是msi或者msx中断 但是不中断cpu bug2 此中断不是边沿中断 而是电平中断 在驱动层需要不断地轮训查询中断事件 bug3 此中断持续时间必须长 而且在收到中断应答
  • 【Xilinx Vivado时序分析/约束系列4】FPGA开发时序分析/约束-实验工程上手实操

    目录 建立工程 添加顶层 模块1 模块2 添加约束文件 编辑时钟约束 打开布线设计 代码代表的含义 时序报告 进行时序分析 Summary 包含了汇总的信息量 Source Clock Path 这部分是表示Tclk1的延时细节 Data
  • [从零开始学习FPGA编程-28]:进阶篇 - 基本组合电路-奇偶校验生成器(Verilog语言版本)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 奇偶校验生成器 1 1 什么是奇校验 1 2 Verilog语言描述
  • 蓝桥杯真题:迷宫

    目录 题目描述 运行限制 dfs bfs 结果 题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 下图给出了一个迷宫的平面图 其中标记为 11 的为障碍 标记为 00 的为可以通行的地方 010000 000
  • ALLEGRO等长时如何将PIN DELAY和VIA长度计算在内

    在PCB设计中 对于时序要求严格的线路 Via和IC pin delay的长度必须得到重视 通过下面的操作 可将Via和Pin delay加入到线路长度的计算中 1st 计算Pin delay 打开Constraint Manager 选择
  • 【电子技术】什么是LFSR?

    目录 0 前言 1 数学基础 1 1 逻辑异或 1 2 模2乘法 和 模2除法 2 线性反馈移位寄存器LFSR 3 抽头和特征多项式 4 阶线性反馈移位寄存器实例 0 前言 线性反馈移位寄存器 Linear Feedback Shift R
  • [从零开始学习FPGA编程-24]:进阶篇 - 基本组合电路-编码器与译码器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 125247358 目录 前言 Veri
  • 硬核 | 从零制作一个激光雷达需要多久?

    编辑 ADS智库 点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 硬件交流 技术交流群 本文只做学术分享 如有侵权 联系删文 激光雷达 LiDAR 是激光探测及测距系统的简称 目前广泛应用在无
  • 串口通信知识点总结

    串口是串行接口 serial port 的简称 也称为串行通信接口或COM接口 串口通信是指采用串行通信协议 serial communication 在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式 串口按电气标准及协议来划分
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于

随机推荐

  • 在ros2下使用ros1_bridge与ros1自定义消息桥接

    在ros2下使用ros1 bridge与ros1自定义消息桥接 示例环境 操作系统 ubuntu 20 04 amd64 ros版本 noetic ros2版本 foxy ros1示例代码 创建ros1的工作空间catkin ws 功能包c
  • AXI4-Stream协议总结

    AXI4 Stream去掉了地址项 允许无限制的数据突发传输规模 一 接口信号描述 信号 源 描述 ACLK 时钟源 全局时钟信号 所有信号在ACLK信号上升沿采样 ARESETn 复位源 全局复位信号 ARESETn低电平有效 TVALI
  • JDBC规范——(8)异常

    当访问一个数据源时发生错误或者警告 JDBC 用 SQLException 这个类及其子类来表示并提供相关的异常信息 8 1 SQLException SQLException 由一下几部分组成 1 描述错误的文本信息 可以通过 SQLEx
  • Aspose功能演示:使用Java以编程方式在 Excel 文件中添加或修改 VBA 宏

    VBA是一种编程语言 用于在 MS Excel 文件中自动执行各种操作 特别是 VBA 宏是用户定义的代码 可加速电子表格操作任务 在本文中 将学习如何以编程方式使用 Excel 文件中的 VBA 宏 最终 将能够 使用 Java 在 Ex
  • 树莓派配置热点(即设置wifi)

    https www raspberrypi org documentation configuration wireless access point routed md 如果官网打不开 看次链接 https qinfeng blog cs
  • rollup常用插件盘点

    1 rollup plugin commonjs 将 CommonJS 模块转换为 ES2015 供 Rollup 处理 rollup plugin commonjs是一个用于将CommonJS模块转换为ES6模块的Rollup插件 它的主
  • Vue组件化学习之scoped

    简介 主要介绍scoped的作用 先弄一个案例 main js 引入vue依赖 import Vue from vue 引入组件App import App from App vue 关闭生产提示 Vue config production
  • pip install -r requirements.txt出现错误解决办法

    pip install r requirements txt安装出现以下错误解决办法如下 PS D YOLO yolov5 master gt pip install r requirements txt Collecting matplo
  • 配置IIS之虚拟目录

    什么是IIS虚拟目录 有什么优点 虚拟目录指在站点下建立一个虚拟子目录 指定一个固定的物理路径做为站点的应用路径 1 虚拟目录与父级站点共用一个应用程序池 例如 站点TestWeb c Inetpub wwwroot TestWeb 下建立
  • 安利一个实用项目--物美智能

    安利一个实用项目 可用于二次开发 官网 项目介绍 项目地址 演示地址
  • Windows 下 Redis 安装与配置 教程

    文章目录 一 Windows 下安装 Redis 的几种方式 1 微软官方维护的 Redis 2 tporadowski 维护的 Redis 3 使用 WSL 安装 Redis 4 使用gcc编译器在Windows下编译redis源码 二
  • USB转串口驱动代码分析

    1 USB插入时 创建设备 DriverObject gt DriverExtension gt AddDevice USB2COM PnPAddDevice 步一 调用USB2COM CreateDeviceObject创建功能设备对象
  • C语言中的printf与scanf函数

    1 printf函数的格式字符串 md 左对齐 若m比实际少时 按实际输出 不足右补空格 include
  • ubuntu16.04 UFactory xArm6 xarm_ros环境安装

    UFactory xArm6 的xarm ros开发 背景 环境部署 相机D435i标定 手眼标定 find object 2d or find object 3d 遇到的问题 背景 最近要对机械臂进行开发控制 部分需求是 机器人导航 摄像
  • 闪回技术概念+闪回技术的形式

    闪回技术概念 闪回技术概念 可以实现数据的迅速恢复 而且不依赖于数据备份的技术 闪回技术的形式 1闪回表 Flashback Table 将表回滚到一个过去的时间点或系统改变号scn上 用来快速恢复表 2闪回删除 Flashback Dro
  • Python 判断质数

    使用for循环和列表list判断数字是否为质数 for i in range 2 10 list for j in range 1 i 1 if i j 0 list append i if len list gt 2 print i 不是
  • Unity 资源商店无法登陆,提示链接失效 的解决办法

    出现资源商店无法登陆问题 网络换一下 用自己的手机热点连网 就可以了
  • js——undefined和undeclared

    先看例子 var a a undefined b b is not defined 这样的报错会让我们认为b也是undefined 更让人抓狂的是 var a typeof a undefined typeof b undefined 虽然
  • 分立元器件——电感器

    基本概念 1 1什么是电感器 电感器是能够把电能转为为磁能存储起来的元件 电感器具有电感 能够阻碍电流的变化 具有维持原状态的能力 即当电流突然通过时 它将阻碍电流流过一段时间 当电流突然断开后 它将维持电流一段时间 电感是描述电感器对抗电
  • FPGA- 红外遥控(附代码)

    目录 1 理论学习 2 实操 2 1 整体说明 2 2 红外接收模块 2 2 1 模块框图 2 2 2 状态机 2 2 3 波形图绘制 2 2 4 RTL代码 2 3 LDE灯控制模块 2 3 1 模块框图 2 3 2 波形绘制 2 3 3