Ortalama bir zaman aralığındaki alınan verilerin toplamının veri sayısına bölünmesi ile hesaplanır. Hareketli ortalama ise zaman aralığının sürekli kaydırılması ile hesaplanır. Yani normal ortalamada her
veride ortalama tekrar hesaplanırken, hareketli ortalamada en eski veri ortalamadan atılır ve yeni veri ortalamaya alınır.
hareketli ortalama,
ortalamaya girecek eleman sayısı ve
'de değerler olmak üzere, hareketli ortalama şu şekilde yazılabilir:

Bölme işlemi diğer işlemlere göre daha yavaş hesaplandığından dolayı, eleman sayısı
'nin kuvveti olarak seçilerek bölme işlemi bitsel kaydırma işlemine dönüştürülebilir.
Donanımsal tasarım aşağıdaki gibi gösterilebilir:
Tasarımı daha kolay anlaşılabilir hale getirmek için, tasarımı modüller sayesinde yapalım. Her bir modül aşağıdaki gibi olsun.
Bu modülün VHDL kodu aşağıdadır:
--Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; entity MovingAverageModule is generic(DataLength : integer := 12; --Veri uzunluğu SumLength : integer := 17); --Toplam verisinin uzunluğu port(Clk, Reset : in std_logic; --Clock ve reset girişi D : in std_logic_vector(DataLength - 1 downto 0); --Veri girişi Q : out std_logic_vector(DataLength - 1 downto 0); --Veri çıkışı SumIn : in std_logic_vector(SumLength - 1 downto 0); --Toplam verisi girişi SumOut : out std_logic_vector(SumLength - 1 downto 0)); --Toplam verisi çıkışı end MovingAverageModule; architecture Behavioral of MovingAverageModule is --Q sinyali signal QSignal : std_logic_vector(DataLength - 1 downto 0); begin --Flip-Flop processi process(Clk, Reset) begin --Eğer Reset sinyali '1' ise flip-flop'u resetle if Reset = '1' then QSignal <= (others => '0'); --Reset '1' değilse, clock sinyalinin yükselen kenarı ile --D sinyalindeki veriyi QSignal sinyaline ata elsif rising_edge(Clk) then QSignal <= D; end if; end process; --QSignal sinyalini Q sinyaline bağla Q <= QSignal; --SumIn ve QSignal sinyallerini topla ve SumOut sinyaline gönder SumOut <= std_logic_vector(unsigned(SumIn) + unsigned(QSignal)); end Behavioral;
Daha sonra bu modülü kullarak hareketli ortalamayı hesaplayan modülü tasarlayalım:
--Kütüphaneler library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; entity MovingAverage is generic(DataLength : integer := 12; --Veri uzunluğu SamplePower : integer := 5); --Ortalamaya girecek örnek sayısının kuvveti --Örnek sayısı = 2^SamplePower port(Clk, Reset : in std_logic; --Clock ve Reset girişi DataIn : in std_logic_vector(DataLength - 1 downto 0); --Ortalamaya girecek yeni veri Average : out std_logic_vector(DataLength - 1 downto 0)); --Ortalama çıkışı end MovingAverage; architecture Behavioral of MovingAverage is --Kayan ortalama modülünü çağır component MovingAverageModule generic(DataLength : integer := 12; --Veri uzunluğu SumLength : integer := 17); --Toplam verisinin uzunluğu port(Clk, Reset : in std_logic; --Clock ve reset girişi D : in std_logic_vector(DataLength - 1 downto 0); --Veri girişi Q : out std_logic_vector(DataLength - 1 downto 0); --Veri çıkışı SumIn : in std_logic_vector(SumLength - 1 downto 0); --Toplam verisi girişi SumOut : out std_logic_vector(SumLength - 1 downto 0)); --Toplam verisi çıkışı end component; --Verilerin taşınacağı sinyal dizisi type Data_Array is array (2**SamplePower downto 0) of std_logic_vector(DataLength - 1 downto 0); --Toplam verilerinin taşınacağı sinyal dizisi type Sum_Array is array (2**SamplePower downto 0) of std_logic_vector(DataLength + SamplePower - 1 downto 0); --Veri ve toplam verilerinin taşınacağı sinyaller signal DBus : Data_Array; signal SBus : Sum_Array; begin --Modullerin üretilmesi Modules : for i in 0 to 2**SamplePower - 1 generate Module : MovingAverageModule generic map(DataLength, DataLength + SamplePower) port map(Clk, Reset, DBus(i), DBus(i + 1), SBus(i), SBus(i + 1)); end generate; --DBus dizisinin ilk elemanına yeri veriler gönderilir DBus(0) <= DataIn; --SBus dizisinin ilk elemanına 0 gönderilir SBus(0) <= (others => '0'); --Bölme işlemi bitsel kaydırma ile hesaplanır --SBus dizisinin son elemanı SamplePower kadar sağa kaydırılır Average <= SBus(2**SamplePower)(DataLength + SamplePower - 1 downto SamplePower); end Behavioral;
Daha önce ADC128S022 entegresi ile ADC verilerini almıştık. Yazıya buradan ulaşabilirsiniz. Aldığımız verilerin hareketli ortalamasını bularak daha stabil değerler elde edebiliriz.
ADC + Hareketli Ortalama Uygulaması:
--Kütüphaneler
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
entity MovingAverageADC is
port(Clk, Reset : in std_logic; --Clock ve reset girişi
CS, SCLK, DIN : out std_logic; --ADC entegresinin SPI bağlantıları
DOUT : in std_logic; --ADC entegresinin SPI bağlantıları
LedOut : out std_logic_vector(11 downto 0)); --Led çıkışı
end MovingAverageADC;
architecture Behavioral of MovingAverageADC is
component MovingAverage
generic(DataLength : integer := 12; --Veri uzunluğu
SamplePower : integer := 5); --Ortalamaya girecek örnek sayısının kuvveti
--Örnek sayısı = 2^SamplePower
port(Clk, Reset : in std_logic; --Clock ve Reset girişi
DataIn : in std_logic_vector(DataLength - 1 downto 0); --Ortalamya girecek yeni veri
Average : out std_logic_vector(DataLength - 1 downto 0)); --Ortalama çıkışı
end component;
component ADC
port(Clk : in std_logic; --Clock Girişi
CS, SCLK, DIN : out std_logic; --ADC Entegresinin CS, SCLK ve DIN Girişleri
DOUT : in std_logic; --ADC Entegresinin DOUT Çıkışı
ADCOut : out std_logic_vector(11 downto 0)); --ADC'den okunan 12 bitlik sinyal
end component;
signal ADCOut : std_logic_vector(11 downto 0);
--Hareketli ortalama modülünün clock sinyali
signal ClkDiv : std_logic := '0';
begin
--Hareketli ortalama modülü için clock bölücü process.
--ADC modülün hızı yaklaşık 195ksps olduğundan
--clock bölücü ile 50Mhz'den 195khz elde edilir.
process(Clk)
variable ClkCnt : unsigned(7 downto 0) := (others => '0');
begin
if rising_edge(Clk) then
if ClkCnt < 127 then
ClkCnt := ClkCnt + 1;
else
ClkDiv <= not ClkDiv;
ClkCnt := (others => '0');
end if;
end if;
end process;
--ADC modülünün üretilmesi
ADCModule : ADC
port map(Clk, CS, SCLK, DIN, DOUT, ADCOut);
--Hareketli ortalama modülünün üretilmesi
--SamplePower = 5 -> 32 örneğin ortalaması alınıyor.
MovingAverageModule : MovingAverage
generic map(12, 5)
port map(ClkDiv, not Reset, ADCOut, LedOut);
end Behavioral;
Video:

aklıma bir şey takıldı aktifseniz sorabilir miyim .