FPGA(8)红外接收(NEC协议)

该模块实现了一个基于时序的协议波形解析器,通过状态机和计数器检测特定时间间隔,如9ms、4.5ms、2.25ms等,用于识别协议信号。在检测到特定时序后,将输入数据转化为8位输出,并通过标志位`repeat_en`指示重复模式。此外,模块还能够从输入数据中提取并存储32位数据块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

协议波形

 

 

 

代码

 

module  hongwai(sys_clk,sys_rst,data1_in,data8_out,repeat_en);
//输入信号
    input   wire    sys_clk,sys_rst;
    input   wire    data1_in;
//输出信号
    output  reg    [7:0]   data8_out;
    output  reg      repeat_en;

//状态机(以及转换条件)
reg     [4:0]   state;
reg             data1_pai1;
reg             data1_pai2;
wire            fall_flag;
wire            rise_flag;

parameter   idle        =5'b00001;
parameter   time_9ms    =5'b00010;
parameter   zhongcai    =5'b00100;
parameter   repeat_my   =5'b01000;
parameter   data_state  =5'b10000;

reg             flag_9ms;
reg             flag_2_25ms;
reg             flag_560us;
reg             flag_4_5ms;
reg             flag_1690us;
reg     [5:0]   cntBit32_data;

//计数(用于计时)
reg     [20:0]     cnt_Time;

parameter       cnt_MAX_9ms     =21'd499_999;//9ms+1ms
parameter       cnt_MIN_9ms     =21'd349_999;//9ms-2ms
parameter       cnt_MAX_4_5ms   =21'd275_000;//4.5ms+1ms
parameter       cnt_MIN_4_5ms   =21'd175_000;//4.5ms-1ms
parameter       cnt_MAX_2_25ms  =21'd162_500;//2.25+1ms
parameter       cnt_MIN_2_25ms  =21'd62_500;//2.25-1ms
parameter       cnt_MAX_560us   =21'd38_000;//560us+100us
parameter       cnt_MIN_560us   =21'd18_000;//560us-100us
parameter       cnt_MAX_1690us  =21'd134_500;//1690us+1000us
parameter       cnt_MIN_1690us  =21'd34_500;//1690-1000us


reg     [31:0]      data32_in1;
reg     [7:0]       data8_temp;



//打拍
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        begin
            data1_pai1<=1'b0;
            data1_pai2<=data1_pai1;
        end
    else
        begin
            data1_pai1<=data1_in;
            data1_pai2<=data1_pai1;
        end
end

//产生上升沿和下降沿标志
assign  fall_flag=(data1_pai1==1'b0)&&(data1_pai2==1'b1);
assign  rise_flag=(data1_pai1==1'b1)&&(data1_pai2==1'b0);

