本期测评,我们使用安路SF1开发板进行Verilog纯逻辑的应用设计,实现智能垃圾桶的功能。测评中使用到的外设有HC-SR04超声波模块、SG90舵机,因此本次工程也主要分为两个模块。分别为sonic超声波模块,以及servos舵机模块。
首先介绍超声波模块。如下图所示,基本原理是超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时。计算公式为:距离 = 声速 × 发出超声波到接收返回的时间/2。本工程中因为取的时钟频率是17Khz,则distance=340*T/2=170*(1/17000)*100,单位是cm。
超声波模块代码如下:
module sonic(
input clk,
input rst_n,
input Echo,
output reg Trig,
output reg [7:0] data
);
//Trig
reg [23:0] cnt_trig;
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_trig<=1'b0;
else
if(cnt_trig =='d250) begin
Trig<=0;
cnt_trig<=cnt_trig+1'b1;
end
else
begin
if(cnt_trig=='d500000)
begin
Trig<=1;
cnt_trig<=0;
end
else
cnt_trig<=cnt_trig+1'b1;
end
end
reg Echo_2,Echo_1,cnt_en,flag;
assign pose_Echo =(~Echo_2)&&Echo_1;
assign nege_Echo = Echo_2&&(~Echo_1);
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10;
reg[1:0] curr_state;
reg [15:0] cnt;
reg [15:0] dis_reg;
reg [15:0] cnt_17k;
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
Echo_1 <= 1'b0;
Echo_2 <= 1'b0;
cnt_17k <=1'b0;
dis_reg <=1'b0;
curr_state <= S0;
end
else
begin
Echo_1<=Echo;
Echo_2<=Echo_1;
case(curr_state)
S0:begin
if (pose_Echo)
curr_state <= S1;
else
begin
cnt <= 1'b0;
end
end
S1:begin
if(nege_Echo)
curr_state <= S2;
else
begin
if(cnt_17k <16'd1470)
begin
cnt_17k <= cnt_17k + 1'b1;
end
else
begin
cnt_17k <= 1'b0;
cnt[3:0] <= cnt[3:0] +1'b1;
end
if(cnt[3:0] >= 'd10)
begin
cnt [3:0] <=1'b0;
cnt [7:4]<=cnt[7:4]+1'b1;
end
if (cnt[7:4] >= 'd10)
begin
cnt[7:4]<=1'b0;
cnt[11:8]<=cnt[11:8]+1'b1;
end
if (cnt[11:8]>='d10)
begin
cnt[11:8]<=1'b0;
cnt[15:12]<=cnt[15:12]+1'b1;
end
if(cnt[15:12]>='d10)
begin
cnt[15:12]<=1'b0;
end
end
end
S2:begin
dis_reg<=cnt;
cnt <=1'b0;
curr_state <= S0;
end
endcase
end
end
//assign data = dis_reg ; //对输出的data赋值,因为取的时钟频率是17Khz,340*T/2=170*(1/17000)*100=T单位是cm
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)
data <= 8'd0;
else if(dis_reg>=255)
data <= 255;
else
data <= dis_reg[7:0];
end
endmodule
下面介绍舵机模块。SG90舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得控制系统非常容易与之接口。舵机的控制一般需要一个20ms 左右的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms 范围内的角度控制脉冲部分。以180 度角度伺服为例,那么对应的控制关系是这样的:
舵机角度的输出采用PWM控制,由于SF1开发板的系统时钟是25MHz,1s的计数为25000000,所以舵机角度与计数次数的关系为:计数次数=278*角度+12500。具体代码如下:
module servos(
input clk,
input rst_n,
input en,
output reg pwm
);
parameter TIME_20MS = 20'd500_000;
parameter TIME_1_5MS = 17'd37_500;
reg [19:0] cnt;
//20ms cnt
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 20'd0;
else if(cnt == TIME_20MS-1'b1)
cnt <= 20'd0;
else
cnt <= cnt + 1'b1;
end
//pwm
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
pwm <= 1'b0;
else if(en)begin
if(cnt<=TIME_1_5MS-1'b1)
pwm <= 1'b1;
else
pwm <= 1'b0;
end
else begin
if(cnt<=17'd10417)
pwm <= 1'b1;
else
pwm <= 1'b0;
end
end
endmodule
在顶层文件 trash_can_top 中,我们设置触发距离为25cm,即当超声波检测到25cm内有物体时,控制舵机自动打开垃圾桶,否则关闭垃圾桶,代码如下:
module trash_can_top(
input clk,
input rst_n,
input echo,
output trig,
output pwm
);
wire [7:0] distance;
wire [0:0] en;
assign en = (distance<=25) ? 1'b1 : 1'b0;
sonic sonic_u1(
.clk(clk),
.rst_n(rst_n),
.Echo(echo),
.Trig(trig),
.data(distance) //cm
);
servos servos_u1(
.clk(clk),
.rst_n(rst_n),
.en(en),
.pwm(pwm)
);
endmodule
引脚约束文件如下:
set_pin_assignment { clk } { LOCATION = D7; }
set_pin_assignment { echo } { LOCATION = B10; }
set_pin_assignment { pwm } { LOCATION = C10; }
set_pin_assignment { rst_n } { LOCATION = G3; }
set_pin_assignment { trig } { LOCATION = B11; }
编译综合无误后下载至开发板,智能垃圾桶外观如下:
视频演示如下,当人距离垃圾桶25cm以内时,垃圾桶自动打开,否则,垃圾桶关闭,实现了无接触的功能:
VID_20230610_183238
工程如下:
SF1芯片由于集成了FPGA与MCU两大模块,开发一些控制系统还是很有优势的。