Hallo Leute,
ich befasse mich grade mit der C-Programmierung. Dafür nutze ich einen
atmega8. Ich versuche gerade eine LED am Pin12 (PD6) vom Port D im
1-Sekunden-Takt zu toggeln. Leider gelingt mir das nicht und ich weiss
nicht an was es liegt. Ich versuche schon seit gestern meinen Fehler zu
finden und binn schon einige Forenbeiträge und Tutorials durchgegangen.
Leider ohne ergolg. Nun habe ich versucht in der IST die LED nur
einzuschalten, umm einen Fehler im restlichen Code aus zu schließen. Das
funktioniert aber auch nicht.
Ich hoffe, ihr könnt mir dabei helfen.
Hier ist mein bisheriger Code:
1
//LED1 = Pin11 PD5
2
//LED2 = Pin12 PD6
3
//Taster 1 = Pin4 PD2
4
//Taster 2 = Pin5 PD3
5
//Taster 3 = Pin6 PD4
6
7
/*****************
8
Header
9
******************/
10
11
#include<avr/io.h>
12
#include<avr/interrupt.h>
13
#include<stdlib.h>
14
#define F_CPU 1000000
15
16
/*****************
17
initialize timer, interrupt and variable
18
*****************/
19
voidtimer0_init()
20
{
21
// Timer 0 konfigurieren
22
TCCR0|=(1<<CS00)|(1<<CS02);// Timer 0 mit Prescaler 1024
Christian S. schrieb:> sei(); // hier wird das gemacht.
Hier wird was gemacht? (ist aber egal)
Du hast vergessen, per setzen von TIMSK0 den Timer-Interrupt auch zu
aktivieren
Wie sind die Taster angeschlossen?
Du benötigte bestimmt pullup oder pulldown Widerstände.
Du kannst die Eingänge und Ausgänge im Debugger testen. Dort ist das
Port Register zu sehen.
Schalte mal den Timer0 Overflow im Register TIMSK ein.
1
TIMSK |= (1<<TOIE0); // ich glaube, daß ist so richtig, habe es jetzt nicht nachgelesen
Mit deiner F_CPU und dem Prescaler wird die ISR mit 3,8 Hz aufgerufen.
F_CPU / (PRESC * 8bit Zählergröße) = 3,81
Dann kannst Du mit einer Zählervariable in der ISR noch weiter teilen,
und so nahe an 1 Hz kommen. Genauer wird es, wenn Du den nächstkleineren
Prescaler nimmst und dafür den Softwarezähler größer wählst (oder
eleganter, den Zähler im CTC-Mode betreiben).
Zum Toggeln eines Pins reicht die Zeile in der ISR
Christian S. schrieb:> DDRD = 0x60; //PortD 0-5 ->Eingang ;6 und 7 Ausgang
beißt sich mit
Christian S. schrieb:>//LED1 = Pin11 PD5>//LED2 = Pin12 PD6>//Taster 1 = Pin4 PD2>//Taster 2 = Pin5 PD3>//Taster 3 = Pin6 PD4
letzteres ist zwar nur ein Kommentar, läßt aber vermuten, daß Du Deine
Pinbelegung und LED-Anschlüsse nochmal überprüfen solltest.
Hallo:
@ Michael Reinelt: mit sei(); habe ich die globalen interruots
zugelassen
"// hier wird das gemacht." ist ein Copy&paste Fehler
@ no AVR: ich verwende das Entwicklungsboard von Pollin-Elektronic mit
der Bestellnummer: 810 038
@ mullwark:Ich habe die Zeile TIMSK |= (1<<TOIE0); unter die Zeile
TCCR0 |= (1<<CS00)|(1<<CS02); geschrieben. Das brachte aber keine
Änderungen
Kann ichden PortD nichtmehr verwenden, wenn ich den Timer0 verwende?
Wenn ja, was ist mit Timer2?
Grüße
Christian S. schrieb:> Nochmal Hallo,>> die Belegung im Kommentar ist meine HW-Beschaltung.> Also:>>//LED1 = Pin11 PD5>>//LED2 = Pin12 PD6>>//Taster 1 = Pin4 PD2>>//Taster 2 = Pin5 PD3>>//Taster 3 = Pin6 PD4>> Was ist an DRD = 0x60; falsch?? Ohne Timer funktioniert der Code
weil du schrubst:
> DDRD = 0x60; //PortD 0-5 ->Eingang ;6 und 7 Ausgang
Also was jetzt? entweder 5 und 6 Ausgang, oder 6 und 7
Generell: gewöhn dir sowas an:
#define LED1_PORT PORTD
#define LED1_DDR DDRD
#define LED1_BIT PORTD5
und ab dann arbeitest du nur mehr mit den LED_* Symbolen, keine PORT,
DDR, und vor allem keine Hex-Zahlen mehr.
Zunächst mal sehe ich in Deinem ersten Code keine wirklich
substantiellen Probleme, bis auf das fehlende setzen von TIMSK.
Die einzige Fehlermöglichkeit die ich konkret sehe, ist die Frage ob Du
die Jumper JP3 bis JP7 gesetzt hast. Es gibt auch noch ein paar andere
Fehlermöglichkeiten, daher:
Versuche zunächst einmal einfach nur die LEDs einzuschalten.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<stdlib.h>
4
5
#define F_CPU 1000000
6
7
#define LED1 PD5
8
#define LED2 PD6
9
10
intmain(void)
11
{
12
DDRD=0x60;// PortD 0-4 u. 7 Eingang, 5 und 6 Ausgang
13
PORTD|=(1<<LED1)||(1<<LED2);// LED1 und LED2 werden eingeschaltet
14
15
while(1)
16
;
Nun sollten die LEDs leuchten. Solange das nicht geht, brauchst Du sonst
nichts zu versuchen.
Falls das nicht geht, dann poste mal ein Foto von Deinem Aufbau.
Bitflüsterer schrieb:> dies und jenes
F_CPU gehört ins makefile (sofern sowas existiert) ansonsten vor alle
includes (tlw. verlassen die sich drauf)
#define LED1 PD5
mag ich persönlich gar nciht. Wenn dann die ganze latte mit PORT, DDR,
PIN (sofern benötigt) und Bit.
Michael Reinelt schrieb:> Bitflüsterer schrieb:>>> dies und jenes>
Das ist kein Zitat von mir! In dem ganzen Thread kommt diese Phrase
nicht vor.
Abgesehen davon, mag das wohl alles sein, spielt aber erstmal keine
Rolle. Meinst Du nicht auch?
Hallo,
@ Michael Reinelt: meine Pinnbelegung geht ja von PD0 bis PD7
die beiden LEDs hängen an Pin11(LED1)PD5 und Pin12(LED2)PD6.
Binär ist dass die 00110000....ok Fehler meinerseits müsste 0x30
heissen.
@Bitflüsterer: die LEDs habe ich im ersten Schritt leuchten lassen. Das
hat funktioniert.
Das mit den Definitionen ist eine gute Idee, vorallem wenn der Code
länger und somit unübersichtlicher wird.
Grüße
Bitflüsterer schrieb:> Michael Reinelt schrieb:>> Bitflüsterer schrieb:>>>>> dies und jenes>>> Das ist kein Zitat von mir! In dem ganzen Thread kommt diese Phrase> nicht vor.
Echt, hey? Kann ich mir nicht vorstellen...
> Abgesehen davon, mag das wohl alles sein, spielt aber erstmal keine> Rolle. Meinst Du nicht auch?
Nein, meine ich nicht. Wenn man einen Anfänger vor sich hat, sollte man
dem keinen schlechten Code vorwerfen.
Christian S. schrieb:> @ Michael Reinelt: meine Pinnbelegung geht ja von PD0 bis PD7> die beiden LEDs hängen an Pin11(LED1)PD5 und Pin12(LED2)PD6.> Binär ist dass die 00110000....ok Fehler meinerseits müsste 0x30> heissen.
Darüber solltest du nochmal nachdenken...
Christian S. schrieb:> Das mit den Definitionen ist eine gute Idee, vorallem wenn der Code> länger und somit unübersichtlicher wird.
Nein, das ist immer eine gute Idee. So klein kann das Programm gar
nicht sein, das ist immer sinnvoll.
@ Michael Reinelt: des is aber wieder der Wert vom Anfang meines
Posts???
____________________
|Pin |7|6|5|4|3|2|1|0|
|Bin |0|1|1|0|0|0|0|0|
|Hex | 6 | 0 |
Habe ich da was verdreht?
Gruß
Christian S. schrieb:> @Bitflüsterer: die LEDs habe ich im ersten Schritt leuchten lassen. Das> hat funktioniert.
Super. OK. Dann lass uns mal probieren, ob Deine LEDs auf Deine Taster
reagieren.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<stdlib.h>
4
5
#define LED1 PD5
6
#define LED2 PD6
7
8
#define TASTE1 PD2
9
#define TASTE2 PD3
10
#define TASTE3 PD4
11
12
intmain(void)
13
{
14
DDRD=(1<<LED1)||(1<<LED2);// PortD 0-4 u. 7 Eingang, 5 und 6 Ausgang
15
16
while(1){
17
if(PIND&(1<<TASTE1))
18
PORTD|=(1<<LED1);// LED1 wird eingeschaltet
19
else
20
PORTD&=~(1<<LED1);// LED1 wird ausgeschaltet
21
if(PIND&(1<<TASTE2))
22
PORTD|=(1<<LED2);// LED2 wird eingeschaltet
23
else
24
PORTD&=~(1<<LED2);// LED2 wird ausgeschaltet
25
}
Sowas wie das Prellen der Tasten lassen wir erstmal weg. Wenn Du eine
der beiden Tasten gedrückt hälst, dann muss die entsprechende LED dauern
leuchten. Sobald Du sie loslässt, sollte sie wieder ausgehen.
Christian S. schrieb:> @ Michael Reinelt: des is aber wieder der Wert vom Anfang meines> Posts???> ______________________> |Pin |7|6|5|4|3|2|1|0|> |Bin |0|1|1|0|0|0|0|0|> |Hex | 6 | 0 |>> Habe ich da was verdreht?
Jetzt nicht mehr.
Denk nochmal über die #define Methode nach. Vielleicht kommst du dann
zum Schluss, dass dann kein nachdenken mehr notwendig ist. Weil
nachdenken verbraucht Energie und verursacht Kopfschmerzen, deshalb
sollte man jede Möglichkeit nützen, nicht nachdenken zu müssen :-)
Christian S. schrieb:> if(PIND & (1<<PD2) || PIND & (1<<PD3 ) || PIND & 0x10) //Taster1
Gewöhn dir klammern an. Oder weisst du asuwenig aus dem Stehgreif und
kannst mit Quellen belegen, dass & stärker bindet als ||?
Siehe oben. Nachdenken vermeiden.
Christian S. schrieb:> Hallo Bitflüsterer,> Das habe ich auch schon erfolgreich ... versucht
Schön. Das hättest Du aber doch mal im ersten Post schreiben sollen.
Leider schreibst Du ja nur, das "es" nicht funktioniert. Wir konnten
also nicht wissen, an was es nun genau liegt.
OK. Es bleibt also der Timer.
Das setzen des TIMSK ist Dir ja schon genannt worden. Mit dem Code oben
wird die LED einfach nur immer wieder eingeschaltet. Sie wird also,
ständig leuchten - unabhängig davon, was Du mit den Tastern tust.
Was genau funktioniert denn nun nicht? Präziser: Was erwartest Du und
was geschieht?
HallovMichael Reinelt,
ich verstehe die nachfolgenden Sätze von dir nicht. Du schreibst "
> Jetzt nicht mehr.> Denk nochmal über die #define Methode nach. Vielleicht kommst du dann> zum Schluss, dass dann kein nachdenken mehr notwendig ist. Weil> nachdenken verbraucht Energie und verursacht Kopfschmerzen, deshalb> sollte man jede Möglichkeit nützen, nicht nachdenken zu müssen :-)"
Wieso jetzt nicht mehr? dass ist doch der selbe Hexwert wie im ersten
Tread?
Verstehe ich das richtig, dass ich die Portbelegung als define
hinterlegen soll?
Gruß
@ Bitflüsterer:
Ich habe es nicht weiter erwähnt, da ich dachte, dass es reicht, wenn es
im Code steht.
In diesem Code wollte nur testen, ob grundsätzlich der Interrupt
aufgerufen wird. Da die LED aber aus bleibt, gehe ich davon aus, dass
die Rutine gar nicht aufgerufen wird
Gruß
Im AVRStudio Version 4, gibt es drei(vier) Stellen, an denen das gesetzt
werden kann.
1. Beim anlegen eines Projektes
2. In dem Dialog "Project->Configuration Options", dort im Tab "General"
rechts neben dem Punkt "Device".
3. Für den Simulator in dem Dialog "Debug->Select Platform and Device".
4. Beim Programmieren. Die Details hängen vom verwendeten Adapter und
seiner Software ab. Die Hilfe zum AVRStudio und/oder dem Adapter resp.
der Software sollte das genau erklären.
Christian S. schrieb:> @ Bitflüsterer:> Ich habe es nicht weiter erwähnt, da ich dachte, dass es reicht, wenn es> im Code steht.
Nun, wir konnten dennoch nicht wissen, ob Du die einzelnen Teile
getestet hattest. Es geht ja hier auch nicht nur um Softwaretests
sondern auch um Hardwaretests. Nebenbei gesagt: Sehr oft entstehen
Fehler weil Teile, die für sich genommen funktionieren, zusammengefügt
werden.
> In diesem Code wollte nur testen, ob grundsätzlich der Interrupt> aufgerufen wird. Da die LED aber aus bleibt, gehe ich davon aus, dass> die Rutine gar nicht aufgerufen wird>> Gruß
Und die LED bleibt auch aus, nachdem Du das setzen von TIMSK hinzugefügt
hast? Zeige mal den Code den Du aktuell verwendest.
Hallo,
ich habe gerade festgestellt, dass ich bei der erstellung eines Projekts
nicht nach dem verwendeten Clntroller gefragt werde und im makefile CU =
atmega128 steht. Kann ich das im Nachhinein ändern (nur da?).
Ich muss jetzt leider weg. Melde mich aber morgen wieder
Grüße und vielen Dank bisher
Hallo Bitflüsterer,
ich habe nur gefragt, da ich mir nicht sicher war, ob es evtl. sonst
noch Stellen gibt, an denen noch etwas geändert werden muss.
Ich habe meinen Code mit AtmelStudio 4.16 simuliert. Nach dem init des
timers 0 war der Haken bei TCCR0, CS02 zu sehen, den Haken bei CS00
konnte man nicht sehen, da dort "no clock source" drüber stand.
Danach habe ich auf Version 4.19 upgedatet und die AVR Toolchain
3.4.2-1573 neu installiert. Es stand dann über CS00 "running no
prescalling". Und jetzt, ohne dass ich bewusst an der Software etwas
geändert habe, stürzt das Programm vor der Simmulation ab.
Grüße