Реферат: Текст программ на языке VHDL для калибровки цифрового трёхосного MEMS акселерометра

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Текст программ на языке VHDL для калибровки цифрового трёхосного MEMS акселерометра















Текст программ на языке VHDL для калибровки цифрового трёхосного MEMS акселерометра

Аннотация к программе

акселерометр калибровка цифровой программа

В документе представлены программы, необходимые для правильной работы устройства калибровки цифрового акселерометра и реализующие обмен данными по протоколу SPI между акселерометром и ПЛИС, а так же RS-232 для передачи данных с макета на ПЭВМ.

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

Программа разработана в среде Quartus II Software Version 9.0. Для ее функционирования требуется наличие на компьютере операционной системы Windows XP/Vista/7.

1. SPI-Master

-объявление пакета(собственной библиотеки)

package spi_pack isspi_states is (sleep, init, rw, iready, status); --iwait --ЦКАbyte is natural range 0 to 255;

--регистр управления режимами работы по мощности и частотой вывода данных(дискретизации)

Constant BW_RATE: byte := 44;

-регистр управления спящим режимом и частотой показаний в спящем режиме

Constant POWER_CTRL: byte := 45;

-регистр управления прерыванием

Constant INT_ENABLE: byte := 46;

-регистр управления логическим уровнем прерывания, выравниванием бит данных и разрядностью

Constant DATA_FORMAT: byte := 49;

-готовность передачи Status_REG: byte := 48;

-ускорение акселерометра по трем осям чувствительности

Constant DATA_X0: byte := 50;

Constant BW_RATE_WORD: byte := 10;--14;--12

--нормальный режим работы, режим измерения

Constant POWER_CTRL_WORD: byte := 8;

--прерывание разрешеноINT_ENABLE_WORD: byte := 128;

--диапазон измеряемых ускорений - ±4g, выравнивание бит - по левому краю, 11 разрядов

Constant DATA_FORMAT_WORD: byte := 13;

--кол-во инициализируемых регистров

Constant all_init_regs: byte := 4;

-кол-во читаемых регистров(по 2 байта на каждую ось чувствительности)

Constant all_read_regs: byte := 6;gyro_regs is array (0 to all_init_regs-1) of byte;init_addreses: gyro_regs := (BW_RATE, POWER_CTRL, INT_ENABLE,DATA_FORMAT);ctrl_data: gyro_regs := (BW_RATE_WORD, POWER_CTRL_WORD, INT_ENABLE_WORD, DATA_FORMAT_WORD);

--количество тактовых импульсов(частота дискретизации)1МГЦ/100Гц

Constant Discrete: natural range 0 to 16_383 := 10_000;--1_000_000/625 ;--10_000 -- 2500spi_pack;

-объявление библиотекieee;ieee.std_logic_1164.all;ieee.std_logic_arith.all;ieee.std_logic_unsigned.all;work.spi_pack.all;spi_core is

(

--сигнал разрешения передачи данных (передача по низкому логическому уровню)

cs: out std_logic;

-тактовый сигнал: out std_logic;

--выходной сигнал SPI для подачи на вход акселерометра

sdi: out std_logic;

-входящий высокочастотный сигнал

-входной сигнал SPI для чтения данных с выхода SDO акселерометра

sdo: in std_logic;

-биты данных для одной оси чувчтвительности

data_out: out std_logic_vector(15 downto 0);

-выход передачи UART: out std_logic;

-вход приема UART: in std_logic

);spi_core;Behavior of spi_core is

--делитель

Component divider is

-настроечная константа

generic (N : natural := 8);

(

-тактовый сигнал: in std_logic;

-сигнал сброса: in std_logic;

-сигналы установки и чтения по разным фронтам

clk_out: out std_LOGIC;_scl: out std_LOGIC

);Component;

-передатчикtx_uart is

(

-скорость передачи

-частота дискретизации

Fd: natural := 100;

-кол-во передаваемых байт по умолчанию

n_bytes: natural := 6

);

port

(

-тактовый высокочастотный сигнал

clock : in std_logic;

-сигнал сброса : in std_logic;

-массив бит входных данных длиной 8*кол-во байт

data_tx: in std_logic_vector(8*n_bytes - 1 downto 0);

-выход UART: out std_LOGIC

);Component;gyro_reads is array (0 to all_read_regs-1) of std_logic_vector(7 downto 0);new_data, new_data_temp, init_ready, rst: std_logic;clk, clk_for_scl, scl_ena: std_logic;wd: std_logic;n_bit: natural range 0 to 8*(all_read_regs + 1) -1;num_init: natural range 0 to all_init_regs;num_read: natural range 0 to all_read_regs;D_out: gyro_reads;ready: std_logic;data_tx: std_logic_vector(8*all_read_regs - 1 downto 0);cnt: std_logic;state, next_state: spi_states;_freq: divider generic map (N => 24) port map (clock, '1', clk, clk_for_scl);(state, wd, init_ready, n_bit, new_data, num_read)(state) issleep => if (init_ready = '0') then next_state <= init;(wd = '1') then next_state <= status;(new_data = '1') then next_state <= rw;next_state <= sleep;if;init => if (n_bit = 15)next_state <= sleep;next_state <= init;if;status => if (n_bit = 15)next_state <= sleep;next_state <= status;if;rw => if (n_bit = (8*(all_read_regs + 1) -1))next_state <= iready;next_state <= rw;if;iready => next_state <= sleep;others => null;case;process;(clk, cnt)(cnt = '0') then n_bit <= 0;(clk'event and clk = '0') then_bit <= n_bit + 1;if;process;(clk)cycle: natural range 0 to Discrete;(clk'event and clk = '0') then<= next_state;cycle = 0wd <= '1';wd <= '0';if;cycle = Discrete - 1cycle := 0; cycle := cycle + 1;if;if;process; (clock, state, n_bit, num_init, num_read)cycle: natural range 0 to Discrete;data: std_logic_vector(15 downto 0); (clock'event and clock = '1') then(state) issleep => sdi <= '0';<= '1';_ena <= '0';<= '0'; init => cs <= '0';_ena <= '1'; := "00" & conv_std_logic_vector(init_addreses(num_init), 6) & conv_std_logic_vector(ctrl_data(num_init), 8);<= data(15 - n_bit);<= '1';status => cs <= '0';_ena <= '1';:= "10" & conv_std_logic_vector(Status_REG, 6) & "11111111";<= data(15 - n_bit);<= '1';rw => cs <= '0';_ena <= '1';:= "11" & conv_std_logic_vector(DATA_X0, 6) & "11111111";(n_bit < 16) then<= data(15 - n_bit);<= '1';if;<= '1';iready => cs <= '1';_ena <= '0';<= '0';<= '0';others => null;case;if;process; (clk, state, n_bit, new_data)data: gyro_reads;(clk'event and clk = '0') then(state) issleep => num_read <= 0;init => if (n_bit = 15) then(num_init = all_init_regs - 1)init_ready <= '1';init_ready <= '0';_init <= num_init + 1;if;if;status => if (n_bit = 8)new_data <= sdo;if;rw => if (n_bit > 7)data(num_read)(7 - (n_bit rem 8)) := sdo;(n_bit rem 8 = 7)num_read <= num_read + 1;if;if;iready => data_out <= data(1) & data(0);_data <= '0';_tx <= data(1) & data(0) & data(3) & data(2) & data(5) & data(4);others => null;case;if; process;<= '1' when scl_ena = '0' else clk_for_scl;_UART_Tx: tx_uart generic map (Rapid => 460_800,=> 100,_bytes => all_read_regs)map

(=> clock,=> not rx,_tx => data_tx,=> tx

);

end Behavior;

. Параметрический делитель частоты с асинхронным сбросом

library IEEE;IEEE.std_logic_1164.all;IEEE.std_logic_arith.all;IEEE.std_logic_unsigned.all;divider is(N : natural);

( : in std_logic;: in std_logic;

);divider;behavior of divider is(clk, reset)cnt: natural := 0;(reset = '0') then:= 0; clk_out <= '0'; clk_scl <= '0'; (clk'event and clk = '1') thencnt is0 => clk_out <= '0'; clk_scl <= '1';N/2 => clk_out <= '1'; clk_scl <= '0';others => null;case;cnt = N -1 then cnt := 0;cnt := cnt + 1;if;if;process;behavior;

1.3 Передатчик UART

package UART_settings isFreq: natural := 24_000_000;package;IEEE;IEEE.std_logic_1164.all;IEEE.std_logic_arith.all;IEEE.std_logic_unsigned.all;work.UART_settings.all;tx_uart is

(: natural := 115_200;: natural := 100;_bytes: natural := 6

-parity: parity_bit := no

);

(: in std_logic;_tx: in std_logic_vector(8*n_bytes - 1 downto 0);: out std_LOGIC

);tx_uart;Behavior of tx_uart isdivider is(N : natural);

( : in std_logic;: in std_logic;_out: out std_LOGIC

);component;Discr: natural := Rapid/Fd;UART_states is (sleep, start, dtx, stop);state, next_state: UART_states := sleep;clk: std_logic;counter: natural range 0 to 15;cnt: std_logic;period: std_logic;sent: std_logic;num: natural range 0 to n_bytes;: divider generic map (N => Freq/Rapid) port map (clock, '1', clk);(clock, state, num)data: std_logic_vector(8*n_bytes - 1 downto 0);(clock'event and clock = '1') then(state) is(sleep) => tx <= '1';<= '0';<= '0';start=> tx <= '0';<= '0';<= '0';(num = 0)data := data_tx;if;stop => tx <= '1';<= '0';<= '1';dtx => cnt <= '1';<= '0';counter /=8 then <= data(8*(n_bytes - num) - 8 + counter);tx <= data(8*(n_bytes - num) - 1) xor data(8*(n_bytes - num) - 2) xor(8*(n_bytes - num) - 3) xor data(8*(n_bytes - num) - 4) xor(8*(n_bytes - num) - 5) xor data(8*(n_bytes - num) - 6) xor(8*(n_bytes - num) - 7) xor data(8*(n_bytes - num) - 8) xor '1';if;others => null;case;if;process;(state, num, counter, period)(state) is(sleep) => if period = '1' then next_state <= start;next_state <= sleep;if;start=> next_state <= dtx;stop => if (num = n_bytes) then_state <= sleep;_state <= start;if;dtx =>if (counter) = 7 then --no

-if (counter) = 8 then -- even or odd_state <= stop;next_state <= dtx;if;others => null;case;process;(clk, cnt)(cnt = '0') then counter <= 0;(clk'event and clk = '0') then<= counter + 1;if;process;(sent, period) (period = '1') then num <= 0;(sent'event and sent = '1') thennum = n_bytes then<= 0;<= num + 1;if;if;process; (clk)cycle: natural range 0 to Discr;(clk'event and clk = '0') then<= next_state;cycle = 0period <= '1';period <= '0';if;cycle = Discr - 1cycle := 0; cycle := cycle + 1;if;if;process; Behavior;

Источник: https://www.bibliofond.ru/detail.aspx?id=897126