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!
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)) .. |
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
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...
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 ?
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.