Brushless

From Lofaro Lab Wiki
Revision as of 13:00, 3 May 2017 by Alafemina (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

About:

This code is designed to drive a brushless dc motor with 3 Hall Effect sensors using our custom h-bridge pcb. The commutation for this motor was determined from a tutorial on the Maxon motors website here: http://www.maxonmotorusa.com/maxon/view/content/maxon-Resources . There are 6 possible outputs from the Hall Effect sensors and each corresponds to two half bridges being turned on in a specific orientation. This allows current to travel in one direction through the coil. Warning: the traces on the pcb are only rated for 5.1 amps so check the motor datasheet to make sure it will not pull more than that when running.

Code:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity bldc_simple_toplevel is Port (
  clk : in  STD_LOGIC;
  reset : in  STD_LOGIC;
  ena : in std_logic;
  direction : in std_logic;
  duty : in  std_logic_vector(3 downto 0);
  hall : in std_logic_vector(2 downto 0);
  pwm_out : out std_logic_vector(2 downto 0);
  enable_out : out std_logic_vector(2 downto 0));
end bldc_simple_toplevel;

architecture Behavioral of bldc_simple_toplevel is

component BLDC_motor Port ( 
  clk      : in std_logic;
  ena      : in std_logic;
  reset      : in std_logic;
  compare      : in std_logic_vector(3 downto 0);
  deadband   : in std_logic_vector(3 downto 0);

  ena_at      : in std_logic;
  ena_ab      : in std_logic;
  ena_bt      : in std_logic;
  ena_bb      : in std_logic;
  ena_ct      : in std_logic;
  ena_cb      : in std_logic;

  pwm_at      : out std_logic;
  pwm_ab      : out std_logic;
  pwm_bt      : out std_logic;
  pwm_bb      : out std_logic;
  pwm_ct      : out std_logic;
  pwm_cb      : out std_logic
  );
end component;

component bldc_hall_decoder Port (
  clk      : in std_logic;
  reset      : in std_logic;
  hall_a      : in std_logic;
  hall_b      : in std_logic;
  hall_c      : in std_logic;
  reverse      : in std_logic;
  enable_at   : out std_logic;
  enable_ab   : out std_logic;
  enable_bt   : out std_logic;
  enable_bb   : out std_logic;
  enable_ct   : out std_logic;
  enable_cb   : out std_logic
  );
end component;

component pwm GENERIC(
  sys_clk         : INTEGER; --system clock frequency in Hz
  pwm_freq        : INTEGER;    --PWM switching frequency in Hz
  bits_resolution : INTEGER;          --bits of resolution setting the duty cycle
  phases          : INTEGER);         --number of output pwms and phases
PORT(
  clk       : IN  STD_LOGIC;                                    --system clock
  reset_n   : IN  STD_LOGIC;                                    --asynchronous reset
  ena       : IN  STD_LOGIC;                                    --latches in new duty cycle
  duty      : IN  STD_LOGIC_VECTOR(bits_resolution-1 DOWNTO 0); --duty cycle
  pwm_out   : OUT STD_LOGIC_VECTOR(phases-1 DOWNTO 0));          --pwm outputs
END component;

  signal pwm_n_out, pwm_out_1 : std_logic_vector(2 downto 0) := "000";-- hall,
  signal pwm_enable : std_logic := '0';

begin
  pwm1: pwm generic map(sys_clk => 500_000_000, pwm_freq => 50_000, bits_resolution => 4, phases => 1)
  port map(clk => clk, reset_n => reset, ena => ena, duty => duty, pwm_out(0) => pwm_enable);
  hall_reader: process(clk, hall, direction, reset)
  begin
     if (direction = '0') then
        case (hall) is 
           when "001" => 
              pwm_out_1 <= "010";
              enable_out <= "110";
           when "101" => 
              pwm_out_1 <= "010";
              enable_out <= "011";
           when "100" => 
              pwm_out_1 <= "001";
              enable_out <= "011";
           when "110" => 
              pwm_out_1 <= "001";
              enable_out <= "101";
           when "010" => 
              pwm_out_1 <= "100";
              enable_out <= "101";
           when "011" => 
              pwm_out_1 <= "100";
              enable_out <= "110";
           when others =>
              pwm_out_1 <= "000";
              enable_out <= "111";
        end case;
     else
        case (hall) is 
           when "001" => 
              pwm_out_1 <= "001";
              enable_out <= "101";
           when "101" => 
              pwm_out_1 <= "100";
              enable_out <= "101";
           when "100" => 
              pwm_out_1 <= "100";
              enable_out <= "110";
           when "110" => 
              pwm_out_1 <= "010";
              enable_out <= "110";
           when "010" => 
              pwm_out_1 <= "010";
              enable_out <= "011";
           when "011" => 
              pwm_out_1 <= "001";
              enable_out <= "011";
           when others =>
              pwm_out_1 <= "000";
              enable_out <= "111";
        end case;
     end if;
  end process;
  pwm_out <= pwm_out_1 and (pwm_enable&pwm_enable&pwm_enable);
end Behavioral;