Hallo alle zusammen,
an einem XMEGA 256A3BU stelle ich folgendes sehr merkwürdiges verhalten
fest. An dem PORTF des XMEGA sind drei Hall-Sensoren angeschlossen. Ob
die Sensoren betätigt sind oder nicht, stelle ich mit LEDs fest. Das
komische ist, sobald ich einen Sensor anspreche, blitzen kurz auch die
anderen LEDs an. Egal ob diese im Programm abgefragt werden oder nicht.
Noch schlimmer ist, dass in einer while Schleife verblieben wird,
solange ein Sensor betätigt ist. In dieser Schleife blinken die LED
durch Timer Interrupt. Nun passiert aber folgendes, dass diese While
Schleife sporadisch verlassen wird, wobei sichergestellt ist, dass die
Sensoren betätigt sind. Das komische, dieses verhalten ist nur an PORTF
festzustellen.
Kennt jemand diese Probleme?
Grüße Peter
also abgefragt wird mit
if (PORTF.IN & 0b00000100)
{
PORTB.OUTSET = PIN5_BM;
}
parallel läuft ein Timer der eine weitere LED blinken lässt. das
Komische ist auch, dass die Einabfrage mal früher mal später verlassen
wird, wobei der Pin immer betätigt ist. Das sagt zumindest das Oszi und
mein Finger am Sensor.
Peter D. schrieb:> Immer diese vergeblichen Versuche, Programme als Prosa zu posten.>> Ich hab mich auch schonmal gewundert. Ursache war ein fehlendes ;
Ich hab mich auch schonmal gewundert. Ursache war ein fehlendes }
Habe jetzt nochmal ganz in ruhe meine Schaltung geprüft. Auf einem
Eingang des XMEGA generiere ich ein Eingangssignal mit ca 1 kHz. Kann
das sein, dass sich die Frequenz überlagert und im ungünstigen
Augenblick meinen Eingang an PORTF als LOW erkennen lässt?
Wenn ja wie kann ich das verhindern? Internen PullUp an betroffen Pin
aktivieren und gegen Masse einen Kondensator?
Hallo, schau mal, ob der C-Compiler einen Read-Modify-Write Sequenz
erzeugt?
Wenn der vom Interrupt unterbrochen wird, und auf den Selben Port
zugegrift wirds Äpfel und Bananen.
Also ich habe einiges schon mit den Xmegas gemacht, nie Probleme gehabt,
sind klasse Teile. Besonders der 32E5.
Hallo,
Sascha schrieb:> C-Compiler einen Read-Modify-Write Sequenz> erzeugt
auf einem Xmega sollte der PORTB.OUTSET das nicht machen, genau dagegen
ist der doch eingeführt....
Aber wie schon erwähnt ohne Schaltung und Code .....
Also am Code kann es nicht liegen. Habe den statt den Eingang an PORTF
einfach mal durch eine anderen ersetzt und dann läuft das Programm
normal durch. Nun wenn ich den PIN abfrage, neben welchem diese 1 KHZ
Frequenz eingeht, gibt es Probleme, Also muss sich doch diese Frequenz
da mit Übertragen?
Ganz geschmeidig ;)Also der Schaltplan ist quasi nicht vorhanden, da es
ein XPLAIn Board ist. an das schliesse ich einfach paar tasten mit
PULLDown 10K an und drei Hellsensoren. An diesen sind zwischen VCC und
GND 100nF und zwischen OUT und VCC 10 K. Dazu liegt an den gleichen Eins
ein zweiter AVR "Arduino" der einfach in 1 KHZ Takt einen Ausgang
triggert.
Danke für die sehr hilfreichen Ratschläge. Wenn der Code mit Abfrage
eines anderen PINS läuft, muss es doch an der Hardware liegen? Wie
gesagt vermute ich eine Überlagerung der Frequenz. Gibt es denn
Hardwaremittel um das zu verhindern?
Habe nochmal folgendes Aufgebaut. Ein Hallenser wird mit einem Magneten
dauerhaft geschalten. Programm macht was es soll. Nun lege ich an dem
zweiten Hallsensor mit einem Ringmagneten und einer Bohrmaschine ein
wechselndes Signal an. Dieses Signal ist dem immer geschaltetem Sensor
wirklich überlagert. Dann spinnt auch das Programm!
Wenn du den ganzen Code postest dann sieht man vielleicht ob an andere
Stelle was nicht passt.
Nur weil die eine Stelle geht heisst es nicht das der ganze Code passt.
Sicher das deine Abfrage alle passen ?
Bei
1
if(PORTF.IN&0b00000100)
2
{
3
PORTB.OUTSET=PIN5_BM;
4
}
kannst dich ja leicht um ne Null verschrieben haben.
Einfacher ist doch
1
if(PORTF.IN&PIN2_bm)
2
{
3
PORTB.OUTSET=PIN5_BM;
4
}
Im Else Zweig löscht den Port wieder oder machst du das ein ner weiteren
Abfrage.
Gruß JackFrost
Die Abfrage ist in einer While-Schleife. Solange gedrückt wird leuchtet
es. Darum sehe ich auch das Flakern. Schreibstill mit 0b oder Pin2
bringen beide den selben Fehler. Nur ein gänzlich anderer Pin läuft
Habe den Code leider jetzt nicht mehr zu Hand, vermute aber nach wie vor
das überlagerte Signal. Das Flachbandkabel welches ich verwende ist
bestimmt nicht das beste?
> Habe den Code leider jetzt nicht mehr zu Hand
Du verschaukelst uns, oder?
Dann schreib jetzt nochmal den ganzen Code neu, teste ihn und fange
nochmal ganz von Vorne mit vernünftigen Fragen an. Vernünftig Fragen
beginnt mit Schaltplan und dem kompletten Code.
Nein ich verschaukel keinen. Möchte doch nur wissen ob sich solch ein
Signal überlagern kann und wenn ich mit welchen Komponenten ich es
unterdrücken kann. Das Programm läuft ja wenn ich statt dem Pin einen
anderen Abfrage!
Peter schrieb:> Wenn der Code mit Abfrage> eines anderen PINS läuft, muss es doch an der Hardware liegen?
Nö.
Solange man den Fehler nicht gefunden hat, ist ein SW-Fehler am
warscheinlichsten.
Und insbesondere dann, wenn man den kompletten Code nicht zeigt.
Es kann aber nichts schaden, wenn man sich die Erratas im Datenblatt
anschaut.
Z.B. der Attiny1634 hat nen ganz fiesen Bug, da geht Pin PB3 nicht als
Eingang, solange der Watchdog nicht läuft.
if(!(PORTF.IN&0b00000100))// Wenn einschalter gedrückt ausführen
41
{
42
// Interrupt für Nulldurchgänge
43
PORTD.INTCTRL=PORT_INT0LVL_HI_gc;
44
PORTD.INT0MASK=0b00000001;
45
PORTD.PIN0CTRL=PORT_ISC_BOTHEDGES_gc;
46
47
while(!(PORTF.IN&0b00000100))
48
{
49
if(Null==1)
50
{
51
Null=0;
52
_delay_ms(6);
53
PORTE.OUTSET=PIN4_bm;
54
_delay_ms(1);
55
PORTE.OUTCLR=PIN4_bm;
56
}
57
58
}
59
60
_delay_ms(1000);
61
PORTE.OUTCLR=PIN4_bm;
62
TCE0.CTRLA=TC_CLKSEL_OFF_gc;
63
counter=0;
64
PORTD.INTCTRL=0x00;
65
PORTD.INT0MASK=0b00000000;
66
}
67
if(PORTF.IN&0b00000100)
68
{
69
update=0;
70
71
PORTE.OUTCLR=PIN4_bm;
72
TCE0.CTRLA=TC_CLKSEL_OFF_gc;
73
//TCF0.CTRLA = TC_CLKSEL_OFF_gc;
74
counter=0;
75
PORTD.INTCTRL=0x00;
76
PORTD.INT0MASK=0b00000000;
77
}
78
}
79
}
hier der Code.
Die While Schleife "Solange taster nicht gedrückt (umgekehrte Logik da
Hallsensor aktiv LOW ausgibt), wird in ungleichen Abständen verlassen.
Wenn die Abfrage an einem anderen PORT als an PORTF gemacht wird, läuft
es aber durch. So scheint es jedenfalls.
> Möchte doch nur wissen ob sich solch ein Signal überlagern kann
Signale können sich überlagern. Ohne Schaltplan kann ich Dir keine
Antwort geben, die in diesem konkreten Fall hilft.
> schliesse ich einfach paar tasten mit PULLDown 10K an
Das passt aber nicht zum Programmcode.
> if (!(PORTF.IN & 0b00000100)) // Wenn einschalter gedrückt ausführen
Hier wird etwas gemacht, wenn der Eingang auf LOW liegt. Wenn dein
Taster in gedrücktem Zustand ein LOW liefert und du auch noch einen
Pull-Down Widerstand parallel geschaltet hast, kann niemals ein HIGH
anliegen.
Also: Schaltplan bitte!
Rücke den Quelltext anständig ein, so kann das ja keiner lesen.
Was mir spontan auffällt:
[code]
if (!(PORTF.IN & 0b00000100)) // Wenn einschalter gedrückt ausführen
{
...
while (!(PORTF.IN & 0b00000100))
{
}
}
if (PORTF.IN & 0b00000100)
{
}
Du willst hier wohl irgendwas machen, wenn der Taster gedrückt wird und
solange wiederholen, wie er gedrückt ist.
Taster prellen aber. Zwischen der if Abfrage und der while Schleife kann
der Taster durchaus wieder in den "losgelassen" Zustand wechseln, so
dass die while Schleife manchmal gar nicht ausgeführt wird.
Weiterhin kann es aus dem selben Grund passieren, dass weder der erste
noch der zweite if Ausdruck wahr ist und es kann passieren, dass beide
wahr sind.
Hast du das berücksichtigt?
> Noch schlimmer ist, dass in einer while Schleife verblieben wird,> solange ein Sensor betätigt ist.
Naja, das st doch der Sinn von while(). Kann es sein, dass nicht einmal
du Dir darüber im klaren bist, was wo angeschlossen ist und wann die
Eingänge HIGH bzw. LOW sind?
Ich wundere mich auch sehr darüber, dass du hier mit Interrupts
arbeitest. Dein Programm sieht ziemlich wirr aus. Wie soll es überhaupt
funktionieren? Zeichne mal einen Programmablaufplan, zerlege es in
Funktionen mit sprechenden Namen und benutze anständige Variablen-Namen.
"Null" ist ein schlechter Witz.
Ich denke, wenn du die Struktur sauber hast und den Plan gezeichnet
hast, wird Dir schon selbst auffallen, wo der Denkfehler ist. Wenn
nicht, helfen wir dann auch gerne weiter.
> TCE0.CTRLA = TC_CLKSEL_OFF_gc;
Welche Funktion hat der Timer in deiner Anwendung und warum ist das der
einzige Wert, den du bei unterschiedlichen Ereignissen wiederholt in
dieses Register schreibst? Das kann so keine Sinnvolle Funktion haben!
Hallo, danke für die Antwort. Vieles im Programm ist vom Testen über
geblieben. Daher auch sinnlose Variablennamen oder übrig geblieben
Timer.
Das prellen der Taster ist mir bekannt. Hier sind Hallsensoren verbaut,
die aktiv LOW liefern. Diese Prellen nicht!
if(!(PORTF.IN&0b00000100))// Wenn einschalter gedrückt ausführen
2
{
3
// Interrupt für Nulldurchgänge
4
PORTD.INTCTRL=PORT_INT0LVL_HI_gc;
5
PORTD.INT0MASK=0b00000001;
6
PORTD.PIN0CTRL=PORT_ISC_BOTHEDGES_gc;
7
8
while(!(PORTF.IN&0b00000100))
9
{
10
if(Null==1)
11
{
12
Null=0;
13
_delay_ms(6);
14
PORTE.OUTSET=PIN4_bm;
15
_delay_ms(1);
16
PORTE.OUTCLR=PIN4_bm;
17
}
18
19
}
20
21
...
22
}
Ich geh mal davon aus das an PD0 der 1kHz Taktgeber sitzt, oder ? Du
setzt die Variable bei jeder Flanke und damit ist das keine
Nulldurchgangserkennung.
Du mischt 0x mit 0b und den "Definitions". Bleib doch bei einem
Den Intlvl kannst du doch auch einfach damit löschen :
1
PORTD.INTCTRL=TC_OVFINTLVL_OFF_gc
Vorallem sollte das reichen. Die Maske wegen dem INT0 Pin brauchst du
dann nicht mehr ändern. Auch kannst du die PORTD.PIN0CTRL vor dein
while(1) setzen.
1
if(Null==1)
2
{
3
Null=0;
4
_delay_ms(6);
5
PORTE.OUTSET=PIN4_bm;
6
_delay_ms(1);
7
PORTE.OUTCLR=PIN4_bm;
8
}
Du setzt 0 Null auf 0 und wartest dann 6 ms und dann triggerst du den
PE4 für eine ms ? Sind da deine LEDs dran , siehst du das oder willst du
das nur mit dem Oszi sehen ?
Während der Wartezeit ist Null wieder 1 da die ISR bei 1kHz mindestens 6
mal ausgelöst wurde. Dein Null=0 am Anfang bringt also nix. Wenn das
Programm wieder bei if steht wird das ausgeführt und es ist nicht
definiert wie der Zustand an deinem PD0 ist.
Du wartest dann noch eine Sekunde
1
_delay_ms(1000);
Und auch da wird Null wieder auf 1 gesetzt.
Die beiden
1
PORTE.OUTCLR=PIN4_bm;
weiter unten kannst du dir auch sparen , da der PE4 bereits 0 ist wenn
du die while Schleife verlässt. Vermutlich wird das Compiler eh löschen.
Wie hast du denn die Hallsensoren an den PORTF gehängt ? Laut dem
Schaltplan vom XPLAIN 256A3BU sind an PF die Taster, der Flash und der
Qtouch aber da geht kein PIN von PF auf die Stiftleisten.
Peter schrieb:> an das schliesse ich einfach paar tasten mit> PULLDown 10K an und drei Hellsensoren. An diesen sind zwischen VCC und> GND 100nF und zwischen OUT und VCC 10 K. Dazu liegt an den gleichen Eins> ein zweiter AVR "Arduino" der einfach in 1 KHZ Takt einen Ausgang> triggert.
Zeichne mal einen Plan das kann doch keiner mehr verstehen wie deine
Hardware aufgebaut ist. Sind da nun Taster oder nicht ? Was meinst du
mit an den gleichen PINs ist der Taktgeber ?
Gruß JackFrost
Bin gerade im Auto und kann leider nicht malen. Das Programm von vorhin
passt nicht mehr zur gestrigen Beschreibung, da ich das mit der Frequenz
ausschließen wollte. Habe nur noch mit 50Hz getriggert und dann den
Hallsensor mit einem Magneten angesprochen. Laut Oszi ist das Signal
dauerhaft auf Low, der Xmega verliert aber den Status. Der Fehler
scheint weg zu sein, wenn ich nah an den bin einen Kondensator mit 4.7
nF schalte.
Peter schrieb:> Laut Oszi ist das Signal> dauerhaft auf Low, der Xmega verliert aber den Status.
Der XMEGA verliert gar nichts! Du konfigurierst die Ports nicht richtig
oder Dein Programm macht Unsinn. Punkt.
Ich bilde mir auch ein, dass das Programm geht weil: wird ein anderer
Pin abgefragt als der Hallsensor läuft alles ohne Probleme. Demnach muss
der Hallsensor was einkoppeln. Und der Fehler kommt mal nach 5 min dann
lange gar nicht mehr oder in kurzen Abständen hintereinander. Darum
vermute ich halt dass die Hardware nicht ganz klappt. Der Hallsensor ist
mit dem Ausgang direkt am Pin des Xmega inkl Pullup.
Peter schrieb:> Ich bilde mir auch ein, dass das Programm geht weil: wird ein anderer> Pin abgefragt als der Hallsensor läuft alles ohne Probleme. Demnach muss> der Hallsensor was einkoppeln. Und der Fehler kommt mal nach 5 min dann> lange gar nicht mehr oder in kurzen Abständen hintereinander. Darum> vermute ich halt dass die Hardware nicht ganz klappt. Der Hallsensor ist> mit dem Ausgang direkt am Pin des Xmega inkl Pullup.
Du hast also an den Pin des XMEGA eine Pullup und die Flachbandleitung
angelötet. An dem gleichen Pin an dem auf dem Board der Taster ist und
ein 100 k Pullup ? Schonmal auf Zinnbrücken überprüft ?
Und wenn du einen x belobigen Pin abfragst obwohl de Hallsensor
angeschlossen ist dann geht dein Program ? Wenn ja, dann liegt der
Fehler in der Software.
Nein. Sorry blöd ausgedrückt. Habe ein weiteres Board gekauft wo ein
Xmega mit randbeschaltung vorhanden ist aber keine Taster. Dann schließe
ich einen Taster an mit 10k pullup und löte ein Flachbandkabel ca 20cm
lang an. An dem Ende an Vcc und Gnd den Hallsensor und dann den dritten
Pin über das Kabel an den Xmega. Dazu kommt nur ein pullup vom Ausgang
des Sensors auf Vcc. Wenn ich nun das Programm laufen lasse und den
Taster Abfrage läuft es richtig durch. Beim Abfragen des Hallsensor
springt es in unterschiedlichen Abständen aus der while schleife. Die
korrekte Funktion wird durch ein blinken einer LED angezeigt.
Hier der Anschluss von Sensor und Taster. Der Kondensator im
gestricheltem Kästchen bewirkt dass das Programm scheinbar richtig
läuft. Kann es nicht hundert pro sagen da es auch ohne mal länger mal
kürzer läuft. Mit Kondensator jedoch bis jetzt ohne Aussetzer.
Findet ihr noch grobe Fehlet im Code oder sollte es vom Prinzip so
laufen? Mögliche Bugs oder Stolperstellen mit Atmel Studio 7 oder Xmega?
Könnte mir sonst nur mit dem eingezeichneten Kondensator helfen oder die
whileschleife eventuell erst verlassen wenn 10 ms hintereinander der Pin
einen High Zustand hat? Dafür müsste man aber genau wissen dass der
Fehler vom Hallsensor kommt. Warum sieht man nichts auf dem Oszi?
Wir wissen nicht was da an Störungen bei dir herumläuft.
Mir hat in einem ähnlichen Fall folgendes geholfen:
Nimm ein 5adriges Flachbandkabel, Q in die Mitte. Die Leitungen links
und rechts davon legst du nur auf der µC Seite auf GND. Für VCC und GND
zum Sensor nimmst du die jeweils äußeren Adern.
Peter schrieb:> Demnach muss> der Hallsensor was einkoppeln. Und der Fehler kommt mal nach 5 min dann> lange gar nicht mehr oder in kurzen Abständen hintereinander.
Ob du das im Oszi siehst?
Wenn deine Pull-Up Widerstände 10MΩ hätten oder deine Leitung 20m lang
wäre, dann hätte ich Dir geschrieben, dass dein Problem kein Wunder ist.
Aber bei 10kΩ und 20cm ist ein kapazitives Übersprechen von einer
Leitung zur Nächsten so gut wie ausgeschlossen. Es sei denn, der Ausgang
vom Hall Sensor liefert keine sauberen Pegel.
Bei einer ungültigen Spannung zwischen HIGH und LOW genügen schon
geringste Schwankungen, um einen Wechsel zwischen 1 und 0 auszulösen.
Mess da mal die Spannung nach. HIGH sollte >2V sein und Low sollte <0,7V
sein. Wenn nicht, dann sind die Signale, die der Sensor liefert nicht zu
deinem Mikrocontroller kompatibel. Dann kann man sicher mit einem
Transistor oder CMOS Gatter nachhelfen.
Also der Sensor liefert exakt 3,3 Volt High und 0,1V Low. Werde die
Randbeschaltung vom Sensor ein zweites Mal inkl Kondensator vom Ausgang
auf Masse ein zweites Mal direkt vor den Controller bringen. Ich hoffe
das Problem ist dann weg.
Sehr gerne! Da der Fehler so unrägelmäßig kommt muss es von der Hardware
kommen da bin ich mir sicher. Werde das mit der randbeschaltung hoch an
die MCU ziehen!
Weil sie unregelmäßig sind.
Um unregelmäßige Signale mit einem Oszilloskop zu erfassen brauchen Sie
ein digitales Gerät mit Speicher und eine Triggerung auf genau diese
Störung.