Hallo, liebe Gemeinde ;-)
... ich arbeite mich gerade in Microcontroller ein und habe mithilfe
eures großartigen AVR-Tutorials sogar schon ein erstes kleines
Testprogramm auf mein "myAVR-MK3 Entwicklungsboard" geladen.
1
#define F_CPU 16000000
2
3
// Einbindung von benötigten Header-Dateien für:
4
#include<stdint.h> // standardisierte Datentypen
5
#include<avr/io.h> // Registernamen
6
//#include <util/delay.h>
7
8
// Deklaration von Variablen
9
uint8_tbtn1;
10
uint8_tbtn2;
11
uint8_tbtn3;
12
uint8_tbtnJoyL;
13
uint8_tbtnJoyR;
14
uint8_tbtnJoyU;
15
uint8_tbtnJoyD;
16
uint8_tbtnJoyX;
17
18
intmain(void){
19
20
// alle Anschlüsse der jeweiligen Ports als Ausgänge einstellen
21
DDRB=0xff;
22
DDRL=0xff;
23
24
// die Werte der Ausgänge festlegen ("0" bzw. "1"; s.a. http://www.mikrocontroller.net/articles/Bitmanipulation)
// ... und anschließende Statusabfrage der Taster-Zustände
59
if(btn1==0){
60
61
PORTL=0x00;
62
PORTL|=(1<<PL7);
63
}
64
65
elseif(btn2==0){
66
PORTL=0x00;
67
PORTL|=(1<<PL6);
68
}
69
70
elseif(btn3==0){
71
PORTL=0x00;
72
PORTL|=(1<<PL5);
73
}
74
75
76
elseif(btnJoyL==0){
77
78
}
79
elseif(btnJoyR==0){
80
81
}
82
elseif(btnJoyU==0){
83
84
}
85
elseif(btnJoyD==0){
86
87
}
88
elseif(btnJoyX==0){
89
90
}
91
}
92
93
return0;
94
}
Nun,... es läuft soweit eigentlich auch, nur verstehe ich nicht ganz,
warum bei Abfrage meiner Taster, das "High"-Signal mit "0" gleichgesetzt
ist. Sprich: Bei gedrücktem Taster soll die jeweils zugeordnete LED
geschaltet werden - die LED wird aber nur bei Tast-Signal "0"
aktiviert?!??? Und dies, obwohl das Grundgerüst aus dem Tutorial stammt.
Jemand vielleicht eine Ahnung, wo der Fehler steckt?
Die andere große Frage ist... ich hab (wie man ja im Code sieht) auch
eine kleine PWM gebastelt, und dabei mal das Datenblatt des atMega2560
gelesen. Ich weiß nicht ganz, ob ich es richtig verstanden habe, aber
gibt es bei diesem µC nur einen einzigen Ausgang mit ein em
PWM-Signal??? (ich frage, weil ich gern eine RGB-Steuerung schreiben
würde. Kennt sich irgendjemand genauer mit diesem Board aus?
MfG, Marcel
Marci schrieb:> // PullUp-Festlegung der Eingänge (Taster)> PINK = 0xff;
Das ist falsch.
1
DDRK = 0x00;
2
PORTK = 0xff;
Mit PINK = 0xff; wäre mir das zu heikel. Wenn di das PIN-Register
beschreibst , werden im PORT-Register die entsprechenden Bits
getoggelt.
mfg mf
PS: dein "invertierte Logik" Problem sag ich dir: deine Taster schalten
nach Masse. Klar, dass du bei gedrücktem Taster eine 0 einliest.
Hi
>Nun,... es läuft soweit eigentlich auch, nur verstehe ich nicht ganz,>warum bei Abfrage meiner Taster, das "High"-Signal mit "0" gleichgesetzt>ist.
Das hängt von der Beschaltung der Taster ab. Wenn die Portleitung über
einen Pull-Up-Widerstand (kann auch der interne sein) bei offenem Taster
auf H gezogen wird und der Taster nach GND schaltet dann, entspricht es
deiner beschriebenen Logik.
>und dabei mal das Datenblatt des atMega2560>gelesen. Ich weiß nicht ganz, ob ich es richtig verstanden habe, aber>gibt es bei diesem µC nur einen einzigen Ausgang mit ein em>PWM-Signal???
Der ATMega2560 hat vier 8-Bit und zwölf 16-Bit PWM-Kanäle.
MfG Spess
Hui... ihr seid´s ja schnell!;-))
Danke, hab´s jetzt soweit abgeändert.
@spess53:
Soweit wußte ich das auch. Ich hab nur ein Problem damit, die
Ausgangspins dafür zu finden.
Ich hab´ nun zwar nach ein paar Stunden zumindest mal 6 OCn-Pins
(scheinbar die Ausgangspins von den PWMs) ausfindig gemacht und
teilweise auch getestet (OC1A auf PB5 und OC5A auf PL3)...:
1
// Grundeinstellung der Timer/Counter: als nicht-invertierende 10-Bit PWMs
2
TCCR1A=(1<<COM1A1)|(1<<WGM11)|(1<<WGM10);
3
TCCR5A=(1<<COM5A1)|(1<<WGM51)|(1<<WGM50);
4
// Generierung eines Taktes von CK/1024
5
TCCR1B=(1<<CS12)|(1<<CS10);
6
TCCR5B=(1<<CS52)|(1<<CS50);
7
// Grundeinstellung des Signals (Top- & Compare-Wert):
8
// ICRn = Pulsbreite; OCRnx = Restdauer (jeweils in Relation zur Taktlänge)
9
ICR1=512;OCR1A=512;
10
ICR5=512;OCR5A=512;
... aber wo sind dann die anderen (mind.) 6 Kanäle/Pins, wenn es doch
ganze 12 16-Bit-Kanäle gibt?
Ich muß gestehen, dass das Datasheet leider ein großes Mysterium für
mich ist, da mein Englisch einfach misserabel ist.
LG, Marcel
Ps.: Zudem würde ich gerne wissen, wie man z.B. folgendes richtig
schreiben könnte:
1
//orig.:
2
TCCR1A=(1<<COM1A1)|(1<<WGM11)|(1<<WGM10);
3
//neu: (wobei nPWM eine Variable mit der jeweiligen PWM-Nr. sein soll, um den Programmauflauf etwas übersichtlicher zu gestalten)
Hi
>Ich hab´ nun zwar nach ein paar Stunden zumindest mal 6 OCn-Pins>(scheinbar die Ausgangspins von den PWMs) ausfindig gemacht und>teilweise auch getestet (OC1A auf PB5 und OC5A auf PL3)...:
Dafür brauchst du Stunden?
OC1A/B/C Pin24/25/26
OC3A/B/C Pin5/6/7
OC4A/B/C Pin15/16/17
OC5A/B/C Pin38/39/40
OC0A/B Pin26/1
OC2A/B Pin23/18
MfG Spess
Hallo Spess,
... mein Thread-Titel ist Programm! Ich bin ein absoluter Neuling, dem
noch dazu ein deutsches Datenblatt als Grundlage für sein Vorhaben
fehlt...;-))
Hehe, thx... aber ich hab mich wohl etwas verquer ausgedrückt. Die Pins
weiß ich, nur den Zugriff darauf nicht. Momentan kann ich ausschließlich
auf OCnA (wobei n = 1,3,4,5) zugreifen, da ich die im Tutorial
gefundenen Registerzuweisungen von OC1A...
1
TCCR1A=(1<<COM1A1)|(1<<WGM11)|(1<<WGM10);
2
TCCR1B=(1<<CS12)|(1<<CS10);
3
ICR1=512;OCR1A=512;
... auch auf die anderen drei übertragen kann.
Z.B. fehlt mir bei OC0A das Register ICRn, weswegen ich ständig
Fehlermeldungen bekomme. Und bei dem Versuch zu OC1B passiert gleich
überhaupt nichts.
WAS mach ich denn falsch, an WELCHER Stelle steh´ ich auf dem
Schlauch???;-))
LG, Marcel
Hi
Jeder 16-Bit-Timer hat drei OC-Register. Und mit jedem kannst du eine
PWM erzeugen.
>Momentan kann ich ausschließlich>auf OCnA (wobei n = 1,3,4,5) zugreifen, da ich die im Tutorial>gefundenen Registerzuweisungen von OC1A...>TCCR1A = (1<<COM1A1) | (1<<WGM11) | (1<<WGM10);>TCCR1B = (1<<CS12) | (1<<CS10);>ICR1 = 512; OCR1A = 512;>... auch auf die anderen drei übertragen kann.
Dann nimm dir das Datenblatt und suche dir die passenden Bits für die
anderen beiden PWM-Kanäle der Timer. Die Einstellungen für PWM-Mode und
Frequenz gelten für alle Kanäle eines Timers. Die COM-Bits und das
OC-Register jeweils für einen Kanal.
MfG Spess
Hallihallöchen,;-)
... ich glaub´s ja ned... ich könnt´dich küssen!;-))))))
Es geht,... Mensch, woher soll man(n) denn SOWAS wissen? ICH kann das
Datenblatt doch kaum entziffern... :(
Jetzt klappt´s, bis auf den 8Bit-Timer "2"...
1
voidstartPWM(){
2
// Grundeinstellung der Timer/Counter: als nicht-invertierende 10-Bit PWMs:
3
// COMnxn = Ausgabeart des PWM-Signals (pro PWM-Kanal)
4
// WGMnn = Pulsweiten-Modulatorbits, um den PWM-Modus zu aktivieren (pro Timer)
Vielleicht ist das nix für dich, wenn du das Datenblatt nicht lesen bzw.
entziffern kannst. Du solltest dann mit einfachen Sachen anfangen und
nicht gleich mit Timer.
Hi
>Jetzt klappt´s, bis auf den 8Bit-Timer "2"...
Was klappt da nicht? Die Möglichkeiten von Timer2 findest du in Tabelle
94.
Mit einem festen Top-Wert von $FF hast du 2 PWM-Kanäle. Ein variabler
Top-Wert lässt sich nur mit OCR2A realisieren. Dadurch hast du für PWM
nur noch Kanal B zur Verfügung. ICR gibt es bei diesem Timer nicht. Bei
AVRs , wie dem ATMega2560 hilft dir das Tutorial nur bedingt. Da ist das
Datenblatt angesagt. Na ja, das ist eigentlich immer angesagt.
MfG Spess
Hey Spess,
... ich versteh´s einfach ned. Noch dazu: Tabelle 94 gibt´s bei mir
ned^^. Seit einer Stunde bastle ich nun rum, aber ich kappier´ die
Beschreibungen zu den Tabellenangaben leider nur sehr gebrochen. Kannst
du mir nochmal auf die Sprünge helfen? Was stimmt denn an meinen
Einstellungen nicht?
LG, Marcel
Hey,
... na, ich versteh einfach ned, wie ich das PWM-Signal auf den Ausgang
OC2A o. z.B. OC0B bekomme. Irgendwann mal hatte ich mal eine
Einstellung, sodass OC2A zumindest durchgehend HIGH war, aber weiter
gings dann auch ned. Oben zu sehen, ist mein bislang letzter Versuch, es
irgendwie zu schaffen.
LG, Marcel
Hi
Poste mal dein Programm, in dem du versuchst OC2A oder OC0B zu
aktivieren.
Ich bin notorischer Assemblerprogrammierer und kann nicht so einfach
C-Code aus dem Ärmel schütteln. Lesen geht halbwegs. Da sehe ich eher,
wo es klemmt.
MfG spess
Hey, du;-))
... das Programm ist doch schon in diesem Thread vorhanden. Im ersten
Beitrag. Und der Teil, in dem ich versuche, auf die PWM-Ausgänge
zuzugreifen, steht schon etwa zwei Seiten weiter oben:
Hi
>OCR2A = 512; OCR2B = 512;
Das ist ein 8-Bit-Timer . Also kannst du nur 0...255 zuweisen. Auch
bei Copy&Paste muss man denken.
Wenn du OC2B benutzen willst, dann fehlen die Zuweisungen für
COM2B1/COM2B0 und OCR2B.
>OCR1A = 512; ICR1 = 512; OCR1B = 512; OCR1C = 512;
Du hast Timer-Mode 3 gewählt. Da ist ICR1 irrelevant.
MfG Spess
Hallöchen Spess;-)
... nö, OC2A liegt doch auf PB4.;-)
Hm... messen tu ich gar nix, grad keine Möglichkeit. Ich seh nur, dass
meine LED durchgehend leuchtet.
Na wenn DU schon keinen Fehler sehen kannst, wie soll ICH denn da erst
weiterkommen?;-)
LG, Marcel
Marci schrieb:> Na wenn DU schon keinen Fehler sehen kannst, wie soll ICH denn da erst> weiterkommen?;-)
Mit dem naheliegensten:
Kompletten Programmcode zeigen
// Einstellung des Top- & Compare-Wertes (jeweils in Relation zur Taktlänge):
36
// OCRnx = Pulsbreite (pro PWM-Kanal);
37
OCR1A=512;OCR1B=512;OCR1C=512;
38
OCR5A=512;OCR5B=512;
39
40
OCR2A=200;
41
}
42
43
voidstopPWM(){
44
TCCR1B=0x00;
45
TCCR5B=0x00;
46
}
47
48
intmain(void){
49
// alle Anschlüsse der jeweiligen Ports als Ausgänge/Eingänge einstellen
50
DDRB=0xff;
51
DDRL=0xff;
52
53
DDRK=0x00;
54
55
// die Werte der Ausgänge festlegen ("0" bzw. "1"; s.a. http://www.mikrocontroller.net/articles/Bitmanipulation)
56
PORTL=0x00;
57
58
// PullUp-Festlegung der Eingänge (Taster)
59
PORTK=0xff;
60
61
val_PWM=0;
62
63
while(1){
64
65
// Variablenzuweisungen...
66
btn1=PINK&0b00000001;
67
btn2=PINK&0b00000010;
68
btn3=PINK&0b00000100;
69
btnJoyL=PINK&0b00010000;
70
btnJoyR=PINK&0b01000000;
71
btnJoyU=PINK&0b00001000;
72
btnJoyD=PINK&0b00100000;
73
btnJoyX=PINK&0b10000000;
74
75
// ... und anschließende Abfrage der Taster-Zustände
76
if(btn1==0){
77
78
PORTL=0x00;
79
PORTL|=(1<<PL7);
80
81
PORTB=0;
82
startPWM();
83
}
84
85
elseif(btn2==0){
86
PORTL=0x00;
87
PORTL|=(1<<PL6);
88
89
stopPWM();
90
PORTB=0;
91
PORTB|=0b01011011;// 7-Seg.-LED: "2" anzeigen
92
}
93
94
elseif(btn3==0){
95
PORTL=0x00;
96
PORTL|=(1<<PL5);
97
98
PORTB=0;
99
stopPWM();
100
}
101
102
103
elseif(btnJoyL==0){
104
105
}
106
elseif(btnJoyR==0){
107
108
}
109
elseif(btnJoyU==0){
110
111
}
112
elseif(btnJoyD==0){
113
114
}
115
elseif(btnJoyX==0){
116
117
}
118
}
119
120
return0;
121
}
Alle PWMs der Timer 1, 3, 4 und 5 bekomm ich so zum Laufen, außer die
von Timer 2 (analog dazu auch Timer 0) - und ich weiß einfach nicht,
WIE.
Help me, please!;-))
LG, Marcel
Marci schrieb:> von Timer 2 (analog dazu auch Timer 0) - und ich weiß einfach nicht,> WIE.
Sieht soweit eigentlich richtig aus.
Allerdings: was erwartest du bei einem PWM Wert von 200? Bei einer 8-Bit
PWM schenkt sich das nicht viel bei einer LED. Die leuchtet mit 200 fast
genauso hell, wie bei einem Pin der auf 1 ist.
(In deiner Stop Routine wird der Timer 2 nicht gestoppt. Ist das
Absicht?)
für Timer0 und das gleiche für Timer2 erscheint, wie erwartet, eine PWM
an den entsprechenden Pins (ATMega1281). Also, an der Initialisierung
liegt es nicht.
Hast du vielleicht irgend welche Jumper/Schalter auf dem Board, die den
Port abtrennen?
MfG Spess
@Karl Heinz:
1. Wenn ich den Wert weiter runter setze, verdunkelt sich die LED,
sprich: der Wert ändert zwar das Verhalten der LED, aber sie leuchtet
durchgehend.
2. Mein Gedanke mit den zwei 8Bit-Timern ist etwas weiter, als die
Stop-Routine.;-) (also schon so beabsichtigt)
@Spess:
Ich habe am myAVR-Board seit der Auslieferung nichts verändert. Alle
angeschlossenen und auch in meinem Quelltext angesprochenen Aktoren sind
voll funktionsfähig. Der Beweis: sämtliche andere (in meinem bisherigen
Code benutzte) PWMs laufen über PORTB (wie z.B. auch OC2A/Timer 2!) -
und funktionieren.
Hm... und nun???;-)
LG, Marcel
Hi
>1. Wenn ich den Wert weiter runter setze, verdunkelt sich die LED,>sprich: der Wert ändert zwar das Verhalten der LED, aber sie leuchtet>durchgehend.
Und was erwartest du? Blinken? Das ist ein 8-Bit-Timer. Bei 16MHz kommst
du auf eine minimale PWM-Frequenz von 61Hz.
MfG Spess
Ach... tschuldige, ich brauch dochn noch mal kurz Hilfe^^. Es gibt
nämlich ein kleines Problem in meiner Schaltung: Ab und an schalten bei
Taster 2 bzw. 3 die anderen Ausgänge von PORTB durch und bleiben dann
auch über mehrere Schaltvorgänge in diesem Zustand. Gibt´s dafür
irgendeine Erklärung?
Außer PB4,5,6 und PB7 sollten ja eigentlich alle Ausgänge auf 0 sein?
LG, Marcel
Hm... eigentlich nicht, oder?!?
Grundlegend sind ja alle PORTs, bis auf B, in meiner Schaltung erst
einmal unbenutzt. Es kann doch dann nur an folgender Anweisung liegen?:
1
//Zuweisung auf Taster 2 u. 3
2
PORTB=0;
??
Wenn ich obige Aktion auskommentiere, läuft ja alles wie gewünscht (aber
die LEDs gehen dann zu meinem Bedauern auch nicht aus^^).
LG, Marcel
Hi
>//Zuweisung auf Taster 2 u. 3>PORTB = 0;>Wenn ich obige Aktion auskommentiere, läuft ja alles wie gewünscht (aber>die LEDs gehen dann zu meinem Bedauern auch nicht aus^^).
Mal eine Dumme Frage: Was willst du einem Taster zuweisen? Die Pins
der Taster müssten eigentlich als Eingang konfiguriert sein. Und da
wirkt sich Port=yxz nur auf die internen Pull-Up-Widerstände aus.
MfG Spess
Falsch ausgedrückt..., wie man im ProgrammCode oben sieht, meinte ich
mit "Zuweisung auf Taster 2 u. 3", die Aktion, die ausgeführt wird, wenn
Taster 2 bzw. 3 gedrückt wird: also "PORTB = 0", um PORTB (die
7Seg.-Anzeige) zu "leeren".
LG, Marcel
PB5,6 u. 7 (OC1A,OC1B u. OC1C).
Da ich ja die PWMs nur durch ein "Timer>Stop" deaktiviere, und im
ungünstigen Fall, gerade bei den durchgeschalteten Pins gestoppt wird.
LG, Marcel