Die Sache mit ISR() bzw. der alten Ausführung Signal(...) ist eine Compilerspezifische Erweiterung von C - im C Standard fehlt das einfach.
Die Timer bei den AVRs sind schon recht ähnlich, aber halt nicht alle gleich. Entsprechend unterscheidet sich die Programmierung der Register etwas. Für genau so etwas muss dann auch ein Anfänger mal ins Datenblatt schauen, wenn man nicht gerade den µC nutzt der auch im Tutorial beschrieben wird. Die AVR Datenblätter sind da sogar noch relativ übersichtlich. Wichtig ist vor allem die Registerbeschreibung, also Abschnitt 11.9 im Datenblatt zum Tiny24/44/84. Da findet man dann z.B. Das im Register TCCR0A der CTC Mode ausgewählt werden kann, aber nicht der Prescaler. Der Prescaler steht dann in TCCR0B. Das Register um dann den Interrupt zu Timer0 einzustellen heißt beim Tiny84, wie bei fast neueren AVRs dann TIMSK0.
Für die Anwendung hier ist der 8 Bit Timer 0 sowieso keine gute Wahl ist. Der 16 Bit Timer 1 ist da deutlich besser, weil da die 10000 auch ins Compare Register passen. .
Hallo,
danke erst mal für euer Info's.
@ oberallgeier = für dass, das hier jeder 2 den Code aufbauen kann tut es aber keinerMit deinem Code kann ich leider nichts anfangen. Zu viel durcheinander drin.
Klar kann der Tiny84 20MHz, aber laut Datenblatt erst ab 4,5V. Ich nutze nur 3V.
@ Wsk8 = Danke für dier Tutorials, werde sie durcharbeiten. Mal schauen ob dich dann schlauer bin...
@ Besserwissi = Habe ganz unten im Datenblatt die gesamte Registerbeschreibung gefunden. Wie man so was vermeidlich unwichtiges ganz nach hinten ins DB macht verstehe ich auch nicht.
Deine Angaben kann ich bestätigen. Scheinbar muss man die Register kreuz und quer ohne Sinn verwenden damit man die gewünscht Funktion erhält![]()
Ich habe aus den Angaben folgenden Code generiert:
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
unsigned char wert;
ISR(SIG_OUTPUT_COMPARE0B)
{
wert++;
}
//----------------------------
int main(void)
{
TCCR0B= (1<<CS00)&&(1<<CS02)&&(1<<WGM02); CPU Takt/1024
OCR0B= xxx ;
TIMSK0 = (1<<OCR0B);
sei();
wert=0;
//------------------------------
while(1)
{
if (wert=1)
{
DDRA = 0x06;//wenn Zählerwert 1 erreicht ist gib 1 als BCD an 7-Segmentanzeige aus
}
}
//-----------------------------
}
Vergleichswert muss ich noch schaue wie man den angibt. Im Datenblatt steht "(CSn2:0 = 7)" CS = Vergleichswert, n = Variable von 1bis..., aber was 2:0=7 bedeutet weis ich nicht.
Wird ja im Datenblatt nirgends erwähnt was ATMEL's fiktive Rechenoperationen bedeuten.
Kann mir wenigstens jemand sagen wo der Fehler in meinem Code ist?
Geändert von ooweberoo (28.02.2014 um 17:23 Uhr)
Mal schnell programmiert, kA obs stimmt.Code:#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 1000000UL // 1MHz volatile uint16_t timerVal = 0; void InitTimer() { TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); // CTC Mode, CLK/1024 TIMSK1 = (1<<OCIE1A); // Output Compare A Match Interrupt Enable OCR1A = 10000; // Top value } int main(void) { timerVal = 0; InitTimer(); sei(); while(1) { if(timerVal == 1) { DDRA = 0x06; timerVal = 0; } } return 0; } ISR(TIMER1_COMPA_vect) { timerVal++; }
mfg
Die Schreibweise mit dem 2:0 steht für die Bits 0 bis 2. In dem Beispiel (CSn2:0 = 7) also das CSn2, CSn1 und CSn0 zusammen als Binärzahl interpretiert 7 ergeben, also alle 3 Bits auf 1.
Hallo,
@ Besserwissi : Das hört sich plausibel an. Jetzt kann man das auch verstehen. 1, 2, 3 --- BIN 111, DEZ 7, HEX 7. Komische das so zu schreiben aber OkDanke
@ Wsk8: Danke erstmal für den Code. Hab in bei meinem ATtiny ausprobiert aber leider ohne Funktion. Keine Fehler im Code aber eine Warnung "TIMER0_COMPA_vect" appears to be
amisspelled Signal handler [enabled by default].
Mittlerweile nach den Tutorials und dem Datenblatt vom ATtiny84 bin ich zu folgender Lösung gekommen (wie macht man das Codefenster?)
8 Bit Timer0, Vorteiler 8, 125ms interupt.
Code:
[-------------------------------------------------------------------------------------------------------------------------
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
volatile unsigned int millisekunden;
int main(void)
{
TCCR0B = (1<<WGM02) && (1<<CS01); // CTC Modus, Vorteiler 8, // ((1000000/8 )/1000) = 125
OCR0B = 125-1; // TCNT0 = OCR0A = 125-1
TIMSK0 = (1<<OCIE0B);
sei();
while(1)
{
}
}
ISR(TIMER0_OVF_vect)
{
millisekunden++;
if(millisekunden == 1000)
{
DDRA = 0x06;
}
}
]------------------------------------------------------------------------------------------------------------------------------------------------
Dieser Coder erzeugt aber auch eine Warnung "TIMER0_OV_vect" appears to be amisspelled Signal handler [enabled by default].
Wenn man nur irgendwo mal ne Lister aller ISR Befehle hätte... kann sein das mein µC den Befehl nicht bearbeiten kann oder so.
Wenn ich nur wüsste ob TCCR0B & OCR0B zueinander stimmen den im Netz wird TCCR0A verwendet???
Gibt es den Timer0 A und Timer0 B?
Kann jemand nochmal helfen???
Verstehe es nicht![]()
![]()
?????????????????
Geändert von ooweberoo (02.03.2014 um 08:57 Uhr)
In meinem Code gibts aber kein "TIMER0_COMPA_vect"Keine Fehler im Code aber eine Warnung "TIMER0_COMPA_vect" appears to be amisspelled Signal handler
wie macht man das Codefenster?
Im Editor "#" anklicken
Da in deinem Code auch nichts initialisiert ist, wirst du auch vermutlich nichts sehen. LED etc um eine Änderung wahrzunehmen wäre nicht schlecht...
mfg
Geändert von Wsk8 (28.02.2014 um 23:16 Uhr)
Die Liste der zur verfügung stehenden Interruptvektoren steht bei GCC in den µC spezifischen files, die über eine paar Umwege (den µC aus der Umgebungsvariable suchen) eingebunden werden, über #include <avr/io.h>
Für den Tiny84 ist das File
iotnx4.h Im Verzeichnis von GCC avr/Include/avr/ - die Interruptvectoren stehen ganz unten im File.
Der gesuchte ist hier TIM0_COMPA_vect bzw. TIM0_OVF_vect . Wieso da jemand die Namen ander als etwa beim Mega32 gewählt hat, kann ich auch nicht sagen - ist irgendwie unpraktisch.
Ich finde, du musst viel ruhiger werden. Oberallgeier hat dir so ein top Beispiel gegeben. Versuch das doch einfach mal zu verstehen. Druck es aus, wenns dir hilft, lösche halt die Zeilen raus, die dich stören, aber versuche zu verstehen, was dort eigentlich passiert. Hier alles mit unbrauchbar zu betiteln, nur weil es nicht speziell für dich geschrieben ist, ist schon ziemlich anmaßend. So viele Leute, die mit den Datenblättern zurecht kommen und es stimmt, AVR Datenblätter sind ansich gut aufgeräumt. Versuche einfach mal den Code von Oberallgeier zu verstehen, versuche herauszufinden, welche Infos er aus dem Datenblatt hat, und wo sie stehen. Wenn du einzelnes nicht findest, darfst du hier gern nachfragen, da gibt es dann Hilfsbereite, die dir sagen, wo du es findest. Und ganz schnell wirst du feststellen, das alles doch ganz logisch aufgebaut ist. C hat mit AWL einer sps nunmal rein gar nix zu tun. Evtl hilft es auch, wenn du erstmal ein reines C-Tutorial ansiehst, zumindest die ersten paar Themen, das du erstmal C-spezifische Dinge verstehst, und dann später kannst du dich mit den Besonderheiten des C eines AVR's bekannt machen.
Die Begriffe sind auch im Datenblatt zu finden, unter der Kategorie Interrupts. Es war also Atmels Idee mit den unterschiedlichen Namen.
Dennis
Ich studiere die Wirkung der Sonnenstrahlen auf das Liebesleben der Pflastersteine
Lesezeichen