|
- `define fosc 50000000 //晶振频率
- module nec_encode( //NEC协议 红外遥控器编码模块
- input clk, //50Mhz时钟输入
- input send, //高电平脉冲发射:用户码+按键码,持续高电平发射:重复码 低电平停止发射
- input [15:0] user, //欲发射的16位用户码
- input [7:0] key, //欲发射的8位按键码
- output reg out //NEC编码发射输出 (未调制,1有载波,0无载波)
- );
- wire [31:0] k = {user,key,~key};
- integer delay_clk = 0; //延时时钟
- reg [6:0] step = 0; //范围:0~71
- reg [4:0] l; //数据指针 范围:0~31
- reg run = 0; //是否正在发射
- always @(posedge clk) begin
- if(send) begin
- run <= 1'b1;
- end else begin
- if(step >= 68 && step < 71 && !out) begin
- run <= 1'b0;
- end
- end
- end
- always @(posedge clk) begin
- if(run) begin
- if(|delay_clk) begin
- delay_clk <= delay_clk - 1'b1;
- end else begin
- if(step == 0) begin //9ms 高引导码
- l <= 0;
- out <= 1;
- delay_clk <= 450000; //延时45w个时钟=9ms fosc*0.009
- end
- if(step == 1) begin //4.5ms 低引导码
- out <= 0;
- delay_clk <= 225000; //4.5ms fosc*0.0045 (一个时钟20ns)
- end
- if(step >= 2 && step <= 67) begin //发送数据
- if(step[0]) begin
- out <= 0;
- l <= l + 1'b1;
- delay_clk <= k[24 ^ l] ? 84000 : 28000;
- end else begin
- out <= 1;
- delay_clk <= 28000; //560us fosc*0.000560
- end
- end
- if(step >= 68) begin //重复码(长按码) 100ms延时+9000uS载波+2250uS空闲+560uS载波
- if(step == 68) begin
- out <= 0;
- delay_clk <= 5000000; //100ms延时
- step <= 69;
- end else if(step == 69) begin
- out <= 1;
- delay_clk <= 450000; //9ms载波
- step <= 70;
- end else if(step == 70) begin
- out <= 0;
- delay_clk <= 112500; //2250us 空闲
- step <= 71;
- end else if(step == 71) begin
- out <= 1;
- delay_clk <= 28000; //560us 载波
- step <= 68;
- end
- end else begin
- step <= step + 1'b1;
- end
- end
- end else begin
- l <= 0;
- delay_clk <= 0;
- step <= 0;
- out <= 0;
- end
- end
- endmodule
- module main(
- input clk, //50Mhz 时钟输入 Pin17
- input skey, //按键 (低电平按下,高电平松开,未消抖) Pin144
- output led, //LED (未调制,发射时(低电平)点亮,发射后(高电平)熄灭) Pin3
- output red //红外发射管 (已调制,低电平点亮) 38Khz 占空比:1/3 Pin30
- );
- //红外发射管载波调制
- wire red_send; //红外载波开关 1有载波 0无载波(高电平)
- integer i = 0;
- assign red = !((i < `fosc/38000/3) && red_send);
- always @(posedge clk) begin
- i = i + 1;
- if(i == `fosc/38000) begin
- i = 0;
- end
- end
- //按键消抖
- reg key;
- initial key = 1;
- integer clk_1ms = 0;
- reg [7:0] key_ms =0; //按键长按时间毫秒 8位最大255 松开清0
- always @(posedge clk) begin
- clk_1ms = clk_1ms + 1;
- if(clk_1ms >= `fosc/1000) begin
- clk_1ms = 0;
- if(skey) begin //按键松开
- key_ms = 0;
- end else begin //按键按下
- if(!(&key_ms)) begin
- key_ms = key_ms + 1;
- end
- end
- key = !(key_ms >= 25); //按键消抖25毫秒
- end
- end
- nec_encode nec_encode(
- .clk(clk),
- .send(!key),
- .user(16'h00FF),
- .key(8'h01),
- .out(red_send)
- );
- assign led = !red_send;
- endmodule
复制代码 |
|