Forum: Mikrocontroller und Digitale Elektronik Eventlogger (PCINT)


von Christian Trohn (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,
Ich bastel seit längerer Pause mal wieder an einem kleinen Projekt. Da 
ich mich eher als blutigen Anfänger betrachte bin ich an ein paar 
Punkten eher festgefahren und komme nicht weiter.
Im Anhang meine Main.c als Textfile.
Zur kurzen Erklärung, da ich keine Kommentare genutzt habe.
Ich habe an PC0 bis PC7 jeweils ein Signal 0 oder 5V. Bei einem 
Pin-Change soll mitgeloggt werden welcher Kanal bei welchem Zeitpunkt 
low oder high geworden ist.
Die Interruptschleife PCINT0 könnt ihr erstmal vergessen, da diese die 
zukünftigen Taster darstellen soll.
Die Whileschleife ist aktuell einfach nur als Ausgabe am Display zu 
erkennen und auch nicht fertig.
Mein erstes Problem ist erstmal. Bei einigen Eingängen (Zum Beispiel 2) 
auf dem Port C werden keine Pinchange Interrupts ausgelöst. Die Spannung 
an den Eingängen hab ich durchgemessen, jedoch reagiert die 
Interrupt-Routine nicht. Ist es normal die Eingänge bei der 
Initialisierung auf 0 zu setzen wie ich das gemacht habe? Sonst werden 
die doch eigentlich beim µC Start als Eingänge gelesen oder?
Weiteres viel größeres Problem. Ich weiß nicht so recht wie ich meine 
Programmstruktur am besten aufbaue:
Das Array Eventlog speichert bei Eintreten eines Events jeweils 8 Byte. 
Nach der Datenerfassung wird der Eventcounter um 1 erhöht. Zukünftig 
will ich dann mit den Bedientasten am Display durch die jeweiligen 
Events scrollen können um zu sehen zu welchem Zeitpunkt z.B. ein 
Drahtbruch an der zu messenden Leitung stattgefunden hat.
Jetzt ist es natürlich so dass 8 Byte pro Event eine ganze Menge Daten 
sind. Und da ich keinen Prellfilter verbaut habe kann ein Schaltvorgang 
schon mal 8-10 Events auslösen. Andererseits will ich ja auch keinen 
Prellfilter Vorschalten oder Programmieren, da mich ja auch die Events 
im Millisekundenbereich interessieren wenn ich irgendwo einen Drahtbruch 
oder Wackler registrieren will. Die Lösung die ich mir angedacht habe 
ist die Datensätze in der While-Schleife Stück für Stück in den EEPROM 
oder vielleicht sogar besser auf eine SD-Karte zu übergeben. Dann könnte 
ich die Datenanzeige vom Display auch direkt aus dem Speicher Laden, da 
ich ja nicht Live alle Events betrachten muss wenn sie gerade 
Stattgefunden haben und ich somit nicht Zeitkritisch bin.
Jetzt weiß ich allerdings nicht wie ich das Programmtechnisch lösen 
kann. Ich könnte zusätzlich zu meinem Eventcounter einen EEPROM-Counter 
laufen lassen der alle Datensätze bis zum Eventcounter verschiebt und 
dann wartet dass der Eventcounter wieder weiter gezählt hat. Dann habe 
ich aber trotzdem das Problem das der Eventcounter irgendwann weiter 
zählt als das Array Speicherplatz hat. Und da komme ich ins Wanken und 
komme eigentlich nicht weiter. Vielleicht hat von euch einer eine Idee 
wie man das alles etwas Sinnvoller aufbauen kann?
Ich bin für jede Hilfe dankbar!

von Christian Trohn (Gast)


Lesenswert?

Hallo,
Sorry, Ergänzung: Atmega644PA mit 20MHz.

von Karl M. (Gast)


Lesenswert?

Hallo,

ist JTAG abgeschaltet ?

Dann stimmen die Bezeichnungen nicht, PCINTXY zum Port siehe Datenblatt 
Figure 1-1. Pinout.

Hier die Zuordnungen und das Basissetup für PortC
1
*PortC*
2
PC0 - PCINT16
3
PC1 - PCINT17
4
PC2 - PCINT18
5
PC3 - PCINT19
6
PC4 - PCINT20
7
PC5 - PCINT21
8
PC6 - PCINT22
9
PC7 - PCINT23
10
11
*PCMSK2  Pin Change Mask Register 2*
12
In deinem Fall: 
13
PCMSK2 = (1<<PCINT16) | .. | (1<<PCINT23); // bitte .. ergänzen
14
15
*PCICR  Pin Change Interrupt Control Register*
16
PCICR |= (1<<PCIE2);

Hat PortC definiert Eingangsspannungen, es sind ja keine Pullup aktiv.

Aber "reine" Taster werden nicht über PCINTxy bedient.

Eigenartig, warum schreibst Du das so ?
Ist mehrfach da:
1
if (difference % (1<<PC0)) ..

von Karl M. (Gast)


Lesenswert?

Nachtrag,

das würde ich so auch nicht schreiben, da sich dein Eingangszustand 
schon wieder ändern kann:
1
if ( PINC & (1<<PC0) ) ...
Lieber den schon gesicherten Zustand über reg auslesen

von Christian Trohn (Gast)


Lesenswert?

Danke schonmal für die Antworten. Ob JTAG Eingeschaltet ist prüfe ich 
heute Abend nochmal. Kann aber schon die erste Lösung sein, da ja nur 
ein paar Pins des Registers nicht funktionieren.
Das mit der anderen Bezeichnung war mir garnicht klar. Ich hab im 
Endeffekt einfach nur die 8 Bit auf 1 geschrieben für die Interrupts. 
Ich dachte mir jede Maske wird von 0-7 gezählt. Aber ändere ich auch ab. 
Danke!
Port C hat definierte Eingangsspannungen. Ich hänge mit jedem PIN an 
einem 4,4k Widerstand den ich über jeweilige Optokoppler auf Masse 
ziehe. Das habe ich auch schon alles geprüft und die 0 und 5V sind 
sauber.

Zu der Schreibweise. Da ich ja über jeden Pin in den Interrupt komme 
habe ich über XOR erstmal herausgefiltert welcher Pin an dem Interrupt 
überhaupt schuld ist. Das Ergebnis ist difference. Wenn ich difference 
durch PINC ersetze, dann arbeite ich ja auch z.B. PC0 ab wenn PC1 in den 
Interrupt gekommen ist. Außerdem müsste ich ja für 0 und 1 eine 
jeweilige IF-Abfrage gestalten. Ich dachte mir das das mit dem XOR eine 
gute Lösung wäre.
Mit der Programmfolge, und vor allem was passiert wenn ich in der 
Interruptschleife einen weiteren Interrupt bekomme oder sogesehen dann 
verliere hab ich mir noch nicht allzu viele Gedanken gemacht...

von Karl M. (Gast)


Lesenswert?

Deine Ausführungen über XOR sind mir als "alter" Programmierer bekannt.

Karl M. schrieb:
> if (difference % (1<<PC0)) ..

Nur ist dies keine XOR Verknüpfung ! Oder ?

von Christian Trohn (Gast)


Lesenswert?

Oha das hat jetzt gedauert bis mir das überhaupt aufgefallen ist was du 
meinst. Sollte ein & sein, bin wohl auf % gekommen. Jap das schaue ich 
mir später nochmal genau an. Danke dir

von Christian Trohn (Gast)


Lesenswert?

Hallo,
Vielen vielen Dank für die Ratschläge. Ich hab jetzt überall das 
difference über & abgefragt und JTAG deaktiviert. Jetzt gehen alle Pins 
auf den Interrupt.

Kann mir wer nochmal einen Ratschlag zur Ablage der Daten geben?

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.