Hallo zusammen, ich hab ein kleines Problem und hoffe ihr könnt mir helfen. Ich will an meinem ATMEGA32 PORTA ( von PA0 bis PA7) jeweils eine "1" durchshiften...Prinzip Lauflicht...ABER irgendwie macht mein µC nciht das was er soll oder ich hab ein kleinen Denkfehler.... hier mein Quellcode: #define F_CPU 8000000 #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> ISR(TIMER1_COMPA_vect) { PORTA = PORTA >>1 ; if(PORTA == 0x00) PORTA = 0x80; } int main(void) { DDRA |= 1<<PD0; DDRA |= 1<<PD1; DDRA |= 1<<PD2; DDRA |= 1<<PD3; DDRA |= 1<<PD4; DDRA |= 1<<PD5; DDRA |= 1<<PD6; DDRA |= 1<<PD7; while(1) { } //Timer konfigurieren TCCR1B |= (1<<WGM12) | (1<<CS11); //| (1<<CS10);//CTC Mode mit WGM12, Prescaler von 8 mit CS11 //TCNT1 = 64286; TIMSK |= (1<<OCIE1A); OCR1A |= 675; //Vergleichswert zur BEstimmung von 1,25ms TIMSK |= (1<<OCIE1A); TCCR1A |= (1<<COM1A0); sei(); } ich will einfach nur, dass jeder Port etwa für 0,1ms einen high-Pegel hat. Der Timer ist jetzt auf 800Hz eingestellt...der sollte natürlich auf 100Hz stehen. Noch besser wäre es wenn man diese Funktion ohne einen Timer Baustein bewerkstelligen kann, da ich die 3 Timer im Atmega eigentlich für was anderes benötige. Danke schonmal für´s durchlesen... LG Paavo
Wie soll der uC denn den Timer konfigurieren? Er bleibt in der while-Schleife hängen! (Ich habe nicht geschaut, ob die Initialiesierung prinzipiell stimmt)
-.- ohne kommentar....ja der Timer muss natürlich vor die while-schleife! sorry
@Paavo: Wenn du das Atmel Studio benutzt hilft bei solchen "blöden" Fehlern schon mal der Debugmodus im Einzelschritt, da kannst du mitverfolgen was der Controller macht, oder eben nicht macht.
@Martin ich arbeite mich gerade rein ins atmel studio, bin also noch echt ein noob!
Ich bin im Moment nicht mit Atmegas vertraut, aber ich denke OCR1A |= 675; wird nicht klappen, da der Atmega nur 8 bit Register hat, also nur Werte bis 255 annehmen kann. Du musst dir wohl einen anderen Vorteiler und eine andere Timerschwelle ausrechnen. PS: Siehst du irgendetwas auf dem Scope? PSS: if(PORTA == 0x00) sieht auch nicht gut aus. Ich würde die Abfrage auf 0x01 machen. Der Shifter ist glaube eh ein Kreisshifter (oder irre ich mich da?)
Zumindest im Simulator läuft das Programm. Der Port wird ca. alle 0,68ms geshifted.
Der Timer läuft im CTC Modus...TCCR1B |= (1<<WGM12) Dersweiteren habe ich einen Rrescaler von 8 eingestellt hier nochmal die Zeile: TCCR1B |= (1<<WGM12) | (1<<CS11); //| (1<<CS10); //CTC Mode mit WGM12, Prescaler von 8 mit CS11 Das mit dem Timer haut schon in da ich ihn am PD5 messen kann mit hilfe des scopes...! Ich will ja eigentlich nur den gesamten PORTA aktivieren. Dass macht er auch mit DDRA = 0xFF // somit sind alle Pins als Ausgänge definiert. ...if(PORTA = 0x00)PORTA 0x80; ist nur dafür gedacht, dass er wieder von vorne anfängt zu zählen und nicht ins nirvana shiftet:D
icke schrieb: > if(PORTA == 0x00) > sieht auch nicht gut aus. Ich würde die Abfrage auf 0x01 machen. > Der Shifter ist glaube eh ein Kreisshifter (oder irre ich mich da?) es is ja C und dort gibt es keinen Kreisshifter. Das ist schon so ok.
@AMrtin wie im simulator läuft das Programm? :D Ich seh bloss nix am scope und würde wenigstens gerne dort was sehen:D @Peter II :D ok passt
Paavo Varniery schrieb: > Das mit dem Timer haut schon in da ich ihn am PD5 messen kann mit hilfe > des scopes...! Wenn du PA5 schreiben wolltest, ist alles ok und ich habe nichts gesagt. Wie gesagt, im Simulator läuft es.
@Matrtin nochmal...wie kannst du eine ISR im Atmelstudio simulieren? BTW ich nutze ATMelstudio 6
Ich auch. Einfach einen Breakpoint in die ISR setzen. Im Bild wo der gelbe Pfeil ist mit der linken Maustaste klicken. Dieses Programm benutze ich:
1 | #define F_CPU 8000000
|
2 | #include <avr/io.h> |
3 | #include <avr/interrupt.h> |
4 | #include <util/delay.h> |
5 | |
6 | ISR(TIMER1_COMPA_vect) |
7 | {
|
8 | PORTA = PORTA >>1 ; |
9 | if(PORTA == 0x00) |
10 | PORTA = 0x80; |
11 | }
|
12 | |
13 | |
14 | int main(void) |
15 | {
|
16 | DDRA |= 1<<PD0; |
17 | DDRA |= 1<<PD1; |
18 | DDRA |= 1<<PD2; |
19 | DDRA |= 1<<PD3; |
20 | DDRA |= 1<<PD4; |
21 | DDRA |= 1<<PD5; |
22 | DDRA |= 1<<PD6; |
23 | DDRA |= 1<<PD7; |
24 | |
25 | |
26 | |
27 | //Timer konfigurieren
|
28 | TCCR1B |= (1<<WGM12) | (1<<CS11); //| (1<<CS10);//CTC Mode mit WGM12, Prescaler von 8 mit CS11 |
29 | //TCNT1 = 64286;
|
30 | TIMSK |= (1<<OCIE1A); |
31 | OCR1A |= 675; //Vergleichswert zur BEstimmung von 1,25ms |
32 | |
33 | TIMSK |= (1<<OCIE1A); |
34 | TCCR1A |= (1<<COM1A0); |
35 | |
36 | sei(); |
37 | while(1) |
38 | {
|
39 | |
40 | }
|
41 | |
42 | }
|
Hi >Ich bin im Moment nicht mit Atmegas vertraut, aber ich denke >OCR1A |= 675; >wird nicht klappen, da der Atmega nur 8 bit Register hat, also nur Werte >bis 255 annehmen kann. Als 8-Bit-Register heißt das OCR1AL und OCR1AH. OCR1A ist für den Compiler ein 16-Bit-Register. >TCCR1A |= (1<<COM1A0); Dann solltest du aber auch OC1A (PD5) auf Ausgang setzen. MfG Spess
Ich debugge und gehe dann mit "step into" jeden schritt durch aber ich komm nicht in die ISR?! auch wenn ich dort ein breakpoint setze!
Benutzt du exakt mein Programm? Gut, das Studio ist schon mal zickig. Mach mal Folgendes: - Den Breakpoint so setzen wie bei mir - Alt+F5 (= Start debuging and break) - jetzt sollte der Cursor in der ersten Zeile der main-Funktion stehen. - F5 (=Run) drücken. - nach einer kurzen Weile sollte der Cursor beim gesetzten Breakpoint in der ISR stehen bleiben.
KOMMANDO zurück und vielen dank für die Zahlreichen kommentare ABER wenn man beim Flashen die falsche Datei nimmt kann es ja nicht gehen!:D:D:D Eine sehendes auge für den blinden bitte:D LG
Hach ist das schön! Auch anderen passiert dieser Fehler ;-) Funktioniert das Debuggen denn jetzt auch? Das sollte eigentlich unabhängig vom zu flashen file laufen.
Ja alles super=) NUR wenn ich schiffte müsste doch auf jedem Port der Highpegel etwas woanders liegen oder? Der Pegel sieht jetzt so aus.... ____-_______-_____ aber ich will eigentlich einen Pegel haben , der wirklich 100 Hz an jedem Pin bleibt! so dass ich insgesamt eine rotation von 800HZ habe.
Es ist auch komisch, dass mir die simulation das im Bild anzeigt und ich aber mit dem Scope ein efrequenz von 1250 Hz messe=(=(
Das war früher(tm) mit dem alten Atmel Studio einfacher. Du musst hier manuell den Wert auf den gewünschten Wert setzen.
Nur zum verständnis... Wenn ich den Timer1 nehme und im CTC modus betreibe und mit einem Prescaler von 8 rangehe und meine Taktfreuenz vom CPU bei 8Mhz liegt und ich eine Frrequenz von 800 Hz haben will rechne ich doch wie folgt oder? ORC1A = (zeit *(CPU_takt/Prescaler)-1 oder?
Du schreibst hier:
1 | OCR1A |= 675; //Vergleichswert zur BEstimmung von 1,25ms |
Wie kommst du darauf? Der µC läuft mit 8MHz, der Timer 1:8 also mit 1MHz, also kommt der Interrupt alle 0,675 Millisekunden. Der richtige Wert wäre 1250. Oh noch was: OCR1A |= 675; GAAAANZ gefährliches Eisen! Was soll hier die Oder-Verknüpfung? OCR1A enthält genau nur dann den Wert 675, wenn es vorher Null war. Wird hier in diesem Fall zwar funktionieren, später kann dir soetwas aber mal das Genick brechen.
Hi >also kommt der Interrupt alle 0,675 Millisekunden. Der richtige Wert >wäre 1250. Genaugenommen sind es 1249. MfG Spess
Ich habe auch 1249 errechnet! Aber damit bekomme ich leider auf dem Scope keine 800 Hz zusehen...Danke martin für den Tip mit der ODer -Verknüpfung! Das habe ich gar nicht gesehen...die sollte da nicht hin!
Hi >Ich habe auch 1249 errechnet! Aber damit bekomme ich leider auf dem >Scope keine 800 Hz zusehen... Und wo gemessen? An einem Pin von PortA solltest du Impulse mit einer Frequenz von 100 Hz messen. Am OC1A-Pin (PD5) müssen 400 Hz symmetrisches Rechteck rauskommen. Dann passt das Ganze. MfG Spess
Hwy:D Also ich messe jetzt an PD5 eine Frequenz von 800Hz mit einem Vergleichswert von OCR1A =624,5; fragt mich nicht wie aber es geht...=)=) Von der Taktung sieht es jetzt genau so aus wie ich es haben will...Also 800Hz an PD5 und an PA0-7 jeweils einen Impuls der dann 7 Takte von PD5 abwartet eh er wieder kommt! Super super super=) Nächste frage die ich habe ist, in welchen Register kann bzw muss ich eine 32bit große Bitfolge abspeichern...ich hab eigentlich ein 64 Bit wort wie ich es aufteile hab ich in C schon realisiert..nur muss ich dem Atmega doch sagen wo er es ablegen soll oder? Kann ich eine Bitfolge einfach an PD4 rauschicken? Oder einen beliebeigen Pin? LG
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.