Icedevil777

КИХ Фильтр на ПЛИС

6 posts in this topic

Icedevil777    1

Здравствуйте, У меня есть плата HELPER LMD-System c АЦП, ЦАП(в виде шим фильтра), cyclon 3.

Я новичок в этом деле делаю первый серьезный проект. Цель проекта научиться рассчитывать и создавать цифровые фильтры, а так же работать с ними.
Мой проект состоит из: Генератора синусоиды, с регулятором частоты(от 200Гц до 5кГц), состоит из счетчиков, которые подают меняющийся по кругу  двоичный код на ШИМ, а он создает аналоговый сигнал - синусоиду в положительной области. Далее Аналоговый сигнал поступает на вход АЦП-12 бит, снова преобразуется в двоичный код, затем поступает на ЦАП (2й канал ШИМ фильтра). Моя задача поставить фильтр между АЦП и ЦАП, который будет, например пропускать частоты ниже 1кГц, а все что выше задавливать.

Суть проблемы: когда я рассчитываю ких фильтр, в матлабе, фиркомпиллере, либо на сайтах онлайн, мне выдают коэффициенты типа:
-41
-120
-125
-22
105
68
-116
-175
130
637
890
637
130
-175
-116
68
105
-22
-125
-120
-41

Они отрицательные! У меня АЦП выдает только прямой код, ЦАП, так же понимает только положительный код! У меня одна идея в голове прибавить к этой последовательности цифр 175, чтобы самое маленькое отрицательное превратить в 0! Когда я это сделал мой фильтр начал задавливать в 0 вообще все частоты, почему? может мой подход не верный? если у кого-нибудь есть готовый, рабочий фильтр 12 бит на VHDL, поделитесь, для изучения.
 Вот код моего фильтра, c другими коэффицентами на них ненужно смотреть:

library Ieee;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_Arith.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Mfil is
Port ( clk: in std_logic;
adc: in std_logic_vector(11 downto 0);
f_out: out std_logic_vector(11 downto 0));
end Mfil;
architecture Behavioral of Mfil is
signal r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31, r32, r33: std_logic_vector(11 downto 0);
signal k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30, k31, k32, k33, k34: std_logic_vector(11 downto 0);
signal p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34: std_logic_vector(26 downto 0);
signal pl0, pl1, pl2, pl3, pl4, pl5, pl6, pl7, pl8, pl9, pl10, pl11, pl12, pl13, pl14, pl15, pl16, pl17, pl18, pl19, pl20, pl21, pl22, pl23, pl24, pl25, pl26, pl27, pl28, pl29, pl30, pl31, pl32, pl33, pl34: std_logic_vector(23 downto 0);
signal sum: std_logic_vector(26 downto 0);
begin
k0    <=    conv_std_logic_vector(45,12);
k1    <=    conv_std_logic_vector(29,12);
k2    <=    conv_std_logic_vector(0,12);
k3    <=    conv_std_logic_vector(-34,12);
k4    <=    conv_std_logic_vector(-59,12);
k5    <=    conv_std_logic_vector(-64,12);
k6    <=    conv_std_logic_vector(-43,12);
k7    <=    conv_std_logic_vector(0,12);
k8    <=    conv_std_logic_vector(53,12);
k9    <=    conv_std_logic_vector(96,12);
k10    <=    conv_std_logic_vector(110,12);
k11    <=    conv_std_logic_vector(79,12);
k12    <=    conv_std_logic_vector(0,12);
k13    <=    conv_std_logic_vector(-119,12);
k14    <=    conv_std_logic_vector(-258,12);
k15    <=    conv_std_logic_vector(-387,12);
k16    <=    conv_std_logic_vector(-478,12);
k17    <=    conv_std_logic_vector(2047,12);
k18    <=    conv_std_logic_vector(-478,12);
k19    <=    conv_std_logic_vector(-387,12);
k20    <=    conv_std_logic_vector(-258,12);
k21    <=    conv_std_logic_vector(-119,12);
k22    <=    conv_std_logic_vector(0,12);
k23    <=    conv_std_logic_vector(79,12);
k24    <=    conv_std_logic_vector(110,12);
k25    <=    conv_std_logic_vector(96,12);
k26    <=    conv_std_logic_vector(53,12);
k27    <=    conv_std_logic_vector(0,12);
k28    <=    conv_std_logic_vector(-43,12);
k29    <=    conv_std_logic_vector(-64,12);
k30    <=    conv_std_logic_vector(-59,12);
k31    <=    conv_std_logic_vector(-34,12);
k32    <=    conv_std_logic_vector(0,12);
k33    <=    conv_std_logic_vector(29,12);
k34    <=    conv_std_logic_vector(45,12);


process (clk)
begin
if clk'event and clk = '1' then
r0 <= adc;
r1    <=    r0    ;
r2    <=    r1    ;
r3    <=    r2    ;
r4    <=    r3    ;
r5    <=    r4    ;
r6    <=    r5    ;
r7    <=    r6    ;
r8    <=    r7    ;
r9    <=    r8    ;
r10    <=    r9    ;
r11    <=    r10    ;
r12    <=    r11    ;
r13    <=    r12    ;
r14    <=    r13    ;
r15    <=    r14    ;
r16    <=    r15    ;
r17    <=    r16    ;
r18    <=    r17    ;
r19    <=    r18    ;
r20    <=    r19    ;
r21    <=    r20    ;
r22    <=    r21    ;
r23    <=    r22    ;
r24    <=    r23    ;
r25    <=    r24    ;
r26    <=    r25    ;
r27    <=    r26    ;
r28    <=    r27    ;
r29    <=    r28    ;
r30    <=    r29    ;
r31    <=    r30    ;
r32    <=    r31    ;
r33    <=    r32    ;

sum(26 downto 0) <=  p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23 + p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31 + p32 + p33 + p34 ;


end if;
end process;


p0    <=    "000" &    pl0    ;
p1    <=    "000" &    pl1    ;
p2    <=    "000" &    pl2    ;
p3    <=    "000" &    pl3    ;
p4    <=    "000" &    pl4    ;
p5    <=    "000" &    pl5    ;
p6    <=    "000" &    pl6    ;
p7    <=    "000" &    pl7    ;
p8    <=    "000" &    pl8    ;
p9    <=    "000" &    pl9    ;
p10    <=    "000" &    pl10    ;
p11    <=    "000" &    pl11    ;
p12    <=    "000" &    pl12    ;
p13    <=    "000" &    pl13    ;
p14    <=    "000" &    pl14    ;
p15    <=    "000" &    pl15    ;
p16    <=    "000" &    pl16    ;
p17    <=    "000" &    pl17    ;
p18    <=    "000" &    pl18    ;
p19    <=    "000" &    pl19    ;
p20    <=    "000" &    pl20    ;
p21    <=    "000" &    pl21    ;
p22    <=    "000" &    pl22    ;
p23    <=    "000" &    pl23    ;
p24    <=    "000" &    pl24    ;
p25    <=    "000" &    pl25    ;
p26    <=    "000" &    pl26    ;
p27    <=    "000" &    pl27    ;
p28    <=    "000" &    pl28    ;
p29    <=    "000" &    pl29    ;
p30    <=    "000" &    pl30    ;
p31    <=    "000" &    pl31    ;
p32    <=    "000" &    pl32    ;
p33    <=    "000" &    pl33    ;
p34    <=    "000" &    pl34    ;

pl1    <=    r0    * k1    ;
pl2    <=    r1    * k2    ;
pl3    <=    r2    * k3    ;
pl4    <=    r3    * k4    ;
pl5    <=    r4    * k5    ;
pl6    <=    r5    * k6    ;
pl7    <=    r6    * k7    ;
pl8    <=    r7    * k8    ;
pl9    <=    r8    * k9    ;
pl10    <=    r9    * k10    ;
pl11    <=    r10    * k11    ;
pl12    <=    r11    * k12    ;
pl13    <=    r12    * k13    ;
pl14    <=    r13    * k14    ;
pl15    <=    r14    * k15    ;
pl16    <=    r15    * k16    ;
pl17    <=    r16    * k17    ;
pl18    <=    r17    * k18    ;
pl19    <=    r18    * k19    ;
pl20    <=    r19    * k20    ;
pl21    <=    r20    * k21    ;
pl22    <=    r21    * k22    ;
pl23    <=    r22    * k23    ;
pl24    <=    r23    * k24    ;
pl25    <=    r24    * k25    ;
pl26    <=    r25    * k26    ;
pl27    <=    r26    * k27    ;
pl28    <=    r27    * k28    ;
pl29    <=    r28    * k29    ;
pl30    <=    r29    * k30    ;
pl31    <=    r30    * k31    ;
pl32    <=    r31    * k32    ;
pl33    <=    r32    * k33    ;
pl34    <=    r33    * k34    ;


f_out(11 downto 0) <= sum (26 downto 15) + "000111011110" ;
end architecture;
[/HTML]

 

Может у меня сам фильтр не правильно сделан? или разрядность sum после сложения нужно увеличить?

Share this post


Link to post
Share on other sites
TDA    14
12 минуты назад, Icedevil777 сказал:

У меня одна идея в голове прибавить к этой последовательности цифр 175, чтобы самое маленькое отрицательное превратить в 0!

Не надо так делать:) фильтр станет совсем другим. Значения АЦП допустим беззнаковые приходят и ползут по линии задержки, но операции умножения на коэффициенты уже знаковые, разрядность результата = Разрядность АЦП + разрядность коэффициентов + знак. Суммирование то же должно быть знаковое. Лучше привести все арифметике с целыми байтами 2 байта значения АЦП, 4 байта результат умножения, 4 байта результат суммирования и далее урезаем лишнее для выхода на ЦАП.

Share this post


Link to post
Share on other sites
Icedevil777    1
Только что, TDA сказал:

Не надо так делать:) фильтр станет совсем другим. Значения АЦП допустим беззнаковые приходят и ползут по линии задержки, но операции умножения на коэффициенты уже знаковые, разрядность результата = Разрядность АЦП + разрядность коэффициентов + знак. Суммирование то же должно быть знаковое. Лучше привести все арифметике с целыми байтами 2 байта значения АЦП, 4 байта результат умножения, 4 байта результат суммирования и далее урезаем лишнее для выхода на ЦАП.

А ЦАП только прямой код понимает, как я фильтрованный сигнал превращу в аналоговый вид? Вот как выглядит ЦАП ШИМ фильтр + прога в ПЛИС.

image.png.0714d5608f431e94511c60de7467e666.png

 

Если на шим приходит все 11111 до это Umax, если 0 то Umin.  Если только научить этот шим понимать отрицательные числа...... но как?

 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity shim is 
port 
( 
clk : in std_logic; 
r: in integer range 0 to 16383 ; 
q : out integer range 0 to 16383 

); 
end entity; 

architecture rtl of shim is 
begin 
process (clk) 
variable cnt : integer range 0 to 16383; 
begin 
if (rising_edge(clk)) then 
cnt := cnt + 1; 
end if; 
if (cnt < r) then q <= 1; 
else q <= 0; 
end if; 
end process; 
end rtl;

 

Share this post


Link to post
Share on other sites

Старт складской программы по Wi-Fi/ Bluetooth-чипам от Espressif

На склад КОМПЭЛ поступили чипы, модули и отладочные платы от компании Espressif Systems на базе ESP8266 и ESP32. Стоимость всех изделий данной линейки – в 2-3 раза ниже ближайших аналогов, чипы занимают минимальное место на плате, энергоэффективны и универсальны в применении

Подробнее...

Vascom    660

Просто переведи числа с твоего АЦП из прямого кода в двоичный дополнительный. И затем результат фильтрации можешь обратно в прямой код перевести для вывода на ЦАП.

Share this post


Link to post
Share on other sites
Icedevil777    1
49 минут назад, Vascom сказал:

Просто переведи числа с твоего АЦП из прямого кода в двоичный дополнительный. И затем результат фильтрации можешь обратно в прямой код перевести для вывода на ЦАП.

Отсюда вытекает два вопроса, каким способом лучше  и проще перевести и если такая запись имеет место быть: k17    <=    conv_std_logic_vector(2047,12); САПР понимает что это прямой код или дополнительный ?

Share this post


Link to post
Share on other sites

Вебинар Литиевые ХИТы FANSO или что нужно знать инженеру о батарейках»

20 июня компания Компэл приглашает всех желающих принять участие в вебинаре, посвященном литиевым батарейкам FANSO. На вебинаре будет рассказано о параметрах батареек, их зависимости от режима работы и эксплуатации. Будет дана информация о том, на какие параметры следует обращать внимание, выбирая литиевый ХИТ, и как избежать некоторых проблем.

Подробнее...

TDA    14
6 часов назад, Icedevil777 сказал:

А ЦАП только прямой код понимает, как я фильтрованный сигнал превращу в аналоговый вид? Вот как выглядит ЦАП ШИМ фильтр + прога в ПЛИС.

p0    <=    "000" &    pl0 ;  Что это за костыль?

f_out(11 downto 0) <= sum (26 downto 15) + "000111011110" ;  что это?

надо написать что-то типа:

pl0 <= (signed(r0)*signed(k0));
...
sum <= (signed(pl0)+signed(pl1) ... ;
fout <= unsigned(sum(26 downto 15)); 

И с разрядностью все равно разбираться надо. Подробнее читайте здесь 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Сообщения

    • ты туповат. Диоды переключают ток и если одного диода нет тогда катушка оказывается по вч закорочена с цепочкой автосмещения и ничего работать не будет. Еще "умные" советы есть?   Разваливается твой "умный" совет и только! Тренироваться надо не мне а тем у кого диоды  проводят   ток в оба направления под автосмещением!  бугг..! Нет, тема эта тухлая. Судя по состоянию мозгов даже понять не могут как это работает а уж купить... нет, купят кетайский ширпотреб. техномусор.  Ничо! У Николы Тесла тоже не покупали а теперь волосы на жопе рвут! Когда ты уже перестанешь болтать и нести чепуху как блондинка?
    • В даташите всё есть, изучайте...
    • Специально для школьников. Смотри внимательно
    • Тебе уже не раз говорили, что свои проблемы не надо сваливать на чужие головы   Не удивительно. Ты же не слышал о таком понятии как автоматическое смещение.  Так что сиди и учи матчасть. И осциллограммы выкладывай!
    • Тогда что-то подобное: Подстроечником RV1 устанавливается порог срабатывания на мигание. По крайней мере симулятор в этой схеме мигает при 4 Вольтах, при 5-ти - светодиод просто горит. LED_blinked.pdsprj
    • Колеги,друзья,славчне,всем рекомендую на Ютубе посмотреть документальный фильм ДОМ
    • Ваши проблемы обширны  и так. бугг.. бугг!  Смещение, батенька, делается постоянным током черед диод детектора, задается начальный ток. А то что диод может открываться амптитудой импульсов без смещения это нам и так известно, брателло!  Но чтобы амплдитуда была сама себе еще и смещением такого нет и быть не может. На диод приходят не только открывающие полуволны но и запирающие. Ты тут сомневаешься что диод работает импульсно, брателло, ты меня уже начал смешить потому и бугг... в ней перемножительный квадратурный детектор. Поганого качества кстати.   это гистерезис по входу, брателло! Кого ты хочешь провести? Это микросхема такая. Еще один псих. бугг... И они у тебя проводят в оба направления? Работа цепочки автосмещения однозначно показывает что образуется баланс фаз и амплитуд и ток идет только в одну сторону. Плохо школа работала...