红外解码编码学习----verilog

在设计中运用红外遥控器可以很好的解决按键缺少的问题,还可以方便的控制产品。

红外发射部分:

红外发射管:

判断红外发射管的好坏

电路原理图:

接收部分:

传输的NEC协议:

本实验电路:

verilog 程序:

发送程序:


    /********************************Copyright**************************************
    **----------------------------File information--------------------------
    ** File name  :IR_send.v
    ** CreateDate :2015.06
    ** Funtions   :红外信号的发送程序,发送格式:引导码+8bit用户码+8bit用户反码(或者用户反码)+8bit数据码+8bit用户反码+结束码
    ** Operate on :M5C06N3L114C7
    ** Copyright  :All rights reserved.
    ** Version    :V1.0
    **---------------------------Modify the file information----------------
    ** Modified by   :
    ** Modified data :
    ** Modify Content:
    *******************************************************************************/

    module  IR_send  (
               clk,
               rst_n,

                         key_1,
                         key_2,

                         IR_out,
                         led_1,
                         led_2,
                         led_3,
                         led_4

//                          testdata
                 );
     input          clk;    //24M/20m
     input          rst_n;

     input          key_1;
     input          key_2;

     output         IR_out;

     output  reg    led_1;
     output  reg    led_2;
   output       led_3;
     output       led_4;

//     output  [7;0]  testdata;
     //-------------------//

    `define     CLK_20M
//    `define     CLK_24M
//    `define     CLK_50M

 `ifdef      CLK_20M
             parameter t_38k    = 10‘d526;
             parameter t_38k_half = 10‘d263;
             parameter t_9ms    = 18‘d179999;
             parameter t_4_5ms  = 17‘d89999;
             parameter t_13_5ms = 19‘d269999;
             parameter t_560us  = 14‘d11199;
             parameter t_1_12ms = 15‘d22399;
             parameter t_1_68ms = 16‘d33599;
             parameter t_2_24ms = 16‘d44799;
      `endif

     `ifdef      CLK_24M
             parameter t_38k    = 10‘d630;
             parameter t_38k_half = 10‘d315;
             parameter t_9ms    = 18‘d215999;
             parameter t_4_5ms  = 17‘d107999;
             parameter t_13_5ms = 19‘d323999;
             parameter t_560us  = 14‘d13439;
             parameter t_1_12ms = 15‘d26879;
             parameter t_1_68ms = 16‘d40319;
             parameter t_2_24ms = 16‘d53759;
      `endif

     `ifdef      CLK_50M
             parameter t_38k    = 11‘d1315;
             parameter t_38k_half = 10‘d657;
             parameter t_9ms    = 19‘d449999;
             parameter t_4_5ms  = 18‘d224999;
             parameter t_13_5ms = 20‘d674999;
             parameter t_560us  = 15‘d27999;
             parameter t_1_12ms = 16‘d55999;
             parameter t_1_68ms = 17‘d83999;
             parameter t_2_24ms = 17‘d111999;
      `endif    

     parameter DATA_USER = 8‘h00;

     //---------------------------------//
      //分频38Khz时钟
      reg  [10:0]   cnt1;
        wire         clk_38k;
        always @(posedge clk or negedge rst_n)
         begin
          if(!rst_n)
           begin
               cnt1 <= 0;
            end
          else if(cnt1 == t_38k)
            begin
               cnt1 <= 0;
            end
            else cnt1 <= cnt1 + 1;
         end
  assign  clk_38k = (cnt1<t_38k_half)?1:0;
 //-------------------------------------------//

