Monday, January 10, 2011

Servo Driver with Altera Max II CPLD

If you don't do CPLD design often, working with Quartus II is a pain in the rear. It doesn't run natively on Ubuntu and my old PC running Win XP didn't have enough memory to install (Quartus II installer is 3GB and uncompresses itself into your temp dir @ 4 GB and the final installation is 5GB so you are talking 12 GB of free space required. My old lap top HD was 16 GB total...) Also you will probably want model sim if you are going to do any synthesizing.

My goal was to drive a servo from the CPLD using VHDL. I've attached the project and source in case anyone else is pulling their hair out looking for a simple tutorial to work with their new design board. This is all assuming you are using the 50 MHz clock on the dev board with the Max II.

Good Luck!



VHDL Code for PWM output


20 ms signal generator output tck should be routed to the servo drive tck input.

20 ms signal generator


-- Generated by Quartus II Version 10.1 (Build Build 153 11/29/2010)
-- Created on Sun Jan 09 00:51:34 2011
LIBRARY ieee;
USE ieee.std_logic_1164.all;


-- Entity Declaration

ENTITY freq_div IS
-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
PORT
(
clk : IN STD_LOGIC;
tck : OUT STD_LOGIC
);
-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!

END freq_div;


-- Architecture Body

ARCHITECTURE freq_div_architecture OF freq_div IS
signal count : INTEGER := 0;
signal x : STD_LOGIC := '0';

BEGIN
process(clk)
begin
if (clk'event and clk = '1') then
tck <= x;
if (count = 1000000) then -- convert 20 ns clk to 20 ms tcks
x <= '1';
count <= 0;
else
x <= '0';
count <= count + 1;
end if;
end if;
end process;
END freq_div_architecture;


Servo Driver


-- Generated by Quartus II Version 10.1 (Build Build 153 11/29/2010)
-- Created on Sun Jan 09 20:59:28 2011

LIBRARY ieee;
USE ieee.std_logic_1164.all;


-- Entity Declaration

ENTITY servo_driver IS
-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
PORT
(
clk : IN STD_LOGIC;
tck : IN STD_LOGIC;
en : IN STD_LOGIC;
pwm : OUT STD_LOGIC
);
-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!

END servo_driver;


-- Architecture Body

ARCHITECTURE servo_driver_architecture OF servo_driver IS
signal count : INTEGER := 0;
signal pos : STD_LOGIC := '0'; -- servo position 0 or 90 deg.
signal x, y : STD_LOGIC := '0';

BEGIN
process(clk, tck)
begin
if (clk'event and clk = '1') then
if (tck = '1') then
x <= '1';
pos <= en;
end if;

pwm <= x;
if (x = '1') then
count <= count + 1;
else
count <= 0;
end if;
-- count = 50000; convert 20ns to 2ms = 90 deg.
-- count = 100000; convert 20ns to 1ms = 0 deg.
if ((pos = '1' and count = 50000) or (pos = '0' and count = 100000)) then
x <= '0';
end if;
end if;
end process;
END servo_driver_architecture;

No comments: