I'm trying to make a servo work on my Spartan-6 based FPGA.
my code is as follows:
`timescale 1ns / 1ps
/*
1 pin for servo--ORANGE CABLE
red cable-- 5V, brown cable-- GND.
Position "0" (1.5 ms pulse) is middle,
"90" (~2ms pulse) is all the way to the right,
"-90" (~1 ms pulse) is all the way to the left.
servo stuff:
http://www.micropik.com/PDF/SG90Servo.pdf
*/
//All i need to do is set SERVOPWM to 1 and 0 with delays i think
module ServoTestNShit(input M_CLOCK,
output [7:0] IO_LED, // IO Board LEDs
output reg SERVOPWM);
assign IO_LED = 7'b1010101; // stagger led lights just cause
reg [15:0] counter;
//use counter to have a 1ms or 2ms or 1.5ms duty cycle for a while inorder to actually run
//because run it this way is asking the servo to move for 1.5ms so it cant atually move that fast
always @*
begin
for(counter = 0; counter < 3000; counter = counter + 1)
begin
SERVOPWM = 1;
#2;
SERVOPWM = 0;
#2;
SERVOPWM = 1;
#2;
SERVOPWM = 0;
#2;
SERVOPWM = 1;
#2;
SERVOPWM = 0;
#2;
end
for(counter = 0; counter < 3000; counter = counter + 1)
begin
SERVOPWM = 1;
#1;
SERVOPWM = 0;
#2;
SERVOPWM = 1;
#1;
SERVOPWM = 0;
#2;
SERVOPWM = 1;
#1;
SERVOPWM = 0;
#2;
end
end
endmodule
and my ucf file is pretty much just:
# Clock signal
NET "M_CLOCK" LOC = P123;
NET "SERVOPWM" LOC = P121 ;//0P1
So in my head, my code will be creating a pulse wave first all the way to the right, by setting high for 2ms, then low, then high for 2ms, etc and repeating. Then, all the way to the left with high for 1ms, etc. I thought this problem would be relatively simple, as all I'm doing is sending a 1 or a 0 to an IO pin and I have my servo hooked to 5v, ground, and the IO pin in question.
Is there something stupid/obvious/easy that I'm missing? Or is there some part of the concept I'm missing?
Thanks for any help in advance! Cody
Delay (#) statements are not synthesized in verilog. This way it will output only the final value. You should synchronize your outputs with clock.
The way I would do is
always @ (posedge clk)
begin
counter <= counter+1;
end
always @ (negedge clk)
begin
SERVOPWM <= (counter <= pwm_value);
end