//    wire         key_1_flg;
//        wire         key_2_flg;
//      key_shake   U1(
//            .clk_100M(clk),
//            .rst_n(rst_n),
//
//            .key_in(key_1),
//            .key_out(key_1_flg)
//             );
//
//        key_shake  U2(
//            .clk_100M(clk),
//            .rst_n(rst_n),
//
//            .key_in(key_2),
//            .key_out(key_2_flg)
//             );
   reg   [2:0]      key_1_flag;
     wire             key_1_neg;
     wire             key_1_pos;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           key_1_flag <= 3‘b000;
        end
      else
        begin
           key_1_flag <= {key_1_flag[1:0],key_1};
        end
      end
    assign key_1_pos = (key_1_flag[2:1]== 2‘b01);

     reg   [2:0]      key_2_flag;
     wire             key_2_neg;
     wire             key_2_pos;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           key_2_flag <= 3‘b000;
        end
      else
        begin
           key_2_flag <= {key_2_flag[1:0],key_2};
        end
      end
    assign key_2_pos = (key_2_flag[2:1] == 2‘b01);

 //------------------------------------------//
    parameter  IDEL       = 3‘D0;        //初始化状态,等待发送命令
        parameter  START      = 3‘D1;        //开始发送引导码
        parameter  SEND_USER  = 3‘D2;        //发送用户码
        parameter  SEND_UNUSER= 3‘D3;        //发送用户反码
        parameter  SEND_DATA  = 3‘D4;        //发送数据
        parameter  SEND_UNDATA= 3‘D5;        //发送数据反码
        parameter  FINISH     = 3‘D6;        //发送结束码
        parameter  FINISH_1   = 3‘D7;        //发送结束
    reg   [2:0]     state;
    reg             start_en;
        wire            start_over;
        reg             zero_en;
        wire            zero_over;
        reg             one_en;
        wire            one_over;
         reg             finish_en;
        wire            finish_over;
        reg             sendover;
        reg   [7:0]     shiftdata;
        reg   [3:0]     i;
        reg   [7:0]     DATA;
        always @(posedge clk or negedge rst_n)
         begin
          if(!rst_n)
           begin
              state <= IDEL;
                    start_en <= 0;
                    zero_en <= 0;
                    one_en <= 0;
                    finish_en <= 0;
                    sendover <= 0;
                    shiftdata <= 0;
                    i <= 0;
                    DATA <= 8‘D0;

                    led_1 <= 1;
                    led_2 <= 1;
            end
          else
            begin
               case(state)
                     IDEL:
                        begin
                          start_en <= 0;
                                zero_en <= 0;
                                one_en <= 0;
                                finish_en <= 0;
                                sendover <= 0;
                                shiftdata <= 0;
                                i <= 0;
                                DATA <= 8‘d0;

                                if(key_1_pos)
                                  begin
                                    state <= START;
                                        DATA <= 8‘d1;
                                    end
                                 else if(key_2_pos)
                                     begin
                                            state <= START;
                                            DATA <= 8‘d2;
                                        end
                                else state <= IDEL;
                         end
                      START:              //发送引导码
                           begin

                                 if(start_over)
                                   begin
                                         start_en <= 0;
                                         state <= SEND_USER;
                                         shiftdata <= DATA_USER;
                                      end
                                 else
                                      begin
                                         start_en <= 1;
                                         state <= START;
                                      end
                            end
                        SEND_USER:
                          begin
//                                    led_3 <= 1;
                                    if((i==7)&&(one_over||zero_over))  //结束位
                                        begin
                                              i <=0;
                                      shiftdata <= ~DATA_USER;
                                              state <= SEND_UNUSER;
                                                one_en <= 0;
                                              zero_en <= 0;
                                         end
                                    else
                                      begin
                                            if(zero_over||one_over)   //1bit发送结束
                                              begin
                                                i <= i + 1;
                                                     one_en <= 0;
                                                     zero_en <= 0;
                                                 end
                                            else if(shiftdata[i])
                                                begin
                                                     one_en <= 1;
                                                 end
                                            else if(!shiftdata[i]) zero_en <= 1;
                                          else
                                                begin
                                                 i <= i ;
                                                     one_en <= one_en;
                                                     zero_en <= zero_en;
                                                 end
                                       end
                             end
                        SEND_UNUSER:
                           begin
                                    led_1 <= ~led_1;
                                 if((i==7)&&(one_over||zero_over))  //结束位
                                        begin
                                              i <=0;
                                              state <= SEND_DATA;
                                                shiftdata <= DATA;
                                                one_en <= 0;
                                                zero_en <= 0;

                                         end
                                    else
                                      begin
                                            if(zero_over||one_over)   //1bit发送结束
                                              begin
                                                 i <= i + 1;
                                                     one_en <= 0;
                                                     zero_en <= 0;
                                                 end
                                            else if(shiftdata[i])
                                                begin
                                                     one_en <= 1;
                                                 end
                                            else if(!shiftdata[i]) zero_en <= 1;
                                          else
                                                begin
                                                 i <= i ;
                                                     one_en <= one_en;
                                                     zero_en <= zero_en;
                                                 end
                                       end     

                                end
                        SEND_DATA:
                           begin
                                     led_2 <= ~led_2    ;
                                    if((i==7)&&(one_over||zero_over))  //结束位
                                        begin
                                              i <=0;
                                              state <= SEND_UNDATA;
                                                shiftdata <= ~DATA;
                                                one_en <= 0;
                                                zero_en <= 0;
                                         end
                                    else
                                      begin
                                            if(zero_over||one_over)   //1bit发送结束
                                              begin
                                                i <= i + 1;
                                                     one_en <= 0;
                                                     zero_en <= 0;
                                                 end
                                            else if(shiftdata[i])
                                                begin
                                                     one_en <= 1;
                                                 end
                                            else if(!shiftdata[i]) zero_en <= 1;
                                          else
                                                begin
                                                 i <= i ;
                                                     one_en <= one_en;
                                                     zero_en <= zero_en;
                                                 end
                                       end 

                                end
                    SEND_UNDATA:
                        begin

                                if((i==7)&&(one_over||zero_over))  //结束位
                                        begin
                                              i <=0;
                                              shiftdata <= 0;
                                              state <= FINISH;
                                                one_en <= 0;
                                                zero_en <= 0;
                                         end
                                    else
                                      begin
                                            if(zero_over||one_over)   //1bit发送结束
                                              begin
                                                 i <= i + 1;
                                                     one_en <= 0;
                                                     zero_en <= 0;
                                                 end
                                            else if(shiftdata[i])
                                                begin
                                                     one_en <= 1;
                                                 end
                                            else if(!shiftdata[i]) zero_en <= 1;
                                          else
                                                begin
                                                 i <= i ;
                                                     one_en <= one_en;
                                                     zero_en <= zero_en;
                                                 end
                                       end         

                                end
                        FINISH:
                           begin
                                    if(finish_over)
                                    begin
                                         finish_en <= 0;
                                         state <= FINISH_1;
                                      end
                                   else
                                      begin
                                         finish_en <= 1;
                                         state <= FINISH;
                                      end      

                                 end
                        FINISH_1:
                              begin

                                      sendover <= 1;
                                        state <= IDEL;

                              end

                      default: state <= IDEL;
                    endcase
            end
          end

  //----------------------------------------------//
     //引导码,9ms载波加4.5ms空闲
     reg    [19:0]     cnt2;
     wire              start_flag;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           cnt2 <= 0;
        end
      else if(start_en)
        begin
          if(cnt2 >= t_13_5ms)  cnt2 <= t_13_5ms+1;
            else cnt2 <= cnt2 + 1;
            end
        else cnt2  <= 0;
     end
    assign start_over = (cnt2 == t_13_5ms)?1:0;
    assign start_flag = (start_en&&(cnt2 <= t_9ms))?1:0;

  //----------------------------------------------//
     //比特0, 560us载波 + 560us空闲
     reg    [15:0]     cnt3;
     wire              zero_flag;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           cnt3 <= 0;
        end
      else if(zero_en)
        begin
          if(cnt3 >= t_1_12ms)  cnt3 <= t_1_12ms+1;
            else cnt3 <= cnt3 + 1;
            end
        else cnt3  <= 0;
     end
    assign zero_over = (cnt3 == t_1_12ms)?1:0;
    assign zero_flag = (zero_en&&(cnt3 <= t_560us))?1:0;

   //----------------------------------------------//
     //比特1, 560us载波 + 1.68ms空闲
     reg    [16:0]     cnt4;
     wire              one_flag;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           cnt4 <= 0;
        end
      else if(one_en)
        begin
          if(cnt4 >= t_2_24ms)  cnt4 <= t_2_24ms+1;
            else cnt4 <= cnt4 + 1;
            end
        else cnt4  <= 0;
     end
    assign one_over = (cnt4 == t_2_24ms)?1:0;
    assign one_flag = (one_en&&(cnt4 <= t_560us))?1:0;

    //----------------------------------------------//
     //结束码, 560us载波
     reg    [14:0]     cnt5;
     wire              finish_flag;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
           cnt5 <= 0;
        end
      else if(finish_en)
        begin
          if(cnt5 >= t_560us)  cnt5 <= t_560us+1;
            else cnt5 <= cnt5 + 1;
            end
        else cnt5  <= 0;
     end
    assign finish_over = (cnt5 == t_560us)?1:0;
    assign finish_flag = (finish_en&&(cnt5 <= t_560us))?1:0;

 //-----------------------------------//
 wire   ir_out;
 assign ir_out = start_flag||zero_flag||one_flag||finish_flag;
 assign IR_out = ir_out&&clk_38k;

 assign led_3 = i[1];
 assign led_4 = i[0];

    endmodule
    

接收程序:


    /********************************Copyright**************************************
    **----------------------------File information--------------------------
    ** File name  :ir_resive.v
    ** CreateDate :2015.06
    ** Funtions   : 中断接收程序。结束数据为:引导码+用户码+用户反码+数据码+数据反码。
    ** Operate on :M5C06N3L114C7
    ** Copyright  :All rights reserved.
    ** Version    :V1.0
    **---------------------------Modify the file information----------------
    ** Modified by   :
    ** Modified data :
    ** Modify Content:
    *******************************************************************************/

     module  IR_resive  (
               clk,
               rst_n,

                         ir_in,

                         led_error,

                         led_5,
                         led_6,
                         led_7,

                         test_data
                 );
     input          clk;
     input          rst_n;

     input          ir_in;

     output         led_error;

     output        led_5;
     output        led_6;
     output         led_7;

     output  [7:0]  test_data;
     //---------------------------------------------//
       reg    [2:0]    ir_in_reg;
         wire            ir_in_pos;
         wire            ir_in_neg;
         wire            ir_in_change;
         always @(posedge clk or negedge rst_n)
         begin
          if(!rst_n)
           begin
               ir_in_reg <= 3‘b111;
            end
          else
            begin
              ir_in_reg <= {ir_in_reg[1:0],ir_in};
            end
          end
        assign     ir_in_pos = (ir_in_reg[2:1] == 2‘b01)?1:0;
        assign     ir_in_neg = (ir_in_reg[2:1] == 2‘b10)?1:0;
        assign  ir_in_change = ir_in_pos|ir_in_neg;

     //------------------------------------//
     //设计分频和计数部分:从1838T的 技术手册中,可以得出最小的脉冲持续时间为500us,在采样时可以对最小的电平采样16次,即对500us采样16次,
   //则每次的采样间隔时间是  500us/16=31.25us     时钟频率为FCLK = X MHZ, 则最小采样计数为:N =31.25*X,
     //然后再用一个计数器计数同一电平的采样计数时间。
     //最后判断是leader的9ms 还是4.5ms,或是数据的 0 还是 1。
     //--------------------------------------------------------//
         `define     FCLK_20M
//         `define     FCLK_24M `

         `ifdef    FCLK_20M
          parameter   t_31_25us = 10‘d625;
                parameter   t_100k = 200;
            `endif    

            `ifdef    FCLK_24M
          parameter   t_31_25us = 10‘d750; //
                parameter   t_100k = 240;
            `endif

            `ifdef    FCLK_50M
          parameter   t_31_25us = 11‘d1562; //
                parameter   t_100k = 500;
            `endif

              parameter   t_low_H = 26;
                parameter   t_low_L = 13;      //16
                parameter   t_high_H=67;       //54  1.7MS左右
                parameter   t_high_L=35 ;
                parameter   t_9ms_H   =9‘d398;   //288
                parameter   t_9ms_L   =9‘d278;
                parameter   t_4_5ms_H =9‘d154;   //144
                parameter   t_4_5ms_L =9‘d134;

                parameter   t_watch  = 9‘d500;   //定时,计数达到500,则已经跑飞,

                parameter   t_1s     = 16‘d31999;

        //---------------------------------------------//
         reg              idel_flag;
         reg     [10:0]    cnt;
         always @(posedge clk or negedge rst_n)
         begin
          if(!rst_n)
           begin
              cnt <= 0;
            end
            else if(idel_flag) cnt <= 0;        //空闲状态,不再变化
          else if(ir_in_change)  cnt <= 0;
          else if(cnt == t_31_25us) cnt <= 0;
            else cnt<= cnt + 1;
         end

     reg    [8:0]        cnt1;
     always @(posedge clk or negedge rst_n)
     begin
      if(!rst_n)
       begin
          cnt1 <= 0;
        end
        else if(idel_flag) cnt1 <= 0;
      else if(ir_in_change)  cnt1 <= 0;
      else if(cnt == t_31_25us) cnt1 <= cnt1 + 1;
        else cnt1 <= cnt1;
     end

           wire          t_9ms_flag;
            wire          t_4_5_ms_flag;
            wire          short_flag;     //短电平,可是高电平也可以是低电平
            wire          long_flag;      //长电平,肯定是高电平
            assign  t_9ms_flag = ((cnt1 > t_9ms_L)&&(cnt1 < t_9ms_H));
            assign  t_4_5_ms_flag = ((cnt1 > t_4_5ms_L)&&(cnt1 < t_4_5ms_H));
            assign  long_flag = ((cnt1 > t_high_L)&&(cnt1 < t_high_H));
            assign  short_flag = ((cnt1 > t_low_L)&&(cnt1 < t_low_H));

            wire          watchdog;
            assign  watchdog =  (cnt1 > t_watch)?1:0;
    //---------------------------------------------//
    parameter   IDEL    = 4‘d0;
    parameter   L_9MS   = 4‘d1;
    parameter   L_4_5MS = 4‘d2;
    parameter   DATA_R  = 4‘d4;
    parameter   FINISH_R= 4‘d8;

   reg      [3:0]      state;
     reg      [31:0]     shiftdata;
     reg      [5:0]      n;
     reg                 error_flag;
     reg                 r_over;
     reg      [31:0]     rdata;
 always @(posedge clk or negedge rst_n)
 begin
  if(!rst_n)
   begin
      state <= IDEL;
            shiftdata <= 0;
            n <= 0;
            error_flag <= 0;
            rdata <= 0;
            r_over<= 0;
            idel_flag <= 0;

//            led_5 <= 1;
//            led_6 <= 1;
    end
//  else  if(watchdog) state <= IDEL;
    else
    begin
      case(state)
             IDEL:
               begin

                      idel_flag <= 1;   //空闲状态
                        shiftdata <= 0;
                  n <= 0;
                  error_flag <= 0;
                        r_over<= 0;
                        if(ir_in_reg[1] ==0)
                         begin
                             state <= L_9MS;  //检测到拉低数据线
                             idel_flag <= 0;
                          end
                        else  state <= IDEL;
                    end
            L_9MS:        //9ms为低电平,数据线拉高时结束
              begin
//                    led_5 <= 0;
                    if(watchdog) state <= IDEL;
                    else if(ir_in_pos)
                     begin
                         if(t_9ms_flag)  state <= L_4_5MS;
                         else
                             begin
                                 state <= IDEL;
                                 error_flag <= 1;
                                end
                      end
                    else   state <= L_9MS;
                 end
            L_4_5MS:
              begin
                 if(watchdog) state <= IDEL;
                    else if(ir_in_neg)
                     begin
                         if(t_4_5_ms_flag)  state <= DATA_R;
                         else
                             begin
                                 state <= IDEL;
                                 error_flag <= 1;
                                end
                      end
                    else   state <= L_4_5MS;
             end
            DATA_R:
              begin
//                    led_6 <= 0;
                 if(watchdog) state <= IDEL;
               else if((n == 32)&&(ir_in_reg[2:1] == 2‘b11))  state <= FINISH_R;
                 else if(ir_in_pos)
                     begin
                         if(short_flag)  state <= DATA_R;
                         else
                             begin
                                 state <= IDEL;
                                 error_flag <= 1;
                                end
                      end
                 else if(ir_in_neg)
                     begin
                            n<= n + 1;
                            if(short_flag) shiftdata[n] <= 0;        //从低位到高位依次接收,这样数据的位置是 相反的
                            else if(long_flag)  shiftdata[n] <= 1;  //从原来的{用户码,用户反码,数据,数据反码}变为{数据反码,数据,用户反码,用户码}
                            else                                     //所以要调整数据位置
                                begin
                                 state <= IDEL;
                                 error_flag <= 1;
                                end
                    end
                    else   state <= DATA_R;
              end
            FINISH_R:
              begin
                    r_over <= 1;
                    rdata <= {shiftdata[7:0],shiftdata[15:8],shiftdata[23:16],shiftdata[31:24]};               //调整位置
                    state <= IDEL;
                 end
            default:state <= IDEL;
         endcase
    end
  end

     //---------------------------------------------//
     assign led_5 = (rdata[15:8] == 8‘h01)?0:1;
     assign led_6 = (rdata[15:8] == 8‘h02)?0:1;
   assign led_7 = (rdata[31:24] == 8‘h00)?0:1;
     assign test_data = rdata[15:8];
//  assign test_data = {error_flag,t_4_5_ms_flag,ir_in_change,ir_in_reg[1],state[3:0]};
    endmodule

按键消抖(与以前有修改):

/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name  :key_shake.v
** CreateDate :2015.03
** Funtions   : 按键的消抖操作:在复位之后的100us内,不响应按键的操作,在之后有按键按下后,有20ms的延迟,之后输出按键输出.
** Operate on :M5C06N3L114C7
** Copyright  :All rights reserved[F].
** Version    :V1.0
**---------------------------Modify the file information----------------
** Modified by   :
** Modified data :             2015.04                            2015.06
** Modify Content:V1.1:clk-->clk_100M, 常数声明放到一起,便于修改。     增加实用20Mclk,并将输出修改为连续高电平
*******************************************************************************/

 module  key_shake (
           clk_100M,
           rst_n,

            key_in,
            key_out
             );
 input          clk_100M;            //100Mhz
 input          rst_n;

 input          key_in;
 output         key_out;

 //--------------------------------------

 //在复位之后的100us内,不响应按键的操作

//  `define   CLK_100M
    `define   CLK_20M

 `ifdef  CLK_100M
            parameter    t_100us  = 14‘d9999;
            parameter    t1ms = 17‘d99999;       //定时1ms
            parameter    t_20ms = 5‘d20;
  `endif

  `ifdef  CLK_20M
            parameter    t_100us  = 14‘d1999;
            parameter    t1ms = 17‘d19999;       //定时1ms
            parameter    t_20ms = 5‘d20;
  `endif

  reg    [13:0]   cnt;
    reg             key_en;         //复位之后允许按键输入标志
 always @(posedge clk_100M or negedge rst_n)
 begin
  if(!rst_n)
   begin
      cnt <= 0;
            key_en <=0;
    end
  else
    begin
      if(cnt == t_100us)
              begin
                   key_en <= 1;
                 end
       else
              begin
                    key_en <= 0;
                   cnt <= cnt + 1;
              end
    end
  end

 //--------------------------------------------------
 wire         HtoL_flag;         //下降沿标志
 wire         LtoH_flag;         //上升沿标志
 reg   [2:0]   key_reg;
 always @(posedge clk_100M or negedge rst_n)
 begin
  if(!rst_n)
   begin
      key_reg <= 3‘b111;            //默认没按下状态为高,按下之后为低.反之则为3‘b000;
    end
  else
    begin
      key_reg <= {key_reg[1:0],key_in};
    end
  end

 assign HtoL_flag = key_en?(key_reg[2:1] == 2‘b10):0;            //下降沿检测,一个时钟的高电平
 assign LtoH_flag = key_en?(key_reg[2:1] == 2‘b01):0;               //上升沿检测,一个时钟的高电平
//---------------------------------------------
 reg          cnt_en;                 //计数使能标志

 reg   [16:0]  cnt2;
 always @(posedge clk_100M or negedge rst_n)
 begin
  if(!rst_n)
   begin
      cnt2 <= 17‘d0;
    end
  else if((cnt_en)&&(cnt2 == t1ms))
    begin
      cnt2 <= 17‘d0;
    end
    else if(cnt_en)
    begin
      cnt2 <= cnt2 + 17‘d1;
    end
    else
          cnt2 <= 17‘d0;
  end

 reg   [4:0]   cnt3;
 always @(posedge clk_100M or negedge rst_n)
 begin
  if(!rst_n)
   begin
       cnt3 <= 5‘d0;
    end
  else if((cnt_en)&&(cnt2 == t1ms))
    begin
            if(cnt3 == t_20ms )
               cnt3 <= t_20ms;
            else
         cnt3 <= cnt3 + 1;
    end
    else if(!cnt_en)
       cnt3 <= 5‘d0;
  end

//----------------------------------
//按键状态机
    reg  [2:0]  i;
    reg      key_down;        //按键按下标志
    reg      key_up;          //按键释放标志
    always @(posedge clk_100M or negedge rst_n)
     begin
      if(!rst_n)
       begin
                key_down <= 0;
                key_up <= 0;
                i <= 0;
                cnt_en <= 0;
        end
      else
        begin
          case(i)
                 ‘d0:
                    begin
                             key_down <= 0;
                       key_up <= 0;
                      if(HtoL_flag) i <= ‘d1;         //检测到按下
                            else if(LtoH_flag) i <= ‘d2;    //检测到释放按键
                            else  i  <= ‘d0;
                     end
                    ‘d1:
                      begin
                            if(cnt3 == t_20ms )
                              begin
                                 if(!key_in)                  //检测到按键依然被按下
                                   begin
                                       key_down <= 1;            //按键按下成功
                                       i <= ‘d3;
                                       cnt_en <= 0;
                                      end
                                    else
                                       begin
                                        key_down <= 0;
                                         i <= ‘d0;
                                         cnt_en <= 0;
                                         end
                                 end
                             else
                               cnt_en <= 1;
                            end
                    ‘d2:
                      begin
                            if(cnt3 == t_20ms )
                              begin
                                    if(key_in)                  //检测到按键被释放
                                   begin
                                       key_up <= 1;             //按键释放成功
                                       i <= ‘d4;
                                       cnt_en <= 0;
                                      end
                                    else
                                        begin
                                           key_up <= 0;
                                         i <= ‘d0;
                                         cnt_en <= 0;
                                         end
                                 end
                             else
                               cnt_en <= 1;
                            end
                    ‘d3:
                      begin
                                                 if(key_in)
                                                   begin
                             key_down <= 0;
                             i <= ‘d0;
                                                      end
                                                    else
                                                         i <= ‘d3;
                         end
                                        ‘d4:
                                            begin
                                                 if(!key_in)
                                                   begin
                             key_up <= 0;
                             i <= ‘d0;
                                                      end
                                                    else
                                                         i <= ‘d4;
                                            end
                  default:i <= ‘d0;
                endcase
        end
      end

 assign      key_out = key_down;         //当按键被按下有效时
// assign   key_out = key_up;         //当按键被释放后才有效时
endmodule

将两个程序合在一起的顶层文件:

    /********************************Copyright**************************************
    **----------------------------File information--------------------------
    ** File name  :IR_TOP.v
    ** CreateDate :2015.06
    ** Funtions   : 中断的顶层文件
    ** Operate on :M5C06N3F256C7
    ** Copyright  :All rights reserved.
    ** Version    :V1.0
    **---------------------------Modify the file information----------------
    ** Modified by   :
    ** Modified data :
    ** Modify Content:
    *******************************************************************************/

    module  IR_TOP  (
               clk,
               rst_n,

                         ir_in,
                         ir_out,

                         key_1,
                         key_2,

                         led_d1,
                         led_d2,
                         led_d3,
                         led_d4,
                         led_d5,
                         led_d6,
                         led_d7,
                         led_d8,

                         test_data
                 );
     input          clk;
     input          rst_n;

     input          key_1;
     input          key_2;

     input          ir_in;
     output         ir_out;

     output         led_d1;
     output         led_d2;
     output         led_d3;
     output         led_d4;
     output         led_d5;
     output         led_d6;
     output         led_d7;
     output         led_d8;

     output  [7:0]  test_data;

     //---------------------------------------------//
      wire         key_1_flag;
        wire         key_2_flag;
      key_shake   U1(
            .clk_100M(clk),
            .rst_n(rst_n),

            .key_in(key_1),
            .key_out(key_1_flag)
             );

        key_shake  U2(
            .clk_100M(clk),
            .rst_n(rst_n),

            .key_in(key_2),
            .key_out(key_2_flag)
             );

      wire  [7:0]   data_t;

      IR_send  u1(
               .clk(clk),
               .rst_n(rst_n),

                         .key_1(key_1_flag),
                         .key_2(key_2_flag),

                         .IR_out(ir_out),
                         .led_1(led_d1),
                         .led_2(led_d2),
                         .led_3(led_d3),
                         .led_4(led_d4)
                 ); 

      IR_resive  u2(
               .clk(clk),
               .rst_n(rst_n),

                         .ir_in(ir_in),

                         .led_error(led_d8),

                         .led_5(led_d5),
                         .led_6(led_d6),
                         .led_7(led_d7),
                         .test_data(data_t)
                 );
     //---------------------------------------------//
     assign  test_data = data_t;
    endmodule

仿真图:

接收仿真图:

发送仿真图:

时间: 2024-10-30 03:29:17

红外解码编码学习----verilog的相关文章

编解码技术学习网站汇总

1.音视频开源 1.1 FFMPEG http://www.ffmpeg.org/ http://dranger.com/ffmpeg/ Ffmpeg Basic http://ffmpeg.tv/ http://www.libav.org/ 1.2 H264/AVC http://www.videolan.org/developers/x264.html 1.3 H265/HEVC 1.HM(HEVC test Model) 团队名称 Joint Collaborative Team on V

FFmpeg软件只是个解码编码软件,如果支持多种格式必须先安装好对应的库,下面就说下我装的库

FFmpeg软件只是个解码编码软件,如果支持多种格式必须先安装好对应的库,下面就说下我装的库:1. 安装faad2 # wget http://downloads.sourceforge.net/faac/faad2-2.6.1.tar.gz# tar xvfz faad2-2.6.1.tar.gz# cd faad2 # ./bootstrap # ./configure # make # make install 2. 安装liba52 # wget http://liba52.source

python --- 字符编码学习小结

上半年的KPI,是用python做一个测试桩系统,现在系统框架基本也差不多定下来了.里面有用到新学的工厂设计模式以及以及常用的大牛写框架的业务逻辑和python小技巧.发现之前自己写的代码还是面向过程思想的多,基本没有面向对象的思想,近半年看的代码给了很大的触动,我需要升级我的技能了,于是也花了挺多时间在这个KPI学习上,现在先总结下在做这个系统时我所面临到的python的字符编码问题. 字符编码问题,如果处理有问题,可能直接就报错了:如果处理不得当,中文就会显示乱码.这是最初接触字符编码遇到问

jsoncpp 解码编码 中文为空 乱码问题

在此,仅对自己出现的问题做个总结,没想到能帮到大家. 本地C++桌面程序,用jsoncpp 对json和服务端进行通信,静态库编译不能用,故采用的源码拷贝进行调用 服务端 用php和客户端进行通信 服务端json 解码和编码的两个函数 json_encode json_decode 如果使用在使用json_encode的中的字符串中有中文的话,有可能会出现,编码后,字符串为空, 这个我遇到的一个原因是 php脚本文件的类型是ansi 而不是utf8 ,所以用txt文本编辑器,将脚本另存为 utf

C语言之霍夫曼编码学习

?1,霍夫曼编码描述哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩. 在计算机信息处理中,"哈夫曼编码"是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩.这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码.这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目

关于URL 解码, 编码

由于近期客户需要用到CA认证,此CA认证采用的是URL方式出传值 使用指定的编码对象将 URL 编码的字符串转换为已解码的字符串. 编码个人理解就是将某字符串以某种方式储存起来,而解码则以其编码格式得出正确的结果 一般编码关键字 Encoding 引入命名空间:System.Text url编码引入命名空间:   System.Web 程序集:System.Web(在 System.Web.dll 中) URL编码 名称 说明 返回值 实例 UrlEncode(Byte[] ) 将字节数组转换为

python解码编码要点

理解要点:一个标准抽象与具体实现,两个编码一致 编码规范标准如unicode,编码具体实现:如utf8(记住要点,便于理解) 正确输出.显示的内容采用的编码与系统本地编码实际类型要一致 程序文件内或ide声明的字符编码有时与实际编码有区别 python对win本地码一律采用mbcs(程序文件强烈建议统一采用unicode实现) 本地编码字符集可能不包括特定字符 要正确的解码decode的字符串本身编码要与解码指定的编码实际类型要一致 使用要点:三个u 程序中生成中文文件名:u'中文文件名' 文件

encodeURI 解码 编码

var uriStr = "http://www.baidu.com?name=张三&num=001 zs"; var uriec = encodeURI(uriStr); document.write("编码后的" + uriec); var uridc = decodeURI(uriec); document.write("解码后的" + uridc); loadMain(); showPopover(); //playOrPause

JS编码,解码. asp.net(C#)对应解码,编码

escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z 1. JS: escape : js使用数据时可以使用escape 例如:搜藏中history纪录. 0-255以外的unicode值进行编码时输出%u**