您的当前位置:首页正文

FPGA操控红外

2020-12-22 来源:品趣旅游知识分享网
FPGA操控红外

所用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=cnt_initl) begin state<=INIT_H; cnt<=16'b0; //接收起始码的低电平时,如果出现高电平时,低电平的持续时间已经? //到7ms,就进入接收起始码的高电平状态,否则当作干扰,重新回到等待状态 end else state<=WAIT; end end /*************************************************/ INIT_H: begin if(tempIR) begin if(cnt if(cnt>=cnt_inith) begin state<=USERCODE_L; cnt<=16'b0;

//接收起始码的高电平时,如果出现低电

平时,高电平的持续时间已经 //到了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//接收数据码的高电平时,如果出现低电平时,高//到了0.35ms但小于1ms,就移位0进入code寄//位1进入code寄存器,code加一,进入下一次

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=cnt_1ms) begin invercode<={1'b1,invercode[7:1]}; codecnt<=codecnt+1'b1; state<=INVERCODE_L; cnt<=16'b0; end else state<=WAIT; end end /*************************************************/ endcase end end

/****************************************************/ endmodule

SignalTap波形图:

因篇幅问题不能全部显示,请点此查看更多更全内容