Hallo, ich probiere derzeit einen Messwert vom ADC über USB an den PC zu bringen. Es klappt auch so weit, doch irgendwie läßt sich der Interrupt nicht aktivieren, so dass ich nie abwarten kann, bis die Messung fertig ist. Ich glaube das ist das Problem, weil ich immer zweimal auf den Knopf drücken muss am PC bis ich die richtige Zahl habe. In main() mache ich eine dummy-Messung: //für ADC //SREG |= (1<<I); sei(); ADMUX |=(1<<REFS0)|(1<<REFS1); ADCSRA |= (1<<ADEN)|(0<<ADATE)|(1<<ADIE);//<<--hier ist das Problem ADCSRB |=(0<<ADTS0)|(0<<ADTS1)|(0<<ADTS2); DIDR0 |=(1<<ADC0D); ADMUX |=(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3)|(0<<MUX4); ADCSRA |=(1<<ADSC); while (ADCSRA & (1<<ADIF)){} uint8_t LB; uint8_t HB; LB=ADCL; HB=ADCH; ich kann meinen avr nur an usb anmelden, wenn ich (1<<ADIE) weglasse. Ich brauch es aber für die Schleife... Wo ist denn das Problem? SREG|=(1<<I) mag er auch nicht. danke Markus
> while (ADCSRA & (1<<ADIF)){}
Entscheide dich: Entweder per Interrupt auf den ADC zugreifen (mit der
dazugehörigen ISR) oder per Polling.
Ok, Quellcode: Es ist die Firmware von Salewski... In Main() mache ich eine Dummymessung, doch wenn ich ADIE einschalte...dann geht nichts mehr mit USB. Den zweiten Kommentar habe ich nicht ganz verstanden... entscheiden? Für was? int main(void) { //für ADC //SREG |= (1<<I); sei(); ADMUX |=(1<<REFS0)|(1<<REFS1); ADCSRA |= (1<<ADEN)|(0<<ADATE)|(1<<ADIE); ADCSRB |=(0<<ADTS0)|(0<<ADTS1)|(0<<ADTS2); DIDR0 |=(1<<ADC0D); ADMUX |=(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3)|(0<<MUX4); ADCSRA |=(1<<ADSC); //while (ADCSRA & (1<<ADIF)){} uint8_t LB; uint8_t HB; LB=ADCL; HB=ADCH; //ADCSRA |=(1<<ADSC); cli(); CLKPR = (1<<7); CLKPR = 0; // clock prescaler == 0, so we have 16 MHz mpu frequency with our 16 MHz crystal USART_Init(); USART_WriteString("\r\n------------------------------------------------- ---------\r\n"); UsbDevLaunchDevice(false); // UsbDevWaitStartupFinished(); // no reason to wait blinkforever(); return 0; } UsbDevFillEP1FIFO(void) { if UsbDevTransmitterReady() { uint8_t LB; uint8_t HB; ADCSRA |=(1<<ADSC); while (ADCSRA & (1<<ADIF)){} LB=ADCL; HB=ADCH; UsbDevClearTransmitterReady(); UsbDevClearNAK_ResponseInBit(); //UsbDevSelectEndpoint(1); UsbDevWriteByte(LB); UsbDevWriteByte(HB); UsbDevSendInData(); } }
Das Bit ADIE gibt den ADC-Interrupt frei. Dadurch springt der Controller beim Auftreten des auslösenden Ereignisses in die ISR. Eine Abfrage, ob das ADIF-Flag gesetzt wurde, kann nichts bringen, da zwischenzeitlich die ISR angesprungen wurde. Die fehlt aber scheinbar in deinem Programm. Eine fehlende ISR bringt den Effekt, dass der Controller immer versucht, in die ISR zu springen, da das ADIF-Bit nicht zurückgestzt wurde. Weiterhin sorgt das Nichtvorhandensein der ISR dazu, dass der Controller irgendwohin springt (Dummy-ISR?); zumindest erzeugt der GCC AFIAK solche Dummy-ISRs aus welchen Gründen auch immer. Das Datenblatt deines Controllers beschreibt, wie man ADC-Interrupts behandelt...
Hallo, wenn Du den Interrupt für den ADC freigibst, muß es natürlich auch die passenden Interruptroutine geben, in dieser wird dann der ADC ausgelesen und entsprechend reagiert. Außer wird automatisch das Interruptflag des ADC gelöscht. Wenn Du per Polling abfragst, wie hier, dann darf der ADC-Interrupt natürlich nicht freigegeben werden, es wird einfach gewartet, bis der ADC das Bit ADSC im Register ADCSRA wieder auf 0 setzt, dann ist er fertig. Darauf hat STK500-Besitzer (Gast) hingewiesen. Gruß aus Berlin Michael
>Ok, Quellcode: Es ist die Firmware von Salewski...
Wie soll das denn einer ahnen...
Mein Beispiel hat den ADC in der ISR ausgelesen, soweit ich mich
erinnere. Wenn Du keine ISR verwendest, musst Du den ADC Code sicher
irgendwie anpassen, wie die anderen oben schon schrieben.
Danke... das mit den ISR wußte ich nicht. Ich könnte dann auch eine while-Schleife schreiben, die wartet bis ADSC auf 0 ist...oder? Ich denke damit komme ich weiter Markus
>Autor: Markus Haege (mh1977) >Datum: 17.07.2009 18:51 >Danke... >das mit den ISR wußte ich nicht. Ich könnte dann auch eine >while-Schleife schreiben, die wartet bis ADSC auf 0 ist...oder? Ohne ISR ist einfacher. Ich kann Dir momentan dazu nicht viel sagen, da ich mich in den letzten 18 Monaten nicht mit der Firmware beschäftigt habe. Sollte aber nicht so schwierig sein. Ich würde zunächst mal versuchen ohne ISR irgendwelche Datensätze über USB zu schicken. Wenn das geht machst Du die ADC-Abfrage ohne ISR und schickst dessen Daten dann Über den USB-Port. ADC und USB haben ja nicht direkt etwas miteinander zu tun, das war ja nur ein Beispiel. Und zum ADC findest du genug, auch hier im Forum.
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.