ich versuche verzeifelt auf GCC umzusteigen, aber selbst einfachste Programme machen Probleme. Z.B.: --------------------- //PWM in Pascal -> läuft begin //Ports DDRB := %11111111; //Port B - alles Ausgang //Timer TCCR1A:= %01111110; // enable TimerA TCCR1B:= %00000011; // Vorteiler Timer A OCR1A:= $64; // Vergleichsregister OCR1C:= $C8; Loop endloop; end pwm. ---------------------- //umgeschrieben in GCC -> Ausgang immer 0 int main() { //Ports DDRB = 0xFF; // PORTB als Ausgang schalten //Timer TCCR1A=(0<<COM1A1)|(1<<COM1A0)|(1<<COM1B1)|(1<<COM1B0)|(1<<FOC1A)|(1<<FO C1B)|(1<<PWM1A)|(0<<PWM1B); TCCR1B=(0<<CTC1)|(0<<PSR1)|(0<<CS13)|(0<<CS12)|(1<<CS11)|(1<<CS10); OCR1A=0x64; OCR1C=0xC8; for(;;); } -------------------------- kann jemand einen Fehler entdecken? ich sitze jetzt schon seit Stunden vor dem Code :-( Gruß Stefan
Ich sehe keine Stelle in dem Quelltext, dass irgendein Ausgang auf 1 gesetzt wird. Welche STelle soll das auch tun?
NiSchü wrote: > Ich sehe keine Stelle in dem Quelltext, dass irgendein Ausgang auf 1 > gesetzt wird. Welche STelle soll das auch tun? Laut Beschreibung : (0<<COM1A1)|(1<<COM1A0) -> Toggle the OC1A output line ich verstehe das so, dass der Pin ständig von 0 auf 1 wechselt.
Sowas:
>(0<<CS13)
Ist total sinnlos. (Guck dir mal in einem C-Buch die Funktion des
Bit-Schiebens an).
Hast du den Tiny auch im Makefile richtig angegeben?
Wie sieht das komplette Programm aus? Wo sind die Include-File?
Sagt der Compiler irgendwas?
Bis auf sinnlose Schiebeaktionen sehe ich auch keinen Fehler (im
Vergleich zum Pascal-Code).
Morgen! Probier statt TCCR1A=(0<<COM1A1)|... mal TCCR1A |= (0<<COM1A1)|... Könnte, muß aber nicht. Gruß Markus
inoffizieller WM-Rahul wrote: > Sowas: >>(0<<CS13) > > Ist total sinnlos. Stimmt zwar, aber wenn jemand aus Lesbarkeitsgründen es so machen will, ist es durchaus erlaubt. Man weiß dann ja immer welche Bits in dem Register überhaupt definiert sind. Peter
hallo, wie auch immer die bits geshiftet und gesetzt werden .. den einzigen Unterschied sehe ich im setzen der TCCR. dort benutzt du die macros der avr-libc, was zunächst sehr löblich ist. aber um fehler auszuschliessen, probiere einmal die entsprechung deiner pascal-notation, wie du es mit den anderen werten auch getan hast: TCCR1A:= %01111110; // enable TimerA TCCR1B:= %00000011; // Vorteiler Timer A entsprechend TCCR1A = 0x7E; TCCR1B = 0x03; vll hilfts, bye kosmo
erster Fehler war der: falsch: TCCR1A = (0<<COM1A1)|... richtig:TCCR1A |= (0<<COM1A1)|... (da gabe ich falsch abgeschrieben :-) hatte aber keine Auswirkung Der Fehler lag im MAKEFILE. Ich benutze das ARV-STUDIO4 das automatisch ein Makefile generiert. Ich hatte aber vergessen von Mega auf Tiny umzustellen. Vielen Dank für die schnelle Hilfe. Gruß Stefan Hier noch das komplette lauffähige Programm: /* ;PWM Test ; ; ================================================ ; TINY26 ; ================================================ ; __ __ ; PB0 |1 |_| 28| PA0 (ADC0) ; (OC1A) PB1 |2 A 27| PA1 (ADC1) ; PB2 |3 T 26| PA2 (ADC2) ; PB3 |4 M 25| PA3 (AREF) ; VCC |5 E 24| GND ; GND |6 L 23| AVCC ; (ADC0) PB4 |7 22| PA4 (ADC3) ; (ADC0) PB5 |8 A 21| PA5 (ADC4) ; (ADC0) PB6 |9 T 20| PA6 (ADC5/AIN0) ; (ADC0) PB7 |10 m 19| PA7 (ADC6/AIN1) ; |_________| ; ; */ #define F_CPU 3600000 #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #define TCCR1A _SFR_IO8(0x30) #define PWM1B 0 #define PWM1A 1 #define FOC1B 2 #define FOC1A 3 #define COM1B0 4 #define COM1B1 5 #define COM1A0 6 #define COM1A1 7 #define TCCR1B _SFR_IO8(0x2F) #define CS10 0 #define CS11 1 #define CS12 2 #define CS13 3 #define PSR1 6 #define CTC1 7 void Pause(void) //etwa 0,5s { uint8_t i; uint8_t j; for(i=0;i<178;i++) { for(j=0;j<250;j++) {} }} int main() { DDRB = 0xFF; // PORTB als Ausgang schalten PORTB = 0x80; TCCR1A|=(0<<COM1A1)|(1<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)|(0<<FOC1A)|(0<<F OC1B)|(1<<PWM1A)|(1<<PWM1B); TCCR1B|=(0<<CTC1)|(0<<PSR1)|(0<<CS13)|(1<<CS12)|(1<<CS11)|(1<<CS10); OCR1A=0x30; // Vergleichsregister OCR1B=0x60; OCR1C=0xFF; // Max Zählwert for(;;) //LED an PORTB5 blinkt { PORTB |= (1 << 5); // Bit 5 setzen Pause(); PORTB &= ~(1 << 5); // Bit 5 löschen Pause(); } }
Stefan Gemmel wrote: > erster Fehler war der: > falsch: TCCR1A = (0<<COM1A1)|... > richtig:TCCR1A |= (0<<COM1A1)|... Nein, das war kein Fehler. Was soll das Verodern denn bringen?
Jörg Wunsch wrote: > Stefan Gemmel wrote: > >> erster Fehler war der: >> falsch: TCCR1A = (0<<COM1A1)|... >> richtig:TCCR1A |= (0<<COM1A1)|... > > Nein, das war kein Fehler. Was soll das Verodern denn bringen? In diesem Fall nichts aber: A = B ist nicht das Gleiche wie A = A oder B Beispiel: 10=01 (ergibt 01) 10=10 oder 01 (ergibt 11) In meinem Programm war es kein Fehler weil ich alle Bits angegeben habe. Ich möchte mir aber trotzdem die richtige Schreibweise angewöhnen :-)
Stefan Gemmel wrote: > In meinem Programm war es kein Fehler weil ich alle Bits angegeben habe. > Ich möchte mir aber trotzdem die richtige Schreibweise angewöhnen :-) Für eine komplette Initialisierung eines Registers (anstatt nur einer Veränderung eines bestehenden Wertes) finde ich aber die absolute Zuweisung ,,richtiger'' als das Verodern. Das Verodern löscht dir eben nicht die Bits, die du so umständlich als (0 << Bitname) angegeben hast.
Höhö: Gewonnen! @Peter: Übersichtlicher wird der Code dadurch nicht. Aber wie die kürzlich verstorbene Annemarie Wendl so schön sagte: "Wenn's sche' macht!?" >Für eine komplette Initialisierung eines Registers (anstatt nur einer >Veränderung eines bestehenden Wertes) finde ich aber die absolute >Zuweisung ,,richtiger'' als das Verodern. Volle Zustimmung.
OK ich ihr habt mich überzeugt. Schade dass man nicht ein paar Kontrollkästchen zum Ankreuzen der Bits hat :-) (Visual-Basic für AVAR)
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.