设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 758|回复: 2
收起左侧

Quartus Verilog HDL/FPGA 一个按键的940nm红外NEC协议遥控器 发射任意按键的编码算法

[复制链接]
发表于 2022-8-12 09:56:58 | 显示全部楼层 |阅读模式
main.png

  1. `define fosc 50000000                //晶振频率

  2. module nec_encode(                        //NEC协议 红外遥控器编码模块
  3.         input clk,                                        //50Mhz时钟输入
  4.         input send,                                        //高电平脉冲发射:用户码+按键码,持续高电平发射:重复码 低电平停止发射
  5.         input [15:0] user,                //欲发射的16位用户码
  6.         input [7:0] key,                        //欲发射的8位按键码
  7.         output reg out                                //NEC编码发射输出 (未调制,1有载波,0无载波)
  8. );

  9. wire [31:0] k = {user,key,~key};
  10. integer delay_clk = 0;                                        //延时时钟
  11. reg [6:0] step = 0;                //范围:0~71
  12. reg [4:0] l;                                //数据指针 范围:0~31
  13. reg run = 0;                                //是否正在发射

  14. always @(posedge clk) begin
  15.         if(send) begin
  16.                 run <= 1'b1;
  17.         end else begin
  18.                 if(step >= 68 && step < 71 && !out) begin
  19.                         run <= 1'b0;
  20.                 end
  21.         end
  22. end

  23. always @(posedge clk) begin
  24.         if(run) begin
  25.                 if(|delay_clk) begin
  26.                         delay_clk <= delay_clk - 1'b1;
  27.                 end else begin
  28.                                 if(step == 0) begin                        //9ms 高引导码
  29.                                         l <= 0;
  30.                                         out <= 1;
  31.                                         delay_clk <= 450000;  //延时45w个时钟=9ms fosc*0.009
  32.                                 end
  33.                                 if(step == 1) begin                        //4.5ms 低引导码
  34.                                         out <= 0;
  35.                                         delay_clk <= 225000;  //4.5ms fosc*0.0045 (一个时钟20ns)
  36.                                 end
  37.                                 if(step >= 2 && step <= 67) begin                //发送数据
  38.                                         if(step[0]) begin
  39.                                                 out <= 0;
  40.                                                 l <= l + 1'b1;
  41.                                                 delay_clk <= k[24 ^ l] ? 84000 : 28000;
  42.                                         end else begin
  43.                                                 out <= 1;
  44.                                                 delay_clk <= 28000;                //560us fosc*0.000560       
  45.                                         end
  46.                                 end

  47.                                 if(step >= 68) begin                        //重复码(长按码) 100ms延时+9000uS载波+2250uS空闲+560uS载波
  48.                                         if(step == 68) begin
  49.                                                 out <= 0;
  50.                                                 delay_clk <= 5000000;                //100ms延时
  51.                                                 step <= 69;
  52.                                         end else if(step == 69) begin
  53.                                                 out <= 1;
  54.                                                 delay_clk <= 450000;                        //9ms载波
  55.                                                 step <= 70;
  56.                                         end else if(step == 70) begin
  57.                                                 out <= 0;
  58.                                                 delay_clk <= 112500;                //2250us 空闲
  59.                                                 step <= 71;
  60.                                         end else if(step == 71) begin
  61.                                                 out <= 1;
  62.                                                 delay_clk <= 28000;                //560us 载波
  63.                                                 step <= 68;
  64.                                         end                                                        
  65.                                 end else begin
  66.                                         step <= step + 1'b1;                       
  67.                                 end
  68.                 end

  69.         end else begin
  70.                 l <= 0;
  71.                 delay_clk <= 0;
  72.                 step <= 0;
  73.                 out <= 0;
  74.         end
  75. end
  76. endmodule

  77. module main(
  78.         input clk,                //50Mhz 时钟输入 Pin17
  79.         input skey,                //按键 (低电平按下,高电平松开,未消抖) Pin144
  80.         output led,                //LED (未调制,发射时(低电平)点亮,发射后(高电平)熄灭) Pin3
  81.         output red                //红外发射管 (已调制,低电平点亮) 38Khz 占空比:1/3 Pin30
  82. );

  83. //红外发射管载波调制
  84. wire red_send;                //红外载波开关 1有载波 0无载波(高电平)
  85. integer i = 0;
  86. assign red = !((i < `fosc/38000/3) && red_send);
  87. always @(posedge clk) begin
  88.         i = i + 1;
  89.         if(i == `fosc/38000) begin
  90.                 i = 0;
  91.         end
  92. end

  93. //按键消抖
  94. reg key;
  95. initial key = 1;
  96. integer clk_1ms = 0;
  97. reg [7:0] key_ms =0;                        //按键长按时间毫秒 8位最大255 松开清0
  98. always @(posedge clk) begin
  99.         clk_1ms = clk_1ms + 1;
  100.         if(clk_1ms >= `fosc/1000) begin
  101.                 clk_1ms = 0;
  102.                 if(skey) begin                //按键松开
  103.                         key_ms = 0;
  104.                 end else begin                //按键按下
  105.                         if(!(&key_ms)) begin
  106.                                 key_ms = key_ms + 1;
  107.                         end
  108.                 end
  109.                 key = !(key_ms >= 25);                //按键消抖25毫秒
  110.         end
  111. end

  112. nec_encode nec_encode(
  113.         .clk(clk),
  114.         .send(!key),
  115.         .user(16'h00FF),
  116.         .key(8'h01),
  117.         .out(red_send)
  118. );

  119. assign led = !red_send;

  120. endmodule
复制代码

相关帖子

您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-26 03:17 , Processed in 1.336076 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表