//状态机的转换总体架构
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        state<=idle;
    else    case(state)
        idle:
            if(fall_flag==1'b1)
                state<=time_9ms;
            else
                state<=state;
        time_9ms:
            if((flag_9ms==1'b1)&&(rise_flag==1'b1))
                state<=zhongcai;
            else    if((flag_9ms==1'b0)&&(rise_flag==1'b1))
                state<=idle;
            else
                state<=state;
        zhongcai:
            if((fall_flag==1'b1)&&(flag_2_25ms==1'b1))
                state<=repeat_my;
            else    if((fall_flag==1'b1)&&(flag_4_5ms==1'b1))
                state<=data_state;
            else    if((fall_flag==1'b1)&&((flag_2_25ms==1'b0)||(flag_4_5ms==1'b0)))
                state<=idle;
            else
                state<=state;
        repeat_my:
            if((rise_flag==1'b1)&&(flag_560us==1'b1))
                state<=idle;
            else    if((rise_flag==1'b1)&&(flag_560us==1'b0))
                state<=idle;
            else
                state<=state;
        data_state:
            if((rise_flag==1'b1)&&(flag_560us==1'b0))
                state<=idle;
            else    if((fall_flag==1'b1)&&(flag_1690us==1'b0)&&(flag_560us==1'b0))
                state<=idle;
            else    if((cntBit32_data==6'd32)&&(rise_flag==1'b1))
                state<=idle;
            else
                state<=state;
        default:    state<=idle;
        endcase
end

//计数延时的建立
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        cnt_Time<=21'd0;
    else    case(state)
        idle:
            cnt_Time<=21'd0;
        time_9ms:
            if((rise_flag==1'b1)||(fall_flag==1'b1))
                cnt_Time<=21'd0;
            else
                cnt_Time<=cnt_Time+1'b1;
        zhongcai:
            if((rise_flag==1'b1)||(fall_flag==1'b1))
                cnt_Time<=21'd0;
            else
                cnt_Time<=cnt_Time+1'b1;
        repeat_my:
            if((rise_flag==1'b1)||(fall_flag==1'b1))
                cnt_Time<=21'd0;
            else
                cnt_Time<=cnt_Time+1'b1;
        data_state:
            if((rise_flag==1'b1)||(fall_flag==1'b1))
                cnt_Time<=21'd0;
            else
                cnt_Time<=cnt_Time+1'b1;
        default:    cnt_Time<=21'd0;
    endcase
end

//9ms
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_9ms<=1'b0;
    else    if((cnt_Time<=cnt_MAX_9ms)&&(cnt_Time>=cnt_MIN_9ms))
        flag_9ms<=1'b1;
    else
        flag_9ms<=1'b0;
end
//4.5ms
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_4_5ms<=1'b0;
    else    if((cnt_Time<=cnt_MAX_4_5ms)&&(cnt_Time>=cnt_MIN_4_5ms))
        flag_4_5ms<=1'b1;
    else
        flag_4_5ms<=1'b0;
end
//2.25ms
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_2_25ms<=1'b0;
    else    if((cnt_Time<=cnt_MAX_2_25ms)&&(cnt_Time>=cnt_MIN_2_25ms))
        flag_2_25ms<=1'b1;
    else
        flag_2_25ms<=1'b0;
end
//1690us
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_1690us<=1'b0;
    else    if((cnt_Time<=cnt_MAX_1690us)&&(cnt_Time>=cnt_MIN_1690us))
        flag_1690us<=1'b1;
    else
        flag_1690us<=1'b0;
end
//560us
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_560us<=1'b0;
    else    if((cnt_Time<=cnt_MAX_560us)&&(cnt_Time>=cnt_MIN_560us))
        flag_560us<=1'b1;
    else
        flag_560us<=1'b0;
end

//cntBit32_data
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        cntBit32_data<=6'd0;
    else    if((cntBit32_data==6'd32)&&(rise_flag==1'b1))
        cntBit32_data<=6'd0;
    else    if((state==data_state)&&(fall_flag==1'b1)&&((flag_1690us==1'b1)||(flag_560us==1'b1)))
        cntBit32_data<=cntBit32_data+1'b1;
    else    
        cntBit32_data<=cntBit32_data;
end

//repeat_en------------
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        repeat_en<=1'b0;
    else    if((state==repeat_my)&&(rise_flag==1'b1)&&(flag_560us==1'b1))
        repeat_en<=1'b1;
    else
        repeat_en<=1'b0;

end

//数据赋值(原始数据)

always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        data32_in1<=32'd0;
    else    if((state==data_state)&&(fall_flag==1'b1)&&(flag_1690us==1'b1))
        data32_in1[cntBit32_data]<=1'b1;
    else    if((state==data_state)&&(fall_flag==1'b1)&&(flag_560us==1'b1))
        data32_in1[cntBit32_data]<=1'b0;
    else
        data32_in1<=data32_in1;
end


//data8_temp
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        data8_temp<=8'd0;
    else    if((cntBit32_data==6'd32)&&(data32_in1[7:0]==~data32_in1[15:8])&&(data32_in1[31:24]==~data32_in1[23:16]))
        data8_temp<=data32_in1[23:16];
    else
        data8_temp<=data8_temp;
end

//data8_out
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        data8_out<=8'd0;
    else
        data8_out<=data8_temp;
end

    
endmodule





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦灵-影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值