hall zusammen
es geht um ein nec signal
ich habe ein signal (SIG) 32 BIT (31 downto 0), der so gebaut ist
BIT =1 ist :wenn der impuls 560 us und die pausenzeit ist 1,7ms
bit =0 ist:wenn der impuls 560 us und der pausen zeit 560 us
1 und 0 UNTERSCHEIDEN SICH VON DER PAUSENZEIT
DER OSZILATORFREQUENZ VON MEINEM BOARD IST 30 MHZ
ICH HABE SO GEMACHT ABER KLAPPT NICHT
..
...
necsr <= necsr(1 downto 0) & nec when rising_edge(clk);
bits <= bits (31 downto 0)& necsig when rising_edge(nec)
if (necsr(2 downto 1)= "01") then -- start bit fuer zâhler
cnt <= 0; -- bei jeder steigende flanke zähler auf null gesetzt
ELSE
cnt <= cnt + 1 ;--hochzählen
if cnt > 37500 then -- wenn der zähler 0 bit länge(freq) überschreitet
necsig <= '1';
else
if cnt <37500 then -- wenn zâhler kleiner als 0 bit länge
necsig <= '0';
das problem ich will dass necsig zeigt ein 1 von bitanfang bis zu
bitende
und nicht erst wenn cnt > 37500 oder das geht nicht ?
oder ich habe denkfehler bitte um hilfe
ich hoffe meine frage ist klar
Eine einfache Lösung, falls ich alles richtig verstanden habe :
Du wertest zu dem zeitpunkt an dem feststeht ob eine '0' oder '1' ankam
für einen takt lang aus.
Da du intern eh mit 30mhz arbeiten willst bringt es dir ja eh nichts
wenn du zigtausend takte lang weist was da kam, du musst es ja nur
einmal wissen.
D.h. an der Stelle wo du den Zähler zurücksetzt würdest du die
Auswertung vornehmen anhand des aktuellen necsig.
bsp:
1
process(clk)
2
begin
3
4
necsr<=necsr(1downto0)&necwhenrising_edge(clk);
5
6
if(necsr(2downto1)="01")then-- start bit fuer zâhler
7
cnt<=0;-- bei jeder steigende flanke zähler auf null gesetzt
8
bits<=bits(31downto0)&necsig;
9
ELSE
10
cnt<=cnt+1;--hochzählen
11
endif;
12
13
ifcnt>37500then-- wenn der zähler 0 bit länge(freq) überschreitet
14
necsig<='1';
15
else
16
necsig<='0';
17
endif;
18
19
endprocess;
allerdings wie gesagt, nur soweit ich das verstanden habe.
was das rising_edge(nec) dort soll weiß ich z.b. nicht, das macht meiner
Meinung nach überhaupt keinen Sinn.
Ansonsten ist dein Code auch nur sehr zusammengekleckst.
Aber probiers erstmal wie ich das beschrieben habe und wenn das noch
nicht klappt -> bitte den gesamten code in [/vhdl] + [vhdl] posten oder
als .vhd anhängen.
> allerdings wie gesagt, nur soweit ich das verstanden habe.
Das NEC Signal ist realtiv simpel, es fehlt hier noch, dass der 9ms Puls
am Anfang zur Synchronisation verwendet wird. Schön erklärt ist das
dort: http://www.sbprojects.com/knowledge/ir/nec.htm
Ich habe das mit dem NEC-Signal auf meiner todo-Liste und werde es die
Tage mal durchkneten. Allerdings zeigt der NEC-Modus auf meiner
Universal-FB ein etwas anderes zetiliches Verhalten... ;-)
Das sieht ja wirklich simpel aus. Danke für den Link.
Mir war bei der Fragestellung oben gar nicht bewusst das es sich um ein
Standardprotokoll handelt.
Hmm, den Startpulse kann man sicher auch ignorieren wenns in einen
kleinen CPLD rein soll..macht den Zähler immerhin um 10 FFs kleiner.
Werd mich morgen auch mal daran versuchen. Immer eine gute Übung :)
danke zusammen
das ist richtig der start signal mit 9ms wollte ich gar nich daran
denken,weil ich keine vorstellung habe wie ich das mache
an miller :wie komme ich zu deiner todo liste miller?
> wie komme ich zu deiner todo liste miller?
Keine Chance....
Die ist in meinem Kopf ;-)
@ Iulius
Das mit dem Sync ist nicht unwichtig, sonst kannst du einen Start nur
raten. Vor allem solltest du einen sättigenden Zähler für die Bitzeit
verwenden. Denn die Zeit für eine '1' kann auch mal wesentlich länger
sein: ich messe an der FB hier bis zu 25 ms!!
Das einzige Problem das ich sehe, ist wenn ich das Gerät zum Empfangen
während einer laufenden Übertragung einschalte.
Auf den anderen Seite gefällt mir das so oder so nicht.
Habe jetzt einen Transceiver entworfen der ~160 LE verbraucht.
Davon entfallen 60 auf den Empfänger(ohne Sync) und 100 auf den
Sender(ziemlich genau nach Protokoll).
Irgentwie wohl doch nix für den CPLD wobei ich mich ehrlich gesagt frage
wo die ganze Logik herkommt... klar Schieberegister+Zähler frisst schon
einiges, aber trotzdem.
Habs mal angehangen, aber naja, gefällt mir wie gesagt nicht besonders.
Zu groß und zu frickelig für meinen Geschmack.
> Denn die Zeit für eine '1' kann auch mal wesentlich länger>> sein: ich messe an der FB hier bis zu 25 ms!!
AN MILLER ,ICH BIN GESPANNT WIE DU DAS MACHST
Iulius C. schrieb:
> Habs mal angehangen, aber naja, gefällt mir wie gesagt nicht besonders.>> Zu groß und zu frickelig für meinen Geschmack.
MILLER SAGT IST SEHR EINFACH
ICH HABE SCHON SEIN RC5-empfänger gesehen er hat das super gemacht und
nur in ein paar zeilen
aber bei rc5 die bits sind gleich fuer mich ist viel einfacher als
nec-emp
na ja nicht aufgeben ,programmieren braucht geduld und erfahrung
ich hoffe ein ergebnis von Miller
Hi,
wenn du Lothars Link oben (uebrigens danke dafuer, kann ich gut
gebrauchen!) folgst, dann wirst du relativ einfach rausfinden, wie man
das loesen kann...
Gruss,
- berndl
Hier wie versprochen meine Lösungsansätze ;-)
Variante 1, Bits werden mit der steigenden Flanke vom NEC-Signal
eingelesen und nach Ablauf eines Timeouts (Pause zwischen 2
Übertragunspaketen) übernommen.
1
libraryIEEE;
2
useIEEE.std_logic_1164.all;
3
useIEEE.numeric_std.all;
4
5
entityNEC_Decoderis
6
Port(clk:inSTD_LOGIC;
7
NEC:inSTD_LOGIC;
8
RXdata:outSTD_LOGIC_VECTOR(15downto0));
9
endNEC_Decoder;
10
11
architectureBehavioralofNEC_Decoderis
12
signalnecsr:std_logic_vector(2downto0):="000";
13
constantoscclk:integer:=50000000;-- 50MHz z.B. FPGA
14
constanttimeout:integer:=(oscclk/(1000000/20000))-1;-- Timeout: 20 ms, nach Timeout werden Daten übernommen.
15
constantone:integer:=(oscclk/(1000000/1685))-1;-- (2,25+1,12)/2 = 1685 us
-- NEC-Signal einlesen, bis Pause (Timeout) länger als 20 ms
22
processbegin
23
waituntilrising_edge(clk);
24
necsr<=necsr(necsr'left-1downto0)&NEC;
25
if(cnt<timeout)then
26
cnt<=cnt+1;
27
else-- Timeout --> Daten übernehmen
28
RXdata<=bits;
29
endif;
30
if(necsr="001")then-- steigende Flanke
31
bits<=bits(bits'left-1downto0)&nextbit;
32
cnt<=0;
33
endif;
34
endprocess;
35
nextbit<='1'when(cnt>=one)else'0';
36
endBehavioral;
Das funktioniert mit meiner Fernbedienung hier, weil die den Repeat-Code
nicht sendet. Statt dessen wird das komplette Datenpaket nochmal
übertragen (siehe Screenshot) :-o
Die Variante 2 ist konform zum NEC-Protokoll, weil dort die Repeat-Pulse
gesondert behandelt werden (siehe Anhang). Allerdings kann ich die
Funktion nicht detailliert testen, weil wie gesagt meine FB nicht ganz
das beschriebene NEC-Protokoll sendet... :-/
danke sehr miller, du hast dein versprechen gehalten danke nochmal
aber ich werde dein code erst morgen analysieren ,bin müde
mein cnt zählt auch vor der ersten flanke
.
.
.
signal cnt : integer range 0 to 67567 := 0;
bits <= bits (31 downto 0)& NECSIG ;
.
.
.
if rising_edge(clk) then
if (necsr(2 downto 1)= "01") then
cnt <= 0;
else cnt <= cnt + 1 ;
end if ;END IF;
NORMALERWEISE DER CNT FÄNGT ZU ZÄHLEN ERST NACH DEM TREFFEN MIT EINER
FLANKE UND NICHT VOR DEM ERSTEN FLANKE VON DER STARTBIT,
WO KEINE FLANKE GIBT
VORAN KANN DAS LIEGEN? HABE ICH WAS FALSCHES üBERSEHEN?
Was mir da sofort auffällt:
Dein Zähler begrenzt nicht. Der zählt lustig weiter bis 131071 und läuft
dann über auf 0 und zählt dann dort weiter....
Besser wäre es auf jeden Fall so:
1
if(necsr(2downto1)="01")then-- start bit fuer zâhler
2
cnt<=0;-- bei jeder steigende flanke zähler auf null gesetzt
3
bits<=bits(31downto0)&necsig;
4
ELSE
5
if(cnt<67567)thencnt<=cnt+1;endif;
6
endif;
>>> signal cnt : integer range 0 to 67567 := 0;
Warum reichen dir nicht 65535 als Endwert?
Dann würden für den Zähler 16 Bit reichen.
dein programm ist 90 prozent wie meins
es gibt ein problem was ich seit tagen lösen will
die steigende flanke von nec signal zeigt den wert von der dem
nextbit(dein signal) von den vorherigen nec signal ;
der letzen bit wird unbewertet ,
stattdessen ist der 15-te bei dir ,bei mir auch der start bit
hier ist ein fertigen testbench kannst du noch mal probieren
NEC_PROC :PROCESS
BEGIN
NEC <= '0'; --pause
WAIT FOR 3 MS;
NEC <= '1';
WAIT FOR 9 mS;--START BIT
NEC <= '0';
WAIT FOR 4500 us;
NEC <= '1'; -- 1
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 2
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 3
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 4
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 5
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 6
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 7
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 8
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 1
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 2
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 3
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 4
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 5
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 6
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 1690 US;
NEC <= '1'; -- 7
WAIT FOR 560 us;
NEC <= '0';
WAIT FOR 560 US;
NEC <= '1'; -- 8
WAIT FOR 560 us;
NEC <= '0'; --PAUSE ,INKLUSIV PAUSENZEIT VON DEM LETZTENBIT
WAIT FOR 20 MS;
END PROCESS;