mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik At90Usb interrupt


Autor: Markus Haege (mh1977)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stell compilerbaren Code hier rein, oder dir kann nur Olga helfen...

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  while (ADCSRA & (1<<ADIF)){}

Entscheide dich: Entweder per Interrupt auf den ADC zugreifen (mit der 
dazugehörigen ISR) oder per Polling.

Autor: Markus Haege (mh1977)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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();
  }
}

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Markus Haege (mh1977)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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: Stefan Salewski (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.