Ещё один тахометр

Анатолий Сергиенко

Редкий радиолюбитель, владелец автомобиля, не полезет в него с паяльником. Вот и размножаются сотнями любительские схемы разных блоков зажигания, октан-корректоров, тахометров, зарядных устройств, охранной сигнализации. Некоторые идут дальше — и появляются бортовые компьютеры, телевизионные зеркала заднего обзора и даже устройства распознавания знаков дорожного движения.

В данной статье предлагается ещё один тахометр. Тахометр — это измеритель числа оборотов двигателя за единицу времени. Входные данные Fx поступают с датчика числа оборотов, которым чаще всего является прерыватель системы зажигания или емкостной датчик импульсов напряжения в свечных проводах. Результат измерения получают путем интегрирования импульсов одинаковой длительности в аналоговой схеме или простым подсчетом импульсов за единицу времени в частотомере.

Но частота Fx слишком низкая для измерения с точностью до 3-5 десятичных цифр в реальном масштабе времени. Измерение частоты на выходе генератора переменного тока бортовой сети не решает проблему кардинально. Кроме того, ещё необходима коррекция результата измерения путем умножения на масштабный коэффициент, т.е.Y=M*Fx. Выход в том, что необходимо измерять период Тх сигнала, а измеряемую величину находить как результат деления Y=M/Tx.

Для вычисления Y=M/Tx существует очень простой и удобный алгоритм. Если из большеразрядного целого М вычитать малоразрядное Тх до тех пор, пока М не приблизится к нулю, то число вычитаний будет равно искомому Y. При этом счетчик числа этих вычитаний можно выполнить по любому основанию, например, по основанию 2, 10, в кодах 7-сегментных индикаторов, в унитарном коде, т.е. коде бегущей единицы, в коде отображения столбика единиц и т.п.

Недостатком алгоритма является его высокая алгоритмическая сложность, т.е. то, что для получения 3-5 — разрядного десятичного результата необходимо выполнить до 1 -100 тыс. вычитаний и столько же сложений с единицей на одно измерение или 0.1 — 100 млн. операций в секунду, в зависимости от быстродействия измерений. Это довольно сложно для микроконтроллера, зато совсем нетрудно для ПЛИС и даже CPLD.

Здесь приводится простая модель тахометра. Модель представлена в Приложении. Тахометр работает периодически с последовательным повторением четырех фаз. В фазе Waiting ожидается фронт входного сигнала, в фазе Measure измеряется период сигнала Period как число тактов синхросерии между двумя соседними фронтами входного сигнала. При этом период меньше measureMIN не фиксируется, так как в нем могут быть импульсы дребезга контактов. В фазе Calculate вычисляется частота F= Masstab/Period . Эта частота F вычисляется в виде кода столбика единиц, который пригоден для непосредственного вывода на линейный светодиодный индикатор. В фазе Display ничего не происходит, кроме вывода результатов измерения.

Частота синхросерии равна 6,8 кГц. Она может быть подстроена выбором констант Masstab, measure_T, а также повышена при использовании дополнительного делителя частоты.

Такой тахометр помещается в любой корпус ПЛИС или CPLD . Он без особенной оптимизации занимает 125 LUT и 71 триггер. Так что весь прибор занимает один корпус CPLD XC9572 и генератор синхроимпульсов, не считая индикатора. Кстати, выходного тока ПЛИС или CPLD достаточно для прямого подключения светодиодов.

Если датчиком является прерыватель или емкостный датчик на проводе свечи зажигания, то на выходе такого датчика присутствуют высоковольтные импульсы. Хотя входы микросхемы защищены от высоковольтного низкотокового воздействия, следует вход микросхемы защитить от перенапряжения, например, резисторным делителем напряжения с диодным стабилизатором.

Приложение

