Hey ihr lieben! Ich habe folgendes Problem. Ein Motor drückt mir zwei um pi/2 verschobene in der Anzahl zur Drehazahl proportionale Rechtecksignale durchs Kabel, welche ich mit dem attiny45 auslese. Die Platine ist denkbar ungünstig geroutet, daher folgende Anschlussbelegung: PB5/Reset <- Rechteck 1 (reset ist per fuse natürlich disabled) PB4 <- Rechteck 2 PB2 -> CLK PB1 -> DATA PB0 -> LOAD Im Debugger läuft alles perfekt, leider nicht in echt. Die Ansteuerroutine des DAC scheint zu laufen, jedenfalls werden die 2047 aus dem Timer Overflow korrekt aufgebraten. Die gesamte Prozedur ist aus er Wiki hier. Allerdings krieg ich nur irgendwelche sprunghaften Signale, wenn ich ganz langsam drehe. Vielleicht ist der ClockDevide 1024 auch zu viel und deshalb zähl ich über das Ziel hinaus? Könnte aber eigentlich nicht sein, da die Taktfrequenz bei 20MHz durch einen externen Oszillator liegt. Jetzt mal das Programm: ----------------------------------------------------------------- main.c ----------------------------------------------------------------- #include <avr/io.h> #include "ltc1257.h" #include "avr/interrupt.h" /* Prototypes: */ static unsigned int counter; int main(void); void interruptinit(void); void ioinit(void); int main(void) { ioinit(); counter = 2047; while(1) { ; } /* NEVEREACHED */ return 0; } void ioinit(void) { /* IO setup: */ DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2) | (0 << PB4) | (0 << PB5); /* LTC1257 pins (output) */ PORTB = (1 << PB4) | (1 << PB5); /* Low-level init of DAC: */ ltc1257_ll_init(); /* init interrupts */ interruptinit(); } void interruptinit(void) { GTCCR = (1 << TSM) | (1 << PSR0); TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00); //Clock devide by 1024 0 0 0 stoppt timer TIMSK = (1 << TOIE0); //Overflow Interrupt Counter 0 GIMSK = (1 << PCIE); //pin change interrupt PCMSK = (1 << PCINT4); //interrupt pin 4 changes; sei(); GTCCR = 0 << TSM; //loszählen } ISR(PCINT0_vect) { if (bit_is_set(PINB, 4) == bit_is_set(PINB, 5)) counter++; else counter--; //zählen Richtungsabhängig } ISR (TIMER0_OVF_vect) { cli(); TCCR0B = (0 << CS02) | (0 << CS01) | (0 << CS00); PCMSK = (0 << PCINT4); ltc1257_ll_write(counter); counter = 2047; TCNT0 = 0; TCCR0B = (1 << CS02) | (0 << CS01) | (1 << CS00); PCMSK = (1 << PCINT4); sei(); } ------------------------------------------------------------- ltc1257.h ------------------------------------------------------------- /* * ltc1257.h * * Created: 28.06.2011 22:20:50 * Author: Berni */ #ifndef LTC1257_H_ #define LTC1257_H_ /* * Low level access routines to the LTC1257 DAC device. */ /* * Port, where LTC1257 is connected to: * PORTC/PINC */ #define DACOUT PORTB #define DACIN PINB /* * Port configuration: * * Port pin LTC1257 * -------------------- * PB0 LOAD * PB1 DATA * PB2 CLK * */ #define DACCLK(LEVEL) DACOUT = (LEVEL) ? (DACIN | _BV(PB2)):(DACIN & ~_BV(PB2)) #define DACDATA(LEVEL) DACOUT = (LEVEL) ? (DACIN | _BV(PB1)):(DACIN & ~_BV(PB1)) #define DACLOAD(LEVEL) DACOUT = (LEVEL) ? (DACIN | _BV(PB0)):(DACIN & ~_BV(PB0)) #define LATCHTIMING 0x01 /* spend some time to the latch */ #define LEV_LOW 0 #define LEV_HIGH 1 void ltc1257_ll_init(void); inline void ltc1257_ll_write(unsigned int); /* * Low level initialisation routine for LTC1257. */ void ltc1257_ll_init(void) { /* Initial port/pin state */ DACCLK(LEV_LOW); /* clock pin low -> idle */ DACLOAD(LEV_HIGH); /* load pin high -> idle */ } /* * Low level write routine for LTC1257. * Awaits data in unsigned integer format * 12 bits masked (0x800 masks the data's MSB) */ void ltc1257_ll_write(unsigned int data) { volatile unsigned char bitctr = 0; for(bitctr = 0; bitctr < 0x0C; bitctr++) { DACDATA(data & 0x800); /* output MSB (bits [11..0]!) */ data <<= 1; /* shift next bit to MSB */ DACCLK(LEV_HIGH); /* rising edge -> load bit */ DACCLK(LEV_LOW); /* -> await rising edge */ } DACCLK(LEV_LOW); /* clock pin low -> idle */ for (bitctr = 0; bitctr < LATCHTIMING; bitctr++) ; DACLOAD(LEV_LOW); /* load pulled low -> output */ DACLOAD(LEV_HIGH); /* load pulled high -> idle */ } #endif /* LTC1257_H_ */ ------------------------------------------------------ Falls ihr eine Idee habt, woran das liegen könnte, nur her damit. Danke für die Mühen und liebe Grüße Bernd
Vorab: Funktionen haben in Header-Dateien nichts zu suchen. Vorab, die zweite: In einer Interruptroutine sind alle weiteren Interrupts sowieso geblockt. Deshalb ist das unnötig: ISR (TIMER0_OVF_vect) { cli(); : sei(); } Bernd P. schrieb: > Ein Motor drückt mir zwei um pi/2 verschobene in der Anzahl > zur Drehazahl proportionale Rechtecksignale durchs Kabel, > welche ich mit dem attiny45 auslese. > ISR(PCINT0_vect) > { > if (bit_is_set(PINB, 4) == bit_is_set(PINB, 5)) counter++; > else counter--; //zählen Richtungsabhängig > } Eine Encoderauswertung sieht normalerweise anders aus... Was soll denn der Code machen? Den Drehgeber auswerten und dann auf den DAC schreiben?
Hey! Danke schonmal für diese Info. Ja, der Drehgeber wird ausgelesen und der DAC gefüttert. Viele Grüße Bernd
Hey! Das Problem lag scheinbar in der ISR(PCINT0_vect) { if (bit_is_set(PINB, 4) == bit_is_set(PINB, 5)) counter++; else counter--; //zählen Richtungsabhängig } Einfach nur hochzählen klappt. Die bit_is_set() hat nich funktioniert. Jemand ne Idee, warum? Ansonsten kann das Problem als gelöst angesehen werden. Viele Grüße Bernd
Bernd P. schrieb: > ISR(PCINT0_vect) > { > if (bit_is_set(PINB, 4) == bit_is_set(PINB, 5)) counter++; > else counter--; //zählen Richtungsabhängig > } > > Einfach nur hochzählen klappt. Die bit_is_set() hat nich funktioniert. > Jemand ne Idee, warum? Ansonsten kann das Problem als gelöst angesehen > werden. Ich habe eine Vermutung: bit_ist_set sieht wahrscheinlich so aus: #define bit_is_set(a,b) ((a) & (1 << (b)) Dieses Makro gibt ungleich 0 zurück wenn das bit gesetzt ist, aber trotzdem keinen festen Wert. Das sollte funktionieren:
1 | if(bit_is_set(PINB, 4) && bit_is_set(PINB, 5)) |
Samuel K. schrieb: > Dieses Makro gibt ungleich 0 zurück wenn das bit gesetzt ist, aber > trotzdem keinen festen Wert. Nicht fest, aber definiert. Zitat avr-gcc-tutorial:
1 | bit_is_set (<Register>,<Bitnummer>) |
>Die Funktion bit_is_set prüft, ob ein Bit gesetzt ist. Wenn das Bit gesetzt >ist, wird ein Wert ungleich 0 zurückgegeben. Genau genommen ist der >Rückgabewert die Wertigkeit des abgefragten Bits, also 1 für Bit0, 2 für >Bit1, 4 für Bit2 etc.
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.