Hallo, ich habe folgenden Code: /* EEPROM */ #ifndef EEMEM #define EEMEM _attribute_ ((section (".eeprom"))) #endif #define Tabellen_Groesse 8 uint8_t ee_Generator_Tabelle[] EEMEM = { 56, 48, 40, 32, 24, 16, 8, 0 }; volatile uint16_t Tabellen_Index; Die Ein-/Ausgänge und Timer sind so festgelegt: DDRA &= ~( (1 << PA0) | (1 << PA1) | (1 << PA2) | (1 << PA3) | (1 << PA4) | (1 << PA5) | (1 << PA6) ); DDRA |= (1 << PA7); /* Eingang */ TCCR0 = (1 << CS01); /* CPU-Takt/8 */ TCNT0 = 44; TIMSK |= (1 << TOIE0); /* Timer Interrupt Mask setzen. */ Jetzt habe ich eine Interrupt-Routine die Regelmässig Daten aus der Tabelle ausgibt: SIGNAL(SIG_OVERFLOW0) { /* Timer neu laden. */ TCNT0 = 44; /* Nächsten Zustande aus dem EEPROM laden und ausgeben. */ PORTA = eeprom_read_byte(&ee_Generator_Tabelle[Tabellen_Index]); Tabellen_Index++; if(Tabellen_Index == Tabellen_Groesse) Tabellen_Index = 0; } Damit müsste ich an den Pins PA5, PA4 und PA3 ja drei verschiedene Frequenzen messen können (PA5 = 2*PA4 = 4*PA3). Allerdings habe ich an allen Pins von Port die Gleiche Frequenz, sogar an PA7, welcher ja ein Ausgang ist. An PA6 kann man ein sauberes Signal erkennen, mit steilen Flanken, welches an eine PWM erinnert. An PA0 - PA5 hat das Signal eine steil steigende Flanke und die fallende Flanke hat die Form einer e-Funktion. Anfangs habe ich geglaubt der Mikrocontroller sei kaputt und habe ihn ausgetauscht, was aber keine Besserung gebracht hat und der gleiche IC hat auch mit einem anderen Programm ohne Tadel funktioniert. Habe ich irgendwo vergessen ein Flag zu setzen oder zu löschen? Gilles
Bitte poste mal einen compilierbaren Code (am besten als Datei hochladen, zumindest aber in [C]-Tags), dann stecke ich das mal auf'm STK500 zusammen.
Also hier mal mein Code. An PA3 müsste ich doch jetzt eine Frequenz von 7,353 kHz messen können wenn mein Mikrocontroller mit 8MHz läuft. Oder ist zwischen zwei Timer-Interrupts nicht genug Zeit um die Werte aus dem Speicher zu holen?
Sicher, dass die eeprom-Funktionen der genutze Version der avr-libc auch mit den ATtiny26 funktionieren? Bei aelteren Versionen der avr-libc gab es Inkompatibilitaeten mit einigen "neueren" AVR-Modellen, mglw. auch mit dem tiny26.
Also ich habe jetzt mal den erzeugten Maschinencode mittels: avr-objdump -h -S Generator.elf > CodeAuswertung.lst angeschaut. Das EEPROM vom ATtiny26 wird korrekt angesprochen, allerdings ist mir aufgefallen, dass ich für Tabellen_Index ein uint16_t benutze und ein uint8_t ja schon gross genug ist. Dabei wird die Adresse $1F beschrieben, diese Adresse trägt im Datenblatt den Namen "Reserved". Kann das das Problem sein?
Nun bin ich endlich mal dazu gekommen, wie versprochen das auf einem STK500 nachzustöpseln. Damit ich was sehen kann, habe ich mir den Timer 0 so langsam wie möglich gestellt und die STK500-LEDs an Port A drangeklemmt. Ich denke, dein Hauptproblem ist einfach nur, dass du die Logik von DDRA exakt verdreht hast. Deinen Eingang (PA7) hast du als Ausgang beschaltet, die anderen 7 Pins sind Eingänge. Ansonsten funktioniert das bei mir erst einmal. Kommentare: > #include <avr/delay.h> Das benutzt du gar nicht. Wenn du es nehmen willst, solltest du F_CPU zuvor definieren. > #define Tabellen_Groesse 8 Kann man eigentlich dynamisch ermitteln. > PORTA = eeprom_read_byte(&ee_Generator_Tabelle[Tabellen_Index]); > Tabellen_Index++; > if(Tabellen_Index == Tabellen_Groesse) > Tabellen_Index = 0; Sehr ungünstig mit einer volatile-Variable. Besser in einer lokalen Variable zwischenspeichern. > /* W?hrend der Initialisierung werden keine Interrupts zugelassem. */ > cli(); Die sind hier sowieso (noch) nicht zugelassen. > /* Die Ein-/Ausg?nge und Timer sind so festgelegt: */ > DDRA &= ~( (1 << PA0) | (1 << PA1) | ... Wie gesagt, das scheint mir das Grundübel bei dir zu sein. > if(PINA & (1 << PA7)) > { > PORTA = 128; /* Generator zeitweise stoppen */ > } Hmm, wirklich anhalten tut das den Generator nicht... Es schreibt immer wieder Nullen drüber, aber wenn ein Interrupt reinhaut, bekommst du einen Spike. Davon abgesehen, das Zurückschreiben von Bit 7 auf einem Eingang in das Ausgaberegister aktiviert dessen Pullup (was du sicher nicht wolltest). Anbei meine Version. ;-)
p.s.: Aus wahrscheinlich nicht völlig unverständlichen Gründen ;-) läuft bei mir natürlich eine aktuelle avr-libc-Version. Falls es also wirklich Probleme mit der Bibliothek und dem ATtiny26 gegeben haben sollte, sind diese zumindest repariert. Allerdings sieht es mir so aus, als hätte der ATtiny26 ,,Standardlage'' für den EEPROM. Das Beschreiben des fehlenden EEARH-Registers sollte kein Problem geben, das macht avr-libc schon immer so.
Vielen Dank, ich habe es jetzt entsprechend abgeändert und es läuft im Simulator. Den Zähler stoppe ich jetzt mit: TCCR0 = ~(1 << CS01); und mit TCCR0 = (1 << CS01); schalte ich ihn wieder ein. Dann ist das setzen der Interrupt-Maske ja überfällig, mache es trotzdem. Schöne Weinachten und einen guten Rutsch.
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.