--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
--  FILE: TAСHOMETER.VHD
--  PROJECT: VHDL_HOBBY
--  AUTHOR:       Anatoli Sergyienko
--  Created:            15/01/02
--  Email:        aser@comsys.kpi.ua
--
--  FUNCTION: - measuring and displaying the rotating
--             frequency of the car engine. 
--  ALGORITHM: 1. Period of the signal DATAI is
--                 measured in clocks
--             2. frequency is calculated
--                 as F= Masstab/Period
--             3. frequency is outputted through DATAO
--                to the barcode display
--  CONSTRAINTS: the barcode display length is limited
--     by Fmax,maximum period of the signal is measure_T;
--     display period is equal to Disp_T - Fmax.
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
library IEEE;
use IEEE.std_logic_1164.all;
entity Taсhometer is 
    generic( Fmax: integer:=32);
         -- Максимальная частота, 1 деление=200 об/мин
    port(CLK: in STD_LOGIC;
        RST: in STD_LOGIC;
        DATAI: in STD_LOGIC;
        DATAO: out STD_LOGIC_VECTOR (Fmax-1 downto 0));
end Taсhometer;

architecture Hobby of Taсhometer is
      constant measure_T: integer := 1024;
                         --Максимальный период сигнала,
                         --тактов, соответствует ~400об/мин
      constant measureMIN:integer := 68;
                            --Минимальный период сигнала,
                            --тактов=1024/15,
                            -- соответствует ~6000об/мин
    constant Disp_T: integer := 4093;
                            --Период отображения, тактов
    constant Masstab:integer := 1000;
                             --Масштабный коэффициент
    signal DATAId: STD_LOGIC;
    signal Calculate,Measure,Display, Waiting :boolean; --FSM states
    signal CT2:integer range 0 to Disp_T+3;
    signal Period: integer range 0 to measure_T;
    signal M: integer range 0 to measure_T-1;   
    signal F: STD_LOGIC_VECTOR(Fmax-1 downto 0); --F = Masstab/Period

begin
    --DATAI __/^^\___/^^\___/^^\___
    --DATAId __/^^\___/^^\___/^^\___
    --Measure__|^^^^^|_____________________
    --Calculate_________|^^^^^^|_____________
    --Display   __________________|^^^^^^^^^^^|____
    --Waiting  ^^|_______________________________|^^^^

    CNTRL:process(CLK,RST)
    begin                           
        if RST='1' then
            Calculate<=false;
            Measure<=false;
            Display<=false;                   
            Waiting<=true;
            CT2<= 0;
        elsif CLK='1' and CLK'event then
            DATAId<=DATAI;    --input delay
    -- finite state machine
      if ( DATAI='1' and DATAId='0' and Waiting ) then
                Measure<= true ;
                Waiting<= false;
      elsif ( DATAI='1' and DATAId='0'
            and Period>MeasureMIN ) then
                Measure<=false ;
                Calculate<=true;   
      elsif(CT2 = Disp_T) then
                Display<=false;
                Waiting<=true;
      elsif (CT2 = Fmax)then
                Calculate<=false;
                Display<=true;
      end if;
    --clock counter
            if ( calculate or display) then
                CT2<= CT2+1;
            elsif  Waiting then
                CT2<= 0;
            end if;
        end if;
    end process;

    CT_PERIOD:     process(CLK,RST)
                   --Счетчик периода вх.импульсов
    begin
        if RST='1' then
            Period<=0;
        elsif CLK='1' and CLK'event then
            if Measure then
                Period<=Period+1;
            elsif Waiting then
                Period<=0;
            end if;      
        end if;   
    end process;

    AU_FREQ:process(CLK,RST)
               --вычисление частоты и ее отображение
    begin
        if RST='1' then
            f<=(others=> '0');
            M<=Masstab;
        elsif CLK='1' and CLK'event then
            if  measure then
                M<=Masstab;
                f<=(others=> '0');
            elsif calculate then
                if ( M-Period >0 ) then
                    M<=M-Period ;
                    F<=F(F'left-1 downto 0) & '1';
                           --сдвиговый регистр- столбик
               end if;
           end if;
        end if;
    end process;
    DATAO<=F;
end Hobby;