Hallo,
ich möchte gerne einen 16bit Timer im ctc modus mit Interrrupt als Übung
für mich einstellen. Hab mir auch ein video dazu angesehen. Die
verwenden aber einen ganz anderen Chip. Und ich möchte den attiny24a
dazu verwenden.
Tabelle datenblatt seite 110 Zeile 4 :
>4 0100 CTC (Clear Timer on Compare) OCR1A Immediate MAX
die oben genannte Zeile müsste ich doch mit einem WGM bit setzen können?
doch wie setze ich das richtige bit für zeile 4? mit dieser tabelle
komme ich einfach nicht klar. Könnte mir das mal bitte jemand erklären?
Mfg Huber
:
Verschoben durch User
Video sind zum lernen auch nicht Sinnvoll. Wie setzt du denn sonst ein bit in einem Byte? Genauso macht du es dort. Erst suchst du das Register woher das bit soll. Dann das bit aus der Tabelle ablesen und eintragen. REGISTER =| (1<<WGM1); Ich habe jetzt nicht ins Datenblatt geschaut, bei einige Atmels gehen die WGM bits über 2 Register da muss man etwas aufpassen.
>REGISTER =| (1<<WGM1);
genau so, aber normalerweise steht ja auch in der Tabelle auch oben in
Spalten unterteilt
WGM12 WGM11 WGM10 usw. Drüber.
Aber in diesem Datenblatt scheint das nicht der fall zu sein, Da ist
irgedwo ein trick dahinter den ich nicht sehe oder verstehe.
Huber M. schrieb: > WGM12 WGM11 WGM10 usw. Drüber. steht doch mehr oder weniger auch da: WGM1[3:0] 0 0000 1 0001 2 0010 also WGM13,WGM12,WGM11,WGM10
Falls es nicht klappen sollte, könnte es auch an Peter II schrieb: > REGISTER =| (1<<WGM1); liegen. Wenn ich mich nicht total vertue, sollte es
1 | REGISTER |= (1<<WGM1); |
sein. Das dürfte einen Compilerfehler geben und deshalb hier nicht das Problem sein, aber bevor es einen Anfänger verwirrt…
ich will hier keinen auf die nerven gehen, dann müsste ich jetzt WGM14 schreiben um die 4. zeile zu erreichen oder wie? wegen binär dazu zählen. Mode WGM Mode of operation Top 13:10 0 0000 Normal 0xFFFF Immediate MAX 1 0001 PWM, Phase Correct, 8-bit 0x00FF TOP BOTTOM 2 0010 PWM, Phase Correct, 9-bit 0x01FF TOP BOTTOM 3 0011 PWM, Phase Correct, 10-bit 0x03FF TOP BOTTOM 4 0100 CTC (Clear Timer on Compare) OCR1A Immediate MAX aber wie komme ich auf die 1 vor der 4
Die binären Ziffern (Bits)(0100) zum Mode 4 (besser nicht Zeile 4) heißen der Reihe nach WGM13, WGM12, WGM11, WGM10. Die 1 nach dem WGM ist im allgemeinen bei den AVR die Timer-Nummer. Hier also der Timer 1. Die Bitnamen (WGM1x) finden sich in den Registern wieder, in denen sie dann gesetzt werden müssen um den Mode einzustellen. Hier muß also das WGM12 im richtigen Register, das du nun suchen darfst, gesetzt werden, um den Modus 4 einzustellen.
> WGM14
?
Es gibt kein WGM14.
WGM10 und 11 stehen in TCCR1A, WGM12 und 13 in TCCR1B. Für Modus 4 muss
also WGM12 in TCCR1B gesetzt werden.
Ach ja, es gibt zum ATtiny24a ein eigenes Datenblatt. Mir scheint, das du das zum ATtiny24 (ohne a) benutzt. Beim 24a ist die Tabelle bei mir auf Seite 108.
>#include <avr/interrupt.h>
#include <avr/io.h>
//ISR falls der vergleichswert erreicht ist
ISR(TIM1_COMPA_vect)
{
PORTA ^= (1<<PA6);
}
int main(void)
{
// Ausgang Festlegen
DDRA |= (1<<PA6);
//Timer1 Konfigurieren
TCCR1B|= (1<<WGM12) | (1<<CS12); //ctc mode und vorteilere 256
TIMSK1|= (OCIE1A); // interrupt aufrufen wenn der
OCR1A = 15624; //vergleichswert erreicht ist
sei();
while(1)
{
}
}
ok, ich geh jetzt davon aus von 13 abwärts zu zählen. in diesem Sketch
soll die Led blinken, aber noch funktioniert es nicht. habe ich
vielleicht noch ein Register falsch gesetzt?
:
Bearbeitet durch User
Sketch? Falls das ein Arduino ist, sollten die '|=' durch '=' ersetzt werden.
nein, kein arduino. -ATMEL STUDIO 6.0 -AVR ISP MK2 original -Attiny24A
Huber M. schrieb: > ok, ich geh jetzt davon aus von 13 abwärts zu zählen. in diesem Sketch > soll die Led blinken, aber noch funktioniert es nicht. habe ich > vielleicht noch ein Register falsch gesetzt? Scheint mir alles richtig zu sein. LED falsch angeschlossen? Kaputt? Vorwiderstand zur LED? zu hoch? Programmierkabel mal abziehen. Mit welcher Frequenz wird der Tiny getaktet?
LED OK, Vorwiderstand evtl. naja eigentlich zu hoch 1K. Led leuchtet aber ohne yc. Getaktet ich dachte der läuft intern mit 1MHz.
Also 1<< noch vervollständigt, Verdrahtung überprüft. Led hängt an PA6, aber nichts blinkt achja einen neuen Controller angebracht. Ändert auch nichts. das müsste doch, wenn ich es drauf spiele mit externer Versorgung 5v blinken?
>Also 1<< noch vervollständigt, Verdrahtung überprüft. Led hängt an PA6, >aber nichts blinkt achja einen neuen Controller angebracht. Ändert auch >nichts. das müsste doch, wenn ich es drauf spiele mit externer >Versorgung 5v blinken? Ja, das müsste es wenn: Die LED richtig angeschlossen ist. Pin verwechselt? Das richtige HEX Datei reingebrutzelt wurde. Die Verdrahtung richtig ist. Jetzt musst du nur noch rausfinden welcher der drei Punkte nicht erfüllt wurde;)
Mir fällt nichts mehr ein. Vielleicht mal A7 nehmen statt A6, Letzterer ist ja auch MOSI.
Aktuelles Programm nochmal posten. Wenn niemand mehr ein Programmfehler entdeckt: PA6 hat entweder high oder low Zusatnd. LED so anschließen, das sie mit µC schon leuchtet. Sollte alle 4 Sekunden an und aus (0,125Hz) gehen bei µC Takt von 1MHz, wenn ich mich nicht verrechnet habe. Wenn nicht, Schaltbild und Foto vom Aufbau. Hab sonst auch keine Idee mehr.
Hi >Also 1<< noch vervollständigt, Verdrahtung überprüft. Led hängt an PA6, >aber nichts blinkt achja einen neuen Controller angebracht. Du hast die COM-Bits in TCCR1A vergessen. MfG Spess
> Du hast die COM-Bits in TCCR1A vergessen.
Die werden nicht benötigt.
S. Landolt schrieb: >> Du hast die COM-Bits in TCCR1A vergessen. > Die werden nicht benötigt. Wie kommst du denn auf dieses schmale Brett? Natürlich werden die COM-Bits immer benötigt, wenn der Timer selber irgendwas an den Pins wackeln lassen soll. Ohne die COM-Bits kann der Timer nur die Interrupt-Flags wackeln lassen, mehr tut sich da nicht.
Ganz speziell für c-hater: ein Assembler-Programm! (in Anlehnung an oben gezeigtes C-Programm):
1 | .include "tn84Adef.inc" |
2 | .def tmp0 = r16 |
3 | |
4 | .org 0 |
5 | rjmp reset |
6 | .org OC1Aaddr |
7 | sbi PINA,7 |
8 | reti |
9 | |
10 | reset: |
11 | sbi DDRA,7 |
12 | ldi tmp0,(1<<WGM12)+(1<<CS12) |
13 | out TCCR1B,tmp0 |
14 | ldi tmp0,(1<<OCIE1A) |
15 | out TIMSK1,tmp0 |
16 | ldi tmp0,high(15624) |
17 | out OCR1AH,tmp0 |
18 | ldi tmp0,low(15624) |
19 | out OCR1AL,tmp0 |
20 | sei |
21 | rjmp pc |
Die LED an A7 blinkt, ganz ohne COM-bits. Warum auch nicht.
Moing, also so sieht er jetzt aus. Und funktioniert immer noch nicht. Heute habe ich aber -atmelstudio 6.2 und gestern hatte ich 6.0 /* * GccApplication3.c * * Created: 28.08.2016 07:59:50 * Author: Huber */ #include <avr/interrupt.h> #include <avr/io.h> //ISR falls der vergleichswert erreicht ist ISR(TIM1_COMPA_vect) { PORTA ^= (1<<PA1); } int main(void) { // Ausgang Festlegen DDRA |= (1<<PA1); //Timer1 Konfigurieren TCCR1A|= (1<<WGM12) | (1<<CS12); //ctc mode und vorteilere 256 TIMSK1|= (OCIE1A); // interrupt aufrufen wenn der OCR1A = 15624; //vergleichswert erreicht ist sei(); while(1) { } } ich bin mir eigentlich ziemlich sicher das ich alles richtig verdrahtet habe, denn wenn ich blinken mit delay hochlade blinkt es ja auch.
Pardon, aber:
> TIMSK1|= (OCIE1A);
Hier fehlt noch immer das '1<<'!
Das mit dem CTC ist sogar extra aufgeführt... The following control bits have been renamed, but retained the same functionality and register locations: • PWM10 is changed to WGM10. • PWM11 is changed to WGM11. • CTC1 is changed to WGM12.
/* * GccApplication3.c * * Created: 28.08.2016 07:59:50 * Author: Huber */ #include <avr/io.h> //ISR falls der vergleichswert erreicht ist ISR(TIM1_COMPA_vect) { PORTA ^= (1<<PA1); } int main(void) { // Ausgang Festlegen DDRA |= (1<<PA1); //Timer1 Konfigurieren TCCR1B|= (1<<WGM12) | (1<<CS12); //ctc mode und vorteilere 256 TIMSK1|= (1<<OCIE1A); // interrupt aufrufen wenn der OCR1A = 15624; //vergleichswert erreicht ist sei(); while(1) { } } so ist er jetzt drauf gespielt. Keine Funktion.Wenn ich, ohne das ich etwas an der verkabelung ändere, folgendes drauf spiele. Blinkt es natürlich /* * GccApplication4.c * * Created: 28.08.2016 08:15:45 * Author: Huber */ #define F_CPU 1000000UL #include <util/delay.h> #include <avr/io.h> int main(void) {DDRA|= (1<<PA1); while(1) { PORTA|= (1<<PA1); _delay_ms(150); PORTA &= ~(1<<PA1); _delay_ms(1500);//TODO:: Please write your application code } } sobald ich aber den anderen Code drauf spiele genau wie oben drauf spiele. Keine Funktion ich bin bin schon am verzweifeln.
Mal so eine Frage: braucht man beim AVR Studio die #include <avr/interrupt.h> nicht? Meckert der Kompiler nichts an? Z.B., dass "sei()" unbekannt ist? Werner
jetzt klappt es. Vielen Dank für eure Geduld. Ich hoffe, ich darf dazu noch ein paar fragen stellen wenn nötig. die avr/interrupt hatte ich wohl versehentlich raus gelöscht. /* * GccApplication3.c * * Created: 28.08.2016 07:59:50 * Author: Huber */ #include <avr/interrupt.h> #include <avr/io.h> //ISR falls der vergleichswert erreicht ist ISR(TIM1_COMPA_vect) { PORTA ^= (1<<PA1); } int main(void) { // Ausgang Festlegen DDRA |= (1<<PA1); //Timer1 Konfigurieren TCCR1B|= (1<<WGM12) | (1<<CS12); //ctc mode und vorteiler 256 TIMSK1|= (1<<OCIE1A); // interrupt aufrufen wenn der OCR1A = 3906; //vergleichswert erreicht ist sei(); while(1) { } }
:
Bearbeitet durch User
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.