由于实在是太久没发帖子了,引起了园长的不满,再加上买了Rd-03雷达几个月了还没怎么玩过,所以今天水一帖交个作业
这次我用的是Rd-03雷达、LCD1602显示屏、和Intel Cyclone 10 10CL025YU256I7G芯片
做的所谓的报警器很简单:雷达检测到有人来,发送信号到主控,蜂鸣器响起,屏幕上显示'some body come in'、'Warning';没人的时候蜂鸣器不响,屏幕上显示'nobody come in'、'safe'
整体就是这个样子,LCD1602用个转接板接到开发板上,不用接杜邦线比较方便,还可以轻易调亮度和对比度
整体图
下面就是思路和程序了
Rd-03雷达检测到有人来会在OT2引脚输出一个高电平,没人的时候输出低电平,因此只需要检测高低电平就知道有没有人来了。
至于检测的距离设置我买的是测试板套装,可以在安信可配网助手里设置距离门(检测距离)
之后是LCD1602的驱动程序
- module lcd(
- clk,
- rst,
- LCD_EN,
- RS,
- RW,
- DB8,
- trig //trigger
- //data_row1,
- //data_row2
- );
- //input [127:0]data_row1,data_row2;//第一行和第二行输入数据
- input clk;
- input rst; //rst为全局复位信号
- input trig;
- output LCD_EN;//LCD_EN为LCD模块的使能信号(下降沿触发)
- output reg RS;//RS=0时为写指令;RS=1时为写数据
- output RW;//RW=0时对LCD模块执行写操作;RW=1时对LCD模块执行读操作
- output [7:0] DB8; //8位指令或数据总线
- reg LCD_EN_Sel;
- reg [7:0] DB8;
- reg [127:0]data_row1;
- reg [127:0]data_row2;
- //-------------------------------------//
- //输入时钟50MHz 输出周期2ms
- //division50MHz_2ms.v
- reg [15:0]count;
- reg clk_2ms;
- always @ (posedge clk)
- begin
- if(count == 16'd50_000)
- begin
- count <= 16'b1;
- clk_2ms <= ~clk_2ms;
- end
- else
- count <= count + 1'b1;
- end
- //---------------------------------------//
- reg [127:0] Data_Buf; //液晶显示的数据缓存
- reg [4:0] disp_count;
- reg [3:0] state;
- parameter Clear_Lcd = 4'b0000, //清屏并光标复位
- Set_Disp_Mode = 4'b0001, //设置显示模式:8位2行5x7点阵
- Disp_On = 4'b0010, //显示器开、光标不显示、光标不允许闪烁
- Shift_Down = 4'b0011, //文字不动,光标自动右移
- Write_Addr = 4'b0100, //写入显示起始地址
- Write_Data_First = 4'b0101, //写入第一行显示的数据
- Write_Data_Second = 4'b0110; //写入第二行显示的数据
- assign RW = 1'b0; //RW=0时对LCD模块执行写操作(一直保持写状态)
- assign LCD_EN = LCD_EN_Sel ? clk_2ms : 1'b0;//通过LCD_EN_Sel信号来控制LCD_EN的开启与关闭
- always @(*) begin
- if(!rst) begin
- data_row1 <= "IT IS IN RESET ";
- data_row2 <= "RELEASE THE KEY ";
- end
- else if(trig) begin
- data_row1 <= "somebody come in";
- data_row2 <= " WARNING ";
- end
- else begin
- data_row1 <= " nobody come in ";
- data_row2 <= " SAFE ";
- end
- end
- always @(posedge clk_2ms or negedge rst)
- begin
- if(!rst)
- begin
- state <= Clear_Lcd; //复位:清屏并光标复位
- RS <= 1'b1; //复位:RS=1时为读指令;
- DB8 <= 8'b0; //复位:使DB8总线输出全0
- LCD_EN_Sel <= 1'b0; //复位:关夜晶使能信号
- disp_count <= 5'b0;
- end
- else
- begin
- case(state) //初始化LCD模块
- Clear_Lcd:
- begin
- LCD_EN_Sel <= 1'b1;//开使能
- RS <= 1'b0;//写指令
- DB8 <= 8'b00000001; //清屏并光标复位
- state <= Set_Disp_Mode;
- end
- Set_Disp_Mode:
- begin
- DB8 <= 8'b00111000; //设置显示模式:8位2行5x8点阵
- state <= Disp_On;
- end
- Disp_On:
- begin
- DB8 <= 8'b00001100; //显示器开、光标不显示、光标不允许闪烁
- state <= Shift_Down;
- end
- Shift_Down:
- begin
- DB8 <= 8'b00000110; //文字不动,光标自动右移
- state <= Write_Addr;
- end
- //---------------------------------显示循环------------------------------------//
- Write_Addr:
- begin
- RS <= 1'b0;//写指令
- DB8 <= 8'b10000000; //写入第一行显示起始地址:第一行第1个位置
- Data_Buf <= data_row1; //将第一行显示的数据赋给Data_First_Buf
- // DB8 <= Data_First_Buf[127:120];
- state <= Write_Data_First;
- end
- Write_Data_First: //写第一行数据
- begin
- if(disp_count == 16) //disp_count等于15时表示第一行数据已写完
- begin
- RS <= 1'b0;//写指令
- DB8 <= 8'b11000000; //送入写第二行的指令,第2行第1个位置
- disp_count <= 5'b0; //计数清0
- Data_Buf <= data_row2;//将第2行显示的数据赋给Data_First_Buf
- // DB8 <= Data_Second_Buf[127:120];
- state <= Write_Data_Second; //写完第一行进入写第二行状态
- end
- else//没写够16字节
- begin
- RS <= 1'b1; //RS=1表示写数据
- DB8 <= Data_Buf[127:120];
- Data_Buf <= (Data_Buf << 8);
- disp_count <= disp_count + 1'b1;
- state <= Write_Data_First;
- end
- end
- Write_Data_Second: //写第二行数据
- begin
- if(disp_count == 16)//数据写完了
- begin
- RS <= 1'b0;//写指令
- DB8 <= 8'b10000000; //写入第一行显示起始地址:第一行第1个位置
- disp_count <= 5'b0;
- state <= Write_Addr; //重新循环
- end
- else//
- begin
- RS <= 1'b1;
- DB8 <= Data_Buf[127:120];
- Data_Buf <= (Data_Buf << 8);
- disp_count <= disp_count + 1'b1;
- state <= Write_Data_Second;
- end
- end
- //--------------------------------------------------------------------------//
- default: state <= Clear_Lcd; //若state为其他值,则将state置为Clear_Lcd
- endcase
- end
- end
- endmodule
复制代码 通过触发信号trig,即雷达OT2引脚的输出来确定检测范围内是否有人,从而确定屏幕上显示什么内容
没人来的时候
有人来的时候
之后是蜂鸣器,我开发板上的蜂鸣器是无源蜂鸣器,需要给一个大约500Hz~5KHz的PWM波才能驱动
- module beep(
- clk, // 50 MHz clock input
- rst, // Reset input
- trig, // trig input to control PWM output
- pwm_out // PWM output
- );
- input clk;
- input rst;
- input trig;
- output reg pwm_out;
- reg [17:0] count; // Counter for generating PWM
- localparam [17:0] count_period = 18'd60_000 - 1; // 50M / 2000 = 25000
- // PWM generation logic
- always @(posedge clk or negedge rst) begin
- if (!rst) begin
- count <= 18'd0;
- pwm_out <= 1'b0;
- end else begin
- if (trig) begin
- if (count >= count_period) begin
- count <= 18'd0;
- pwm_out <= ~pwm_out; // Toggle the PWM output
- end else begin
- count <= count + 1;
- end
- end else begin
- count <= 18'd0; // Reset the counter when sw is 0
- pwm_out <= 1'b0; // Disable PWM output when sw is 0
- end
- end
- end
- endmodule
复制代码 beep蜂鸣器同样由trig信号来控制是否响,有人来响,没人来不响。
写好了蜂鸣器和LCD1602模块之后,在顶层模块例化它们
- module radar(
- clk, // 50 MHz clock input
- rst, // Reset input
- pwm_out, // PWM output
- LCD_EN,
- RS,
- RW,
- DB8,
- trig //trigger
- );
- input clk;
- input rst;
- input trig;
- output pwm_out;
-
- output LCD_EN;//LCD_EN为LCD模块的使能信号(下降沿触发)
- output RS;//RS=0时为写指令;RS=1时为写数据
- output RW;//RW=0时对LCD模块执行写操作;RW=1时对LCD模块执行读操作
- output [7:0] DB8; //8位指令或数据总线
-
- lcd u_lcd(
- .clk(clk),
- .rst(rst),
- .LCD_EN(LCD_EN),
- .RS(RS),
- .RW(RW),
- .DB8(DB8),
- .trig(trig)
- );
-
- beep u_beep(
- .clk(clk),
- .rst(rst),
- .trig(trig),
- .pwm_out(pwm_out)
- );
- endmodule
复制代码
综合、分配管脚,大功告成
论坛发不了视频,只能发个GIF了,没有蜂鸣器的声音
|