回顾
上一节稍微带了点ps2手柄的协议,主要是cs与cmd信号控制的细致时间,也为大家备上了代码,这节是关于ps2手柄与fpga通信然后控制小车电机的信号处理部分。这部分建议是对ps2手柄和机械臂有点基础理解的看哈。
思路
规划右边的旋钮x反向上控制机械臂的舵机一也就是最下面在水平上往左还是右转的,然后y轴上控制舵机二也就是舵机一的朝向前或后转,三角形与X分别是舵机舵机三,然后⚪与□就是舵机四。效果为把旋钮往左或右边掰就是让舵机一水平向左或右转每100ms转若干度,往上或下掰就是舵机一也就是舵机二朝前或后每100ms转若干度,其他四个按钮也是,最后还有手柄正前方食指按的俩个按键一个让机械爪松一个紧。再进阶些我准备就是让旋钮在不同的模拟量每100ms旋转的量不同可以看看下面的图。
实现
由上节的代码我们可以得到旋钮的模拟量,所以可以例化上节的过程然后把数据引出,再对每个模拟量定于个四位的寄存器,当模拟量处于0-59就第0位为高其他类推然后中间是全为低电平认为没有推旋钮。
// 处理摇杆数据
always @(posedge clk or negedge rst) begin
if (!rst) begin
Dat5_state <= 4'b0000;
Dat6_state <= 4'b0000;
Dat7_state <= 4'b0000;
Dat8_state <= 4'b0000;
end else begin
// 处理Dat5(右侧X轴)
if (Dat5 >= 8'd0 && Dat5 < 8'd59) begin
Dat5_state <= 4'b0001; // 最小区域
end else if (Dat5 >= 8'd59 && Dat5 < 8'd118) begin
Dat5_state <= 4'b0010; // 第二小区域
end else if (Dat5 >= 8'd138 && Dat5 < 8'd200) begin
Dat5_state <= 4'b0100; // 第二大数据区域
end else if (Dat5 >= 8'd200 && Dat5 <= 8'd256) begin
Dat5_state <= 4'b1000; // 最大数据区域
end else begin
Dat5_state <= 4'b0000;
end
y轴以及左边的也一样。
然后就可以用这个四位寄存器去控制角度变化啦。
// 100ms计数器逻辑
always @(posedge clk or negedge rst) begin
if (!rst) begin
cnt_100ms <= 23'd0;
flag_100ms <= 1'b0;
end else begin
if (cnt_100ms == 23'd4_999_999) begin
cnt_100ms <= 23'd0;
flag_100ms <= 1'b1;
end else begin
cnt_100ms <= cnt_100ms + 1'b1;
flag_100ms <= 1'b0;
end
end
end
// 角度控制逻辑
always @(posedge clk or negedge rst) begin
if (!rst) begin
angle1 <= 9'd180; // 复位时角度为180
angle2 <= 9'd180; // 复位时角度为180
angle3 <= 9'd180; // 复位时角度为180
angle4 <= 9'd180; // 复位时角度为180
end else if (flag_100ms) begin
// 处理angle1(对应Dat5_state)
if (Dat5_state[0] && angle1 < 9'd360) begin
angle1 <= angle1 + 9'd3;
end else if (Dat5_state[1] && angle1 < 9'd360) begin
angle1 <= angle1 + 9'd1;
end else if (Dat5_state[2] && angle1 > 9'd0) begin
angle1 <= angle1 - 9'd1;
end else if (Dat5_state[3] && angle1 > 9'd0) begin
angle1 <= angle1 - 9'd3;
end else begin
angle1 <= angle1;
end
其中4个angle对应每个舵机的要旋转的多少度,(了解机械臂的都知道我们应该要舵机旋转到多少度,其实我这样设计是因为我们工程中不止有ps2手柄对机械臂控制,大家要可以让其先复位然后就有个初始角度然后就可以得到最终的角度了。) angle1 2差不多 具体的加减要看对应的机械臂的对应角度。而角度3 4如下
// 处理angle3(对应Dat4的第5位和第7位)
if (Dat4[4] && angle3 < 9'd360) begin //按下△
angle3 <= angle3 + 9'd2;
end else if (Dat4[6] && angle3 > 9'd0) begin //按下□
angle3 <= angle3 - 9'd2;
end else begin
angle3 <= angle3;
end
有了角度去转化pwm波就很容易了 这个我也就不补啦,还有就是对于抓取部分的,可以把对应其在data的位置引出作为flag信号,来的的时候发送抓或松要的角度的pwm波就行啦。
总结
总体框架如下