Auf dem Steckbrett jedoch leuchtet die LED, welche von PB4 nach GND
geschaltet ist, durchgehend schwach, ohne irgendwie zu blinken. Da ich
ein Einsteiger im Thema AVR-Mikrocontroller bin, wollte ich fragen, ob
jemand mir mit diesem Problem helfen kann.
Ich sehe keinen Fehler.
Wenn eine LED schwach glimmt hat man typischerweise vergessen, den Pin
als Ausgang zu konfigurieren. Aber das ist hier offenbar nicht der Fall.
Sicher, dass die LED an PB4 hängt und dass dieser Pin nicht defekt ist?
Ich hoffe, du hast der LED einen Vorwiderstand spendiert.
Marc V. schrieb:> Es läuft 10x schneller über, also alle 21,845ms.
Und mit 46Hz siehst du kein flackern, sondern nur schwaches (?)
leuchten.
Beim Tiny13 brauchst du übrigens mit PINB weniger code/register
und bist auch schneller, was in der ISR vorteilhaft sein kann.
Armin W. schrieb:> Ich habe nun einen 220 Ohm Vorwiderstand vor die LED geschaltet und den> Codevorschlag>
1
>PINB=(1<<PB4);// toggle LED pin
2
>
> übernommen, aber es tut sich nichts..Marc V. schrieb:> Marc V. schrieb:>> Es läuft 10x schneller über, also alle 21,845ms.>> Und mit 46Hz siehst du kein flackern, sondern nur schwaches (?)> leuchten.
Es tut sich schon etwas, nur ist es zu schnell als das man es sehen
kann.
Probiere mal folgendes:
====================================================================
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
volatile uint8_t isr_cnt = 0;
5
6
ISR(TIM0_OVF_vect) {
7
if(isr_cnt++ > 10) {
8
PINB = (1 << PB4); // toggle LED pin
9
isr_cnt = 0;
10
}
11
}
12
13
int main(void) {
14
DDRB |= (1 << DDB4); // set LED pin as OUTPUT
15
PORTB = 0b00000000; // set all pins to LOW
16
TCCR0B |= (1 << CS02)|(1 << CS00); // set prescaler to 1024 (CLK=1200000Hz/1024/256=4Hz, 0.25s)
Marc V. schrieb:> Probiere mal folgendes:> ====================================================================#inc lude> <avr/io.h>> #include <avr/interrupt.h>>> volatile uint8_t isr_cnt = 0;>> ISR(TIM0_OVF_vect) {> if(isr_cnt++ > 10) {> PINB = (1 << PB4); // toggle LED pin> isr_cnt = 0;> }> }>> int main(void) {> DDRB |= (1 << DDB4); // set LED pin as OUTPUT> PORTB = 0b00000000; // set all pins to LOW> TCCR0B |= (1 << CS02)|(1 << CS00); // set prescaler to 1024> (CLK=1200000Hz/1024/256=4Hz, 0.25s)> TIMSK0 |= (1 << TOIE0); // enable Timer Overflow interrupt> sei(); // enable global interrupts> while(1) {> }> }> ====================================================================
Hab ich versucht, ohne Wirkung.
Auch das einsetzen eines anderen Vorwiderstandes (10K) und einer anderen
LED änderten nichts.
Könnte es daran liegen, das ich die gesamte Schaltung an den VCC/GND
Pins eines Arduino Unos betreibe?
Stefanus F. schrieb:> Marc V. schrieb:>> Es läuft 10x schneller über, also alle 21,845ms.>> Wie kommst du darauf?
Heute ist nicht mein Tag.
Ich habe glatt mit 12MHz gerechnet.
See ya, gehe schlafen, genug Unfug für heute angerichtet.
P.S.
Armin W. schrieb:> Könnte es daran liegen, das ich die gesamte Schaltung an den VCC/GND> Pins eines Arduino Unos betreibe?
Nein.
Aber es könnte sehr wohl daran liegen, dass sich der Tiny dauernd
resetet.
Armin W. schrieb:> Ich habe mal zum Test ein Blink-Programm ohne Timmer-Interrupt mit der> delay-Funktion geschrieben, was anstandslos funktioniert.
Na und, ich habe das alte Programm (von mir) ausprobiert, es läuft
ohne Probleme, nur eben in 2,5s Takt.
Interrupt kann bestimmt nicht daran Schuld sein, aber das dein Tiny
dauernd in den Reset gesprungen ist, das kann sehr wohl sein.
Armin W. schrieb:> #define F_CPU 10000000UL
Da ist doch was faul. Entweder läuft dein Tiny13 im Auslieferzustand,
dann sind es 9,6 MHz geteilt durch 8, also 1,2 MHz. Oder du hast an den
Fuses schon rumgefummelt, dann sind es entweder 9,6 MHz ohne die CKDIV8
Fuse, oder 4,8 Mhz mit oder ohne CKDIV8 Fuse, das wären 4,8 Mhz resp.
500 kHz.
10 Mhz hingegen erreichst du nur mit einem externen Oszillator.
Bei meinem Attiny13 habe ich noch nie was an den Fuses verändert (wie
kann man die über avrdude auslesen?).
Aber auch bei einem anderen Programm, welches einen externen Interrupt
nutzt, leuchtet die LED die ganze Zeit schwach.
Könnte es sein, das ich die ganze Zeit ungewollt ein Interrrupt auslöse,
welcher keine ISR besitzt und deshalb den Attiny13 wie "neustartet"?
Ungenutzte ISR machen kein Problem.
Der Compiler erzeugt eine Sprungtabelle die ungenutzt sauber schliesst.
Zudem muss man Interrupts stets frei schalten in einem Register
Hast du rekursive Funktionsaufrufe oder dynamischer Speicher Management?
Armin W. schrieb:> Könnte ein fehlerhaftes Fuse-Bit solche Probleme verursachen?> Denn bei Marc V. funktioniert das Programm ja...
Nein, aber fehlerhaftes Aufbau schon.
Screenshot anbei, so geht es bei mir.
Nee, das Konzept ist falsch.
PORTB ^= (1 << PB4); // toggle LED pin
bedeutet PORTB lesen, aendern, schreiben.
nun sollte man erstens PINB lesen, nicht PORTB, und dann stimmen die
Spannungen nicht. Denn nur weil man eine Null schreibt, ist beim
Ruecklesen nicht unbedingt eine Null dort. Wir haben ja eine Diode.
Also ueber eine globat statische Zwischenvariable gehen.
also
volatile int ledstate=0;
interrupt() {
ledstate != ledstate;
portb = ledstate;
..
}
Den interrupt ueberpruft man am Besten mit einem Oszilloskop.
Beim Tiny13 reicht es, eine 1 ins PINB Register an die gewünschte Stelle
zu schreiben, dann toggelt der Pin.
1
PINB=(1<<PB4);
Das ist in Armins letztem Programm schon richtig gemacht.
'isr_cnt' kann auch eine static Variable in der ISR sein, wenn man ihren
Wert nur innerhalb der ISR benötigt.
Allerdings steht da immer noch
Armin W. schrieb:> #define F_CPU 10000000UL
was nicht stimmt.
Jetzt ist G. schrieb:> nun sollte man erstens PINB lesen, nicht PORTB, und dann stimmen die> Spannungen nicht. Denn nur weil man eine Null schreibt, ist beim> Ruecklesen nicht unbedingt eine Null dort. Wir haben ja eine Diode.
Das ist ja nun völliger Unsinn.
Matthias S. schrieb:> Allerdings steht da immer noch> Armin W. schrieb:>> #define F_CPU 10000000UL> was nicht stimmt.
Spielt erst eine Rolle, wenn der Compiler Berechnungen damit durchführt.
tut er in diesem Fall aber nicht. Nichtsdestotrotz gehört da natürlich
1,2MHz hingeschrieben. Denn die Fuses hat er ja nach eigener Aussage
nicht angefasst.
Andererseits ist die Sache doch schon längst geklärt:
Armin W. schrieb:> Es könnte am Breadboard liegen, denn auf einem anderen funktioniert die> Schaltung, wenn auch unzuverlässig (geht nur ab und zu).
Das Breadboard ist Scheiße. Und das zweite auch nicht besonders.
Wurde aber auch schon frühzeitig drauf hingewiesen:
Georg M. schrieb:> Armin W. schrieb:>> Auf dem Steckbrett …>> Da muss man aufpassen: schlechte Kontakte, fehlende Abblockkondensatoren> usw.
Ich habe den Fehler gefunden!
Schuld war weder Breadboard noch sonst was, ich habe bei der
Kompilierung
mit AVR-GCC als mmcu=t13 angegeben, da ich gelesen hatte, t13 steht für
den Attiny13.
Das war so wies aussieht jedoch falsch, den mit mmcu=attiny13 läuft es
tadellos!
Wie markiere ich den Thread als solved?
Armin W. schrieb:> mit AVR-GCC als mmcu=t13 angegeben, da ich gelesen hatte, t13 steht für> den Attiny13.
Dann sollte aber eine Fehlermeldung erfolgen:
main.c:1: error: MCU 't13' supported for assembler only
Armin W. schrieb:> Wie markiere ich den Thread als solved?
Bearbeite Deinen Eröffnungsbeitrag.
Es gibt da einige Abkürzungen, die ich auch schon öfter gelesen habe.
Man muss sie nicht benutzen.
Ich benutze immer einfach den richtigen Namen des Mikrocontrollers (so
wie attiny13a) und genau den selben String benutze ich auch für avrdude.
Armin W. schrieb:> Bei meinem Attiny13 habe ich noch nie was an den Fuses verändert (wie> kann man die über avrdude auslesen?).
mit
1
avrdude -p attiny13 -c avrispmkii -P usb -v
würde bei einem via USB angeschlossenen AVR ISP MKII der angeschlossene
Mikrocontroller ausgelesen werden samt Fuses. Ist es kein Attiny13 gibts
ne Fehlermeldung von avrdude ;)