C Kleine Tischlampe bitte um Hilfestellung.

Hi Nicole,

Ich möchte in erster Linie mit Mikrocontroller arbeiten.
Also wäre es besser ein Buch über AVR zu kaufen ?

Wenn ja welches sollte ich wählen?

Das mit der Sprache ist meiner Meinung nach nicht so einfach.
Es sollte eine Sprache sein wo ich nicht erst 2 Seiten Schreiben muss bis die LED leuchtet :D

ich würde so wie gp177 oben im Beitrag #17 für den Einstieg Bascom und das Buch von Roland Walter empfehlen. Mit der Demo-Version von Bascom kannst du bereits ne Menge machen. Außerdem kann man in Bascom sehr einfach Assembler einbinden wenn es denn mal etwas hardwarenäher sein soll. Die Fortschritte in Bascom werden bei einem Programmieranfänger(in) wohl am größten sein. Die nicht hardwarenahen Befehle in Bascom wirst du auch in Pascal, Perl, PHP, C, Java, ... wiederfinden.

Aber auch das Buch von Stefan Hoffmann ist recht gut. Roland Walter geht meiner Meinung nach etwas intensiver auf die Innereien ein. Bei Stefan Hoffmann sind mehr Programmbeispiele drin an denen man sich orientieren kann und aus denen man Teile "klauen" kann ;)

Bascom-Bücher:

Roland Walter
AVR Mikrocontroller Lehrbuch
Einführung in die Welt der AAVR-RISC-Mikrocontroller am Beispieldes ATmega8
Denkholz Buchmanufaktur Berlin
ISBN 978-3-9811894-4-5
39,-eur

Stefan Hoffmann
Einfacher Einstieg in die Elektronik mit AVR-Mikrocontroller und BASCOM
Systematische Einführung und Nachschlagewerk mit vielen Anregungen
Books on Demand GmbH, Norderstedt
ISBN 978-3-8391-8430-1
54,-eur

Beide sind sozusagen "Standardwerke" für die AVRs und Bascom.

Gruß
Dino
 
Schau Dir mal Dirks Programm genauer an: das ist eigentlich kürzer als es wirkt. Durch die Leerzeilen und Kommentare wird es übersichtlicher und verständlicher. Er hätte auch die defines oben weglassen können, aber so kann schnell was an der Hardware umgeplant werden ohne daß dann Überall im Code was geändert werden muß. So was existiert eigentlich in jeder Sprache (alias in Bascom, .def/.equ in Assembler). Das ist "guter Stil", den man sich frühzeitig an gewöhnen sollte. Das macht es nämlich auf Dauer leichter.
Unter Bascom gibt's auch noch den Kühnel...
 
Hallo zusammen,

ich habe das ganze jetzt getestet und es funktioniert soweit auch alles.

Ich kan per Taster die LED an oder ausschalten.
Habe den Taster an PB1 am Attiny 13 angeschlossen ( zusätzlich noch an Masse )

Leider geht die LED nach den 2 Minuten nicht wieder automatisch aus ?
Warum ist das so ?

An bzw ausschalten per Taster geht immer.
Nur das automatische ausschalten funktioniert nicht.

Vielen Dank mal wieder.
 
Sicher, daß er nicht doch nach 16 Minuten abschaltet?
Hintergrund: Dirk geht laut Kommentaren von einem 9,6MHz-Takt aus. Der Tiny läuft out-of-the-Box auch mit dem internem 9,6MHz-Oszillator - allerdings ist default auch ein Vorteile von 8 aktiviert (CKDIV8-Fusebit), wodurch sich effektiv ein Takt von 1,2MHz ergibt. Der Controller ist dann also um Faktor 8 langsamer.

Hast Du die Fuse ausgenommenen?
 
Danke für deine Antwort.

Puh 16 Minuten habe ich nicht gewartet :D
Vielleicht 8-10 Minuten aber nicht länger.

Das einzige was ich Probiert habe war

#define F_CPU 20000000UL
Oder
#define F_CPU 10000000UL

