Forum: FPGA, VHDL & Co. Noise Filter für UART?


von Michael F. (mifi)


Lesenswert?

Hallo zusammen,

die genauen Eigenschaften des Filters kann ich leider nicht beschreiben, 
nur die Umgebung für die er benutzt werden soll.

Für eine RS485 UART Übertragung (8,N,1) mit 2MBit wollte ich evt. 
Störungen am Empfänger filtern. Hierfür wird für die Synchronisation 
natürlich das Signal erst einmal über zwei FFs geführt. Danach soll 
folgender "Filter" eingesetzt werden:
1
   signal noise_sr : std_logic_vector(2 downto 0)  := (others => '0');
2
   signal rxd      : std_logic := '0'; 
3
4
5
   process (clk_i)
6
   begin
7
      if rising_edge(clk_i) then
8
      
9
         if (rxd_i = '1') then
10
            noise_sr <= noise_sr(1 downto 0) & '1';
11
         end if;   
12
         
13
         if (rxd_i = '0') then
14
            noise_sr <= '0' & noise_sr(2 downto 1);
15
         end if;   
16
         
17
         if (noise_sr = "000") then
18
            rxd <= '0';
19
         end if;   
20
         
21
         if (noise_sr = "111") then
22
            rxd <= '1';
23
         end if;   
24
         
25
      end if;
26
   end process;

clk_i beträgt hier 96MHz. rxd_i ist das synchronisierte Signal und rxd 
das Signal nach dem Filter. Ist das Signal (rxd_i) 1 so wird diese von 
rechts in den Filter geschoben. Bei einer 0 wird diese von links 
geschoben. Steht der Filter auf 0 ist der Ausgang auch 0, entsprechend 
gilt dies für die 1. Ich meine das dies eine gleitende Mittelwertbildung 
ist.

Als Alternative könnte man auch eine 2 aus 3 Auswahl umsetzen.

Das rxd Signal soll später 16 fach abgetastet werden, und die Mitte (#8) 
gibt dann den Wert für das entsprechende Bit an.

Wie ist nach Eurer Erfahrung hier das richtige Vorgehen?

Viele Grüße,
Michael

von TestX (Gast)


Lesenswert?

Wieso nimmst du nicht einen klassischen Ansatz wie einen TP Filter ?

Was du da machst ist ziemlicher Murks... wenn du das Signal "abtasten" 
willst solltest du es auch analog sampeln..überleg dir mal wieviel sinn 
es macht hier nur digital eine Art "Mittelwert" zu bilden..

von Michael F. (mifi)


Lesenswert?

Wie meinst Du das mit "solltest du es auch analog sampeln"? Ich glaube 
nicht das es eine gute Idee wäre einen echten TP vor den RS485 
Transceiver zu setzen.

von TestX (Gast)


Lesenswert?

Such mal nach "slew rate" in zusammenhang mit rs485 oder auch can 
transceivern.

von A. S. (Gast)


Lesenswert?

Michael F. schrieb:
> die Mitte (#8)gibt

warum wertest Du denn dann nicht genau die Signale dort aus? Also die 
Mehrheit aus #7,#8 und #9

Wenn alle 3 gleich sind, ... OK gut.
Wenn einer anders ist (33%), dann ist Dein Signal doch so verrauscht, 
dass die Startflanke und die Auswertung des Rests nur geraten ist. Der 
Gewinn durch bessere Digitalverarbeitung ist dann vernachlässigbar.

von Michael F. (mifi)


Lesenswert?

Hallo Achim

das mit der #7,#8 und #9 habe ich mir auch schon überlegt. Und die Frage
ist ob das Vergleichbar ist mit einer 2 aus 3 Auswahl wenn dies schon 
mit dem Signal selbst gemacht wird.

Gruß,
Michael

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Um eine Taste zu entprellen habe ich mal das hier geschrieben:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
5
entity Pin_debounce is
6
  Port (  CLK  : in STD_LOGIC;
7
    PIN_in  : in STD_LOGIC;
8
    PIN_out : out STD_LOGIC);
9
end Pin_debounce;
10
11
architecture Verhalten of Pin_debounce is
12
13
signal wert: unsigned(3 downto 0);
14
15
begin
16
17
process
18
  begin
19
  wait until rising_edge(CLK);
20
  
21
  if PIN_in = '1' then
22
    if wert < 15 then wert <= wert +1; end if;
23
  else
24
    if wert > 0 then wert <= wert -1; end if;
25
  end if;
26
  
27
  PIN_out <= wert(3);
28
end process;
29
30
end Verhalten;

Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

von A. S. (Gast)


Lesenswert?

Gustl B. schrieb:

> Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

Kein Tiefpass. Denn Dein Filter hat keinerlei Hysterese oder Dämpfung. 
Er lässt selbst die maximale Frequenz (Abtastfrequenz) ungefiltert 
durch, wenn er zufällig grad in der Mitte ist.

Gleichwohl hat er eine Phasenverschiebung von bis zu 15  Takten.

Dein Filter wäre der von oben, wenn Du ein Ausgangs-Flag einbaust, dass 
bei +15 high wird, bei -15 low und sich sonst nicht ändert. Dann ist die 
maximale Ausgangsfrequenz ein 30tel der Eingangsfrequenz, also ein 
Tiefpass.

von gleitendem Mittelwert kann man bei beiden m.E. nicht sprechen, da 
der Ausgang immer genau einer der beiden Maximalwerte ist. Es wird also 
genau nichts gemittelt.

von A. S. (Gast)


Lesenswert?

Michael F. schrieb:
> Und die Frage
> ist ob das Vergleichbar ist mit einer 2 aus 3 Auswahl wenn dies schon
> mit dem Signal selbst gemacht wird.

Meist gibt es 2 Probleme bei UART-Signalen:

1) Erkennung der Startflanke. Meist wird diese (beim ersten Zeichen) zu 
später erkannt, da die Leitung in maximaler Sättigung ist (seit 
Stunden der Ruhepegel;-)

2) Erkennung des letzten Pegels. Bei 8+2+1 = 11 Bits müssen Taktfehler 
(Quartz, UART-Teiler, Synchronisation) kleiner als 3% bzw. 1/2 Bit 
bleiben.

