所用FPGA芯片:EP2C8Q208C8
红外发射端的波形(接收端的输出的高低电平与发射端的相反):
module infrared ( CLK, RST_N, IR, TO );
/********************************/ input CLK;
input IR;//红外一体化接收头的输出端
input RST_N;
output [7:0] TO;//八位led灯输出,用以显示接收的数据码 /***************************************/ wire clk_1MHz;//分频出1MHz,周期为1us fenpinqi_daicanshu #25 f1(CLK,clk_1MHz); /*******************************/ wire clk_10kHz;//分频出10kHz
fenpinqi_daicanshu #2500 f2(CLK,clk_10kHz); /************************************/ reg tempIR;
always @ (posedge clk_1MHz) begin tempIR<=IR; end
/****************************************/ //计数值以1MHz时钟为标准
parameter cnt_initl=7000;//起始码由9ms的低电平和4.5ms的高电平组成,这里如果收到7ms的低电平就认为是起始码的低电平
parameter cnt_inith=3000;//起始码由9ms的低电平和4.5ms的高电平组成,这里如果收到3ms的低电平就认为是起始码的高电平
//位0由0.56ms的低电平和0.565的高电平组成,接收用户码和数据码状态时,先检测是否收到低电平,
//然后计算高电平的持续时间以判断是收到0还是1
parameter cnt_effect=100;//接收用户码和数据码时高电平大于0.1ms才有效,否则当作无效高电平
parameter cnt_350us=350;//高电平持续时间超过0.35ms,小于1ms,认为是位0的高电平 parameter cnt_1ms=1000;//接收用户码或者数据码时,高电平持续时间大于1ms就认为是位1的高电平
parameter cnt_3ms=3000;//接收数据码或者用户码时,高电平持续时间过长也认为是无效高电平
parameter WAIT=9'b0_0000_0001;//等待接收阶段
parameter INIT_L=9'b0_0000_0010;//接收起始码低电平状态 parameter INIT_H=9'b0_0000_0100;//接收起始码高电平状态
parameter USERCODE_L=9'b0_0000_1000;//接收用户码低电平阶段 parameter USERCODE_H=9'b0_0001_0000;//接收用户码高电平阶段 parameter DATACODE_L=9'b0_0010_0000;//接收数据码低电平状态 parameter DATACODE_H=9'b0_0100_0000;//接收数据码高电平状态 parameter INVERCODE_L=9'b0_1000_0000;//接收数据反码低电平状态 parameter INVERCODE_H=9'b1_0000_0000;//接收数据反码高电平状态 /****************************************/ reg [15:0] cnt; reg [7:0] code;
reg [7:0] invercode; reg [8:0] state;
reg [4:0] codecnt;
/*************************************************/
reg rxfinish;//接收完成标志位,每完成一次接收,出现一次上升沿 reg rxfinish1; reg rxfinish2; reg [7:0] TO;
always @ (posedge CLK)//注意,这里检测rxfinish的上升沿时要注意,因为rxfinish在这里只持续一个clk_1MHz的时间,所以你的检测时钟频率要是clk_1MHz的两倍以上 begin rxfinish1<=rxfinish; rxfinish2<=rxfinish1; if(~rxfinish2&rxfinish1) TO<=code;//输出数据码 //TO<=invercode;//输出数据反码 end
/*********************************************/ always @ (posedge clk_1MHz) begin if(!RST_N) begin cnt<=16'b0; code<=8'b0; invercode<=8'b0; codecnt<=5'b0; rxfinish<=1'b0; state<=WAIT; end else begin case(state) WAIT: begin if(!tempIR) begin state<=INIT_L; cnt<=16'b0; code<=8'b0; invercode<=8'b0; codecnt<=5'b0; rxfinish<=1'b0; end else begin cnt<=16'b0;
code<=8'b0; invercode<=8'b0; codecnt<=5'b0; state<=WAIT; rxfinish<=1'b0; end end /*************************************************/ INIT_L: begin if(!tempIR) begin if(cnt //接收起始码的高电平时,如果出现低电 平时,高电平的持续时间已经 //到了3ms,就进入接收数据码的状态,否则当作干扰,重新回到等待状态 end else state<=WAIT; end end /*************************************************/ USERCODE_L://接收用户码的低电平 begin if(codecnt>=5'b10000) //检测接收数据个数时,要在低电平时检测,因为每个数据 位的波形都是从低电平零开始的 begin codecnt<=5'b0; state<=DATACODE_L; cnt<=16'b0; end else if(!tempIR) begin if(cnt>cnt_1ms)//如果接收用户码时低电平持续时间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us) 电平的持续时间已经 否则当作干扰,重新回到等待状态 //接收用户码的低电平时,如果出现高电平时,低//到了0.35ms,就进入接收用户码的高电平状态, begin state<=USERCODE_H; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ USERCODE_H://接收用户码的高电平 begin if(tempIR) begin if(cnt>cnt_3ms)//如果接收用户码时高电平持续时 间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us) //接收用户码的高电平时,如果出现低电平时,高电平的持续时间已经 //到了0.35ms,就code加一,进入下一次用户码的接收或者接收数据码 begin codecnt<=codecnt+1'b1; state<=USERCODE_L; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ DATACODE_L: begin if(codecnt>=5'b01000) //判断接收数据个数时要在低电平时进行判断,因为每一位数据的波形都是先从低电平开始的 begin //rxfinish<=1'b1; state<=INVERCODE_L; cnt<=16'b0; codecnt<=5'b0; end else if(!tempIR) begin if(cnt>cnt_1ms)//如果接收数据码时低电平持续时间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us) //接收数据码的低电平时,如果出现高电平时,低电平的持续时间经 //到了0.35ms,就进入接收数据码的高电平状态,否则当作干扰,重新回到等待状态 begin state<=DATACODE_H; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ DATACODE_H: begin if(tempIR) begin if(cnt>cnt_3ms)//如果接收数据码时高电平持续时间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us&&cnt begin code<={1'b0,code[7:1]}; codecnt<=codecnt+1'b1; state<=DATACODE_L; cnt<=16'b0; end else if(cnt>=cnt_1ms) begin code<={1'b1,code[7:1]}; codecnt<=codecnt+1'b1; state<=DATACODE_L; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ INVERCODE_L: begin if(codecnt>=5'b01000) begin rxfinish<=1'b1; state<=WAIT; cnt<=16'b0; codecnt<=5'b0; end else if(!tempIR) begin if(cnt>cnt_1ms)//如果接收数据码反码时低电平持续时间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us) 低电平的持续时间经 否则当作干扰,重新回到等待状态 //接收数据码反码的低电平时,如果出现高电平时,//到了0.35ms,就进入接收数据码的高电平状态, begin state<=INVERCODE_H; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ INVERCODE_H: begin if(tempIR) begin if(cnt>cnt_3ms)//如果接收数据码反码时高电平持 续时间过长,也认为是干扰,回到等待状态 state<=WAIT; else cnt<=cnt+1'b1; end else begin if(cnt>=cnt_350us&&cnt /****************************************************/ endmodule SignalTap波形图: 因篇幅问题不能全部显示,请点此查看更多更全内容