At90Usb interrupt

OP #1338296
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
OP
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();
  }
}
Gast
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
Gast
>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.
Gast
>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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.