Die Flanken dazwischen sind quasi "sicherer", die Pegel zum 
Abtastzeitpunkt "stabiler".

Mit Deinem Ansatz erkennst Du die Startflanke grundsätzlich erst ein 
paar Takte später. Das könntest Du zwar noch konstant korrigieren, wäre 
aber ein Problem, wenn das Signal da toggelt.

Da die Startflanke in der Regel sowieso verzögert ist, ist es am 
einfachsten und effektivsten, sofort auf dieses Signal zu reagieren und 
von dort nach 15,16 und 17 Takten die Mehrheit zu bestimmen.

Wenn Du wirkliche Spikes auf der Leitung (ein high trotz dauerhaftem 
low) hast, solltest Du an analog und nicht digital handeln.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

TestX schrieb:
> Was du da machst ist ziemlicher Murks...
Mitnichten. Ich würde auch in etwa diesen Ansatz gehen.

Allerdings ohne diese Rechts-Links-Schieberei (auch wenn ich 
Schieberegister liebe). Diese aufwändige versteckte "Summiererei" macht 
die Sache ziemlich undurchschaubar...

Mein Ansatz wäre also der hier (mit einem etwas breiteren 
Schieberegister):
1
   process (clk_i)
2
   begin
3
      if rising_edge(clk_i) then
4
      
5
         noise_sr <= noise_sr(5 downto 0) & rxd_i;
6
        
7
         if (noise_sr = (others=>'0')) then
8
            rxd <= '0';
9
         end if;   
10
         
11
         if (noise_sr = (others=>'1')) then
12
            rxd <= '1';
13
         end if;   
14
         
15
      end if;
16
   end process;

Michael F. schrieb:
> wollte ich evt. Störungen am Empfänger filtern.
Solange du nicht weißt, was du filtern musst und wie oft es 
auftritt, kann jeder Schuss ins Blaue gleich gut oder schlecht treffen. 
Mein erster Schritt wäre also, diese Störungen zu qualifizieren und zu 
analysieren...

: Bearbeitet durch Moderator
von Gustl B. (-gb-)


Lesenswert?

OK OK, ja, kein gleitender Mittelwert, der Ausgang ist das MSB des 
gleitenden Mittelwerts. Sprich bei 16 Samplewerten wird eine '1' 
ausgegeben wenn der gleitende Mittelwert > 7 ist, sonst '0'.

Wieso so und nicht wie Lothar ein langes Schieberegister bei dem auf 
alles '0' oder alles '1' geprüft wird?
Weil wenn ein Rauschen da ist vielleicht nie der Zustand alles '0' 
erreicht wird sondern nur fast alles '0'. Ob das jetzt sinnvoll ist weiß 
ich nicht.

von Michael F. (mifi)


Lesenswert?

Hallo Lothar,

mit Deiner Version habe ich etwas Bauchschmerzen.Wenn hier 5 Takte eine 
1 vorhanden waren, und dann eine 0 kommt, braucht es erneut 6x eine 1 um 
am Ausgang wirklich eine 1 zu bekommen. Darum die Idee mit dem 
rechts/links schieben.

@Achim,
Ich glaube ich weiss was Du meinst. Das man die Startflanke etwas spät 
erkennt und dadurch sich der Abtastpunkt immer weiter nach hinten 
verschiebt.

Ich glaube man muss das mal testen wie es reagiert. Bei einem Clock vom 
96MHz und einer Bitrate vom 2MHz habe ich 48 Clocks Zeit. Bei #24 ist 
die Mitte wo man abtasten sollte. Die Startflanke wird über ein 
Schieberegister erkannt, evt. darf man hier den Counter dann nicht auf 0 
setzen, sondern schon auf 2 oder 3.

Und wie Lothar schon angemerkt hat. Erst mal schauen wie die Störungen 
später wirklich aussehen.

Danke für Eure Anmerkungen.

Gruß,
Michael

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael F. schrieb:
> Darum die Idee mit dem rechts/links schieben.
Das ist nichts anderes als ein Zähler mit Hysterese:
1
signal noise_cnt : integer range 0 to 3 := 0;
2
:
3
:
4
   process (clk_i)
5
   begin
6
      if rising_edge(clk_i) then
7
      
8
         if rxd_i='1' and noise_cnt<3 then
9
            noise_cnt <= noise_cnt + 1;
10
         end if;
11
12
         if rxd_i='0' and noise_cnt>0 then
13
            noise_cnt <= noise_cnt - 1;
14
         end if;   
15
        
16
         if (noise_cnt = 0) then
17
            rxd <= '0';
18
         end if;   
19
         
20
         if (noise_cnt = 3) then
21
            rxd <= '1';
22
         end if;   
23
         
24
      end if;
25
   end process;

: Bearbeitet durch Moderator
von Achim S. (Gast)


Lesenswert?

Gustl B. schrieb:
> Wieso so und nicht wie Lothar ein langes Schieberegister bei dem auf
> alles '0' oder alles '1' geprüft wird?

Lothars Ansatz ist quasi außer Konkurrenz, da (wie Michael schon 
anmerkt) jede einzelne 0 wieder n 1en erfordert und umgekehrt.

Dein Ansatz und Michaels sind dagegen gleichwertig. 15 Bit bei Michael 
entspräche Zählen bis 15 bei Dir. In beiden sind die gleichen Schwellen 
möglich:
Alles 0 oder 1 entspricht 0 bzw. 15 bei Dir.
Deine abfrage entspricht Bit 8 bei Michael.
Sämtliche Zwischenwerte wären möglich, also 1 bei > 10 und 0 bei <5.

von Edi M. (Gast)


Lesenswert?

Diese Hysterese-Grenzen kann Ich nicht empfehlen. Die speichern die 
Geschichte von Störungen und schaffen ein Level, das mit der neuen 
Störung nichts zu tun hat.

Solche Sachen filtert man diskret und dann mit einem AKF.

von Michael F. (mifi)


Lesenswert?

Was ist ein "AKF"?
Ist damit ein "Aktives Filter" gemeint?
Hast Du hier auch einen Vorschlag den man gut in VHDL umsetzen kann?

von Edi M. (Gast)


Lesenswert?

Auto-Korrelations-Filter

Es passt sich den Pegeln automatisch an. D.h. Du sampelst das Signal 
passend ab und wirst die Spitzen diskret raus. Rest Filterung mit 
Glättung.

von J. S. (engineer) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Das ist eigentlich auch ein gleitender Mittelwert und so ein Tiefpass.

Das ist ein Integrator, der nur bedingt ein klassischer Tiefpass ist.
Da muss man gfs noch differenzieren, um Gleichanteil wegzukriegen. Das 
läuft dann auf ein CIC hinaus. Da kann man oft auch einen trägen 
Tiefpass nehmen, wie ich es beim Entprellen-Artikel reingeschrieben 
habe. Normalerweise reicht sowas.

Generell ist der Tiefpass und Filterung nötig, wenn man runtersampelt, 
um z.B. auf der Datentaktrate arbeiten zu können.

von T.U.Darmstadt (Gast)


Lesenswert?

Bei dem Ansatz, wenn nur 6 Takte betrachtet werden, reicht der scope 
gerade für 1/6 der Taktfrequenz und dämpft nur Frequenzen im Bereich 
16MHz aufwärts weg. Was ist mit tieffrequenteren Störungen?

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Gustl B. schrieb:
> OK OK, ja, kein gleitender Mittelwert, der Ausgang ist das MSB des
> gleitenden Mittelwerts. Sprich bei 16 Samplewerten wird eine '1'
> ausgegeben wenn der gleitende Mittelwert > 7 ist, sonst '0'.
Wenn die Signale zu sehr verrauscht sind, sodaß es zu Sprüngen um den 
Mittelwert kommen kann, weil ...

Beitrag "Gleitender Mittelwert rauscht"

... dann kann man das auch so machen, dass über einen sehr langen 
Zeitraum integriert und dann wieder differenziert wird:

Beitrag "Differenzieren in VHDL"

Läuft auf sowas hinaus:

Beitrag "Decimator-Schaltung für Puls-Datenstrom"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.