Geändert hat sich dadurch nichts.

Mich hat gewundert warum der Dirk die Geschwindigkeit des Attiny13 nicht gesetzt hat ?
Muss man das nicht immer machen ?
Ich habe mal gelesen das man es machen sollte damit der Microcontroller besser läuft.

Ob das jetzt stimmt oder nicht weiß ich leider nicht.

Sonst habe ich an den Werten nichts geändert.

Vielen Dank
 
Das CKDIV ist eine Fuse, das hat mit dem eigentlichen Programm nichts zu tun, sondern muss beim Flashen gesetzt werden.
Die bleiben afaik auch immer die selben, zumindest bei den Programmern die ich nutze.

Kannnst es dir vorstellen wie 3 unabhängige Speicherbereiche. Fuses - Flash - EEPROM.

Wenn der Dividor gesetzt ist (Fuses) und du im Code 9,6MHz angibst (oder 4,8, je nachdem), denn sind möglicherweise sämtliche Timings in deinem Programm falsch, wie die Ausschaltzeit, die jetzt, sollte das der Fehler sein, 8x so lang ist.

Dein
#define F_CPU 20000000UL
erscheint mir auch falsch. 20 MHz?
Müsste es nicht
#define F_CPU 9600000UL // für 9,6 MHz
#define F_CPU 4800000UL // für 4,8 MHz
#define F_CPU 1200000UL // für 9,6 MHz + /8 Prescaler
#define F_CPU 600000UL // für 4,8 MHz + /8 Prescaler
sein?
 
Nur kurz weil es spät ist und ich mit meinem spartphone schreibe. Define fcpu benötigt man nicht. Am einfachsten man ändert den prescaler und oder den comparewert des timers. Mache ich morgen wenn zwischenzeitlich niemand sonst das übernimmt.
 
Gerade nochmals nachgeschaut.

Es ist CKDIV8 gesetzt.
Ist das vielleicht der Fehler ?
 
Ok das heißt also der Fehler ist das ich CKDIV8 gesetzt habe.

Somit stimmen die Werte des Timers nicht mehr.
Habe ich das richtig verstanden ?

Vielen Dank an euch.
 
Hier sind die neuen Timer-Initialisierungswerte für fcpu = 1,2MHz

geändert: Prescaler=64, CompareValue=187

[CCODE]
// Timer initialisieren // CompareA Interrupt, CTC: Clear Timer on Compare Match
// fcpu=1,2MHz, Prescaler=64, CompareValue=187 -> tisr= 10ms (10,027ms)

TCNT0 = 0;

OCR0A = 187;

TCCR0A = 1<<WGM01;

TCCR0B = (1<<CS01) | (1<<CS00); // Prescaler 64, Timer Start

TIMSK0 = 1<<OCIE0A; // CompareA Interrupt

[/CCODE]


#define F_CPU benötigt man nur, wenn auch Programmteile diese Definition benötigen. Zum Beispiel, wenn man util/delay.h einbindet.

Die Fehlergrenzen des RC-Oszillators sind größer, als die eines Quarzoszillators. Für genaues Timing (Uhr) ist der RC-Oszillator nicht so geeignet, reicht aber ja eventuell für die Anwendung.



Zum Testen kannst du auch einmal folgendes zusätzlich in die ISR des CompareInterrupts einfügen. Deine LED sollte dann mit 1Hz blinken:
[CCODE]// Test Start (Blinken 1Hz)
static uint8_t testtimer = 0;

if (testtimer > 0)
{
testtimer--;
} else {
testtimer = 50; // 500ms = 50 x 10ms
LED_TGL; // toggle LED
}
// Test Ende[/CCODE]



Dirk :ciao:
 
Jain...
Das die Fuse gesetzt ist ist nicht der Fehler, vielmehr paßt der Takt dann lediglich nicht mehr zum Rest der Rechnung. An welcher Stelle man das jetzt korrigiert, ist Wurst.
(per Fuse den MainClockPrescaler bereits beim Reset auf 1,
am Anfang des Programmes den MainClockPrescaler von 8 auf 1 umschalten (CLKPR=(1<<CLKPCE), CLKPR=0),
den TimerPrescaler von 1024 auf 128 ändern. Da es den nicht gibt, muß man auf 64 oder 256 ausweichen, entsprechend ist die CTC-Vorgabe von 93 auf 187 bzw 46 zu ändern.)

Mit "define fcpu" sagst Du C, mit welcher Taktfrequenz der Controller angeblich läuft. Das ist eine Compiler-Variable. C kann daraus dann Zeiten ausrechnen, zB um für Dich die Berechnung von irgendwelchen Werten aus einer vorgegebenen Baudrate, oder eben Warteschleifen und -takte wenn Du irgend'ne wait-Instruktion nutzt.
Der Controller kennt keine Zeiten, der arbeitet nur anhand des tatsächlich anliegenden Taktes. Ist der Takt langsamer oder schneller, ist auch der Controller langsamer oder schneller. Da Dirk die Werte für den Timer selbst vorgegeben hat, braucht er diese Variable nicht.
Mal 'ne Erklärung zu Dirks Werten:
Er ist von 9,6MHz MCU-Takt ausgegangen. Dieser Takt liegt durch 1024 geteilt am Timer - dieser läuft also mit 9,375kHz. Alle 94 Timer-Takte (93+1) läuft der Timer über und generiert einen Interrupt, also mit 9,375kHz/94=99,7Hz. In der Interrupt Service Routine wird nun eine Variable von 12000 decrementiert, bei 0 abgeschaltet. 99,7Hz/12000=8,3mHz. 1/8,3mHz=120s=2min.

(Man könnte theoretisch übrigens ebenso den 128kHz Watchdog-Timer als Systemtakt verwenden, den MainClockprescaler dann auf 128 ergibt einen effektiven Systemtakt von 1kHz. Mit 'nem 1024er Timer-Prescaler inkrementiert der Timer alle 1,024s. Setzt man den CTC-Compare auf 116, hat man alle 119,8s einen IRQ.
(allerdings muß der Programmer dann auf 'ne ISP-Frequenz von weniger als 1kHz/4=250Hz gesetzt werden können...))
 
Define fcpu benötigt man nicht.
Oops, mein Fehler, hatte ich nicht gesehen.
Beim überfliegen dachte ich du hast den Compiler die Werte ausrechnen lassen statt dies selber zu tun.

OT @LotadaC du immer mit dem Watchdog :D
Aber so genau scheint der nicht zu sein, da werden 4 Sekunden gerne mal zu 6.
 
Danke mal wieder für eure Hilfe.

Ich habe das von Dirk jetzt so übernommen.
Leider geht meine LED immer noch nicht aus :confused:

Auch habe ich festgestellt, wenn ich die Batterie anstecke fängt die LED an zu leuchten obwohl ich den Taster nicht gedrückt habe.

Ist das normal ?
Meiner Meinung nach habe ich alles richtig angeschlossen bzw verkabelt :)

Vielen Dank
 
Hi Nicole,

Ok das heißt also der Fehler ist das ich CKDIV8 gesetzt habe.

Somit stimmen die Werte des Timers nicht mehr.
Habe ich das richtig verstanden ?

du hast zwei Stellen für die Arbeitsgeschwindigkeit des Prozessors.

1. Das Programm:
Du sagts dem Compiler wie schnell der Prozessor arbeitet. Daraus berechnet er das Timing was er im Programm einhalten muß. Zum Beispiel für WAIT-Befehle oder für die Ansteuerung von LCDs, UART-Baudrate, usw. Beim Timer mußt du das selber über den Vorteiler und Zählerinhalt des Timers berechnen. Hier mußt du der Software sagen wie die Hardware aufgebaut ist.

2. Die Hardware und Fuses:
Du setzt einen bestimmten Quarz an den Prozessor oder benutzt den internen Takt. Über die Fuses kannst du noch mit CKDIV8 einen Teiler durch 8 aktivieren oder bei manchen über eine PLL den Takt vervielfachen. Von diesen Einstellungen weiß das Programm nichts. Du solltest hier also die Hardware so aufbauen wie die Software es erwartet.

Diese beiden Sachen müssen zusammenpassen.

- Wenn du der Software sagst, der Takt ist 1MHz und du packst nen 20MHz-Quarz dran, dann läuft alles 20fach zu schnell. ( 20MHz / 1MHz = 20fach )

- Wenn du der Software sagst der Takt ist 16MHz und du setzt nur nen 4MHz-Quarz dran, und aktivierst zusätzlich noch die CKDIV8 (4MHz / 8 = 500kHz) dann ist alles um das 32fache zu langsam. ( 16MHz / 500kHz = 32fach )

Gruß
Dino
 
Wenn die LED angehen soll, wird der entsprechende IO Pin nach GND gezogen, das heisst die Anode der LED muss an VCC angeschlossen werden (natürlich mit seriellem Widerstand).

Soll nicht-invertierende Logik verwendet werden, läßt sich das einfach in den defines für die LED ändern.

Ich kann hier leider nicht testen. Ein ganz einfacher Test, ist diese Sache mit dem Toggeln in der ISR, dann weiß man schon mal, ob die Zeitbasis stimmt und ob die ISR aufgerufen wird.


EDIT:
Wenn die Taste betätigt wird, dann wird auch die LED an/aus geschaltet?
 

Ich war mir nun nicht sicher, ob das wirklich mit der Beispielsoftware so ist, deshalb nochmal die Nachfrage.

Wenn das so geht, sollten schonmal die IP-Pins für LED und Taster richtig zugeordnet sein und auch die TimerISR aufgerufen werden, wenn auch nicht mit richtiger Periodendauer.


Wie schon geschrieben, zum Testen mal den folgenden Code in die ISR einfügen:

[CCODE]// Test Start (Blinken 1Hz)
static uint8_t testtimer = 0;

if (testtimer > 0)
{
testtimer--;
} else {
testtimer = 50; // 500ms = 50 x 10ms
LED_TGL; // toggle LED
}
// Test Ende[/CCODE]



oder ...


noch einen Schritt zurück und nur die Funktion der LED, sowie fcpu testen:

Am Programmanfang:
[CCODE]#define F_CPU 1200000
include <util/delay.h>[/CCODE]

Interrupts global deaktivieren, sei() entfernen:
[CCODE]// sei();[/CCODE]

vor die while(1) schleife:

[CCODE]while(1)
{
LED_ON
_delay_ms(500);
LED_OFF
_delay_ms(500);
}[/CCODE]


Damit dollte die LED mit 1Hz blinken.
 
Hallo zusammen,

ich schreibe auch jetzt mal auf was ich auf meinem Steckbrett verbaut habe :D

1. Batterie 9 Volt Block
2. Spannungswandler von 9 auf 5 Volt
3. Attiny13
4. Led mit einem Vorwiederstand.
5. Taster

Einen zusätzlichen Quarz habe ich nicht verbaut.
Geht es nicht ohne den Quarz?

Was mir gerade aufgefallen ist, schalte ich die LED per Taster aus.
Geht die LED nach 1,56 Minuten wieder automatisch an :stupid:

Ich glaube irgendwo ist hier ein Dreher im System :hmmmm:
 
Was mir gerade aufgefallen ist, schalte ich die LED per Taster aus.
Geht die LED nach 1,56 Minuten wieder automatisch an :stupid:

Ich glaube irgendwo ist hier ein Dreher im System :hmmmm:

Die Anode der LED ist somit an den IO-Pin angeschlossen ... "nicht invertierende Logik".

Dann ersetze

[CCODE]#define LED_ON LEDPORT &= ~(1<<LED); // Pin low
#define LED_OFF LEDPORT |= 1<<LED; // Pin high
[/CCODE]

durch

[CCODE]#define LED_ON LEDPORT |= 1<<LED; // Pin high
#define LED_OFF LEDPORT &= ~(1<<LED); // Pin low
[/CCODE]
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)