www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI-Problem nach ADC-Wandlung


Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!!!

Ich bin gerade daran eine längere AD-Wandlung zu machen welche gefolgt 
wird von einer SPI-Übertragung zu einem anderen Controller.
Das ganze wird von einer 2 Werte AD-Wandlung nochmal gefolgt.
Wenn die Endlosschleife, in der diese Programmabfolge steht, zum 2. mal 
durchlaufen wird sendet die Spi nicht mehr.
Ich habe daraufhin mehrere Versuche gemacht, nachgelesen usw. und bin 
dann durch probieren darauf gekommen, wenn die AD-Wandlung nach der 
SPI-Übertragung weggelassen wird läuft es.
Kann mir da jemand weiterhelfen?
Ich weiss echt nicht an was das noch liegen könnte.

MfG

Benjamin

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
< beliebigen Glaskugelwitz einfügen >

wie wär's mit ein bischen mehr Infomationen für die, die dir helfen 
sollen/könnten ?
z.B.:
welche(r) Controller/Programmiersprache/Compiler/ADC/µC-Takt/etc?
Ich hab da scheinbar mehr Fragen als du ;)

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry verwende einen ATmega8l , programmiere ihn in C (AVR Studio) und 
er hat einen CPU Takt von 3,6864 MHz.
Ist ein komisches Problem, da der erste Durchlauf funtioniert und beim 
2. Durchlauf bleibt er stehen, s.o.

MfG

Benjamin

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- gibtst du auch ein bischen Code zum anschauen heraus?
- hast du das Problem mit der Hardware oder dem Simulator (der ja seine 
eigenen Fehler hat) ?
Denn, wenn das ein ganz gewöhnliches Problem wäre, hättest du doch 
bestimmt mit der Foren-suche eine Lösung gefunden ;)

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar gerne, das hilft sicher dem Verständniss :-)
Ich habe die Probleme mit der Hardware.
Die Programmsequenz läuft einmal durch beim 2. mal bleibt er bei der 
SPI-Übertragung stehen (SPI_MasterTramsmitc).
Auf der anderen Seite befindet siche ein anderer Controller, gleichen 
Typs, welcher auch eine Messaufgabe hat und über UART an einen Rechner 
verbunden ist.
Das Ziel wäre nun beide unabhängig voneinander betreiben zu können und 
in der Ruhephase (PinB1 nicht) die Werte eimal über die SPI an den 2. 
Controller zu übergeben und dann gemeinsam mit den anderen Werten an die 
Schnittstelle geben.
Controller 2 mit UART funtioniert einwandfrei und die Übertragung der 
Werte über die SPI an Controller 2 auch (allerdings nur beim ersten 
mal).
Hier nun der wichtigste Sourcecode-Ausschnitt:


void SPI_MasterInit(void)

{
/*Set MOSI and SCK output, all others input */
DDRB |= (1<<PINB3)|(1<<PINB5);
/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

}

void SPI_MasterTransmitc(uint8_t Data)
{
/* Start transmission */
SPDR = Data;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
}

uint16_t ReadChannel(uint8_t mux)
{
uint16_t result = 0; //Initialisieren wichtig, da lokale Variablen nicht 
automatisch initialisiert wird

ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler 
setzen auf 8 (1) und ADC aktivieren (1)
ADMUX = mux; // Kanal waehlen

//ADMUX = ADMUX | (1<<REFS1) | (1<<REFS0);

ADMUX |= (0<<REFS1) | (1<<REFS0); // Spannungsversorgung als 
Referenzspannung nutzen nach Aktivieren des ADC wird ein "Dummy-Readout" 
empfohlen,
//man liest also einen Wert und verwirft diesen, um den ADC "warmlaufen 
zu lassen" */

ADCSRA |= (1<<ADSC); // eine ADC-Wandlung

while ( ADCSRA & (1<<ADSC) )
{
; // auf Abschluss der Konvertierung warten
}

ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC) )
{
; // auf Abschluss der Konvertierung warten
}
result=ADCW;
return result;
}

int main(void)
{
DDRC=0x00;
DDRB=0xff;
DDRD=0xff;
PORTB = (0<<PB0);
uart_init(tx, rx);
TIFR = (1<<TOV1);
TIMSK = (1<<TOIE1);
TCNT1H=0x1F;
TCNT1L=0;
TCNT2=0;
TCCR1B = (1<<ICES1);
DDRB = (1<<PINB2);
SPI_MasterInit ();
sei();
while(1)
{

  while ((PINB & (1<<PINB1)))
  {
    if (flag_timer)
    {
      TCCR1B |= (0<<CS10)|(0<<CS11)|(0<<CS12);
      TCNT1H=0;
      TCNT1L=0;
      TCNT2 = 0;
      TCCR1B|=(1<<CS10)|(1<<CS11)|(0<<CS12);//Startet Timer 1 (16 Bit)
      for(x=0; x<40000; x++);
      if(!(PINB & (1<<PINB1)))
        break;
      flag_timer=0;
      flag_ausg = 1;
      flag_kurve1 = 1;

    }

    if (flag_kurve1)
    {
      adca0=adc0;
      adc0 = ReadChannel(0);
      if (ms0>adc0)
      {
        if (adc0>adca0)
        {
        }
        else
        {
          DDRB &= (0<<PB0);
          PORTB |= (1<<PB0);
          //while(!(TIFR & (1<<ICF1)));
            //cli();
          wh_k1 = TCNT1H;
          wl_k1 = TCNT1L;
          c_k1 = TCNT2;
            //sei();
          TIFR |= (1<<ICF1);
          DDRB |= (1<<PB0);
          PORTB &= (0<<PB0);
        }
      }
      else
      {
        flag_kurve1 = 0;
        flag_kurve2 = 1;
      }
    }

    if (flag_kurve2)
    {

      adca1=adc1;
      adc1 = ReadChannel(1);
      if (ms1>adc1)
      {
        if (adc1>adca1)
        {
        }
        else
        {
          DDRB &= (0<<PB0);
          PORTB |= (1<<PB0);
          //while(!(TIFR & (1<<ICF1)));
          //cli();
          wh_k2 = TCNT1H;
          wl_k2= TCNT1L;
          c_k2 = TCNT2;
          //sei();

          TIFR |= (1<<ICF1);
          DDRB |= (1<<PB0);
          PORTB &= (0<<PB0);
        }
      }
      else
      {
        flag_kurve1 = 0;
        flag_kurve2 = 0;
      }
    }

  }
    while(!(PINB & (1<<PINB1)))
    {
      if (flag_ausg)
         {
        cli();
        //tl =TCNT1L;
        //th = TCNT1H;
        //tc = TCNT2;
        for(y=0;y<30000;y++);
        if((PINB & (1<<PINB1)))
          break;
        TCCR1B |= (0<<CS10)|(0<<CS11)|(0<<CS12);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('1');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('2');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('3');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('4');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('5');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('6');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('7');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('8');
        for(y=0;y<3000;y++);
        PORTB &= (0<<PINB2);
        SPI_MasterTransmitc('9');
        for(y=0;y<3000;y++);
        TCNT1H=0x1F;
        TCNT1L=0;
        TCNT2 = 0x00;
        sei();
        flag_timer = 1;
        flag_kurve1 = 0;
        flag_kurve2 = 0;
        flag_ausg = 0;
        wh_k1=0;
        wl_k1=0;
        c_k1=0;
        wh_k2=0;
        wl_k2=0;
        c_k2=0;
        tl=0;
        tc=0;

ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler 
setzen auf 8 (1) und ADC aktivieren (1)
ADMUX = 0; // Kanal waehlen
ADMUX |= (0<<REFS1) | (1<<REFS0); // Spannungsversorgung als 
Referenzspannung nutzen nach Aktivieren des ADC wird ein "Dummy-Readout" 
empfohlen,
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC)); // auf Abschluss der Konvertierung warten
ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
while ( ADCSRA & (1<<ADSC));
// auf Abschluss der Konvertierung warten
ms0 = ADCW;
        }
      }
    }
}

Hoffe du kannst mir helfen, bin schon über 2 Tage an diesem sch... 
Problem.
Dank!

MfG Benajmin

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin wrote:

> Controller 2 mit UART funtioniert einwandfrei und die Übertragung der
> Werte über die SPI an Controller 2 auch (allerdings nur beim ersten
> mal).

Woher willst Du das wissen ?

Wenn ich Dein Programm richtig verstehe überträgt es nur den String 
"123456789".



> Hier nun der wichtigste Sourcecode-Ausschnitt:

Ja, da jubeln hier alle, daß sie wieder mal rumraten und sich 
totscrollen dürfen.

Wozu gibt es den "Dateianhang" ?

Richtig, damit man einen kompilierbaren (kein PDF, JPG usw.) 
abgespeckten (aller rauskommentierter Code entfernt), kommentierten 
Sourcecode postet, der den Fehler enthält (geprüft).

Peter

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo hast du den PB2 angeschlossen?

und was soll  z.B.    " DDRB &= (0<<PB0); "
meinst Du damit evtl  " DDRB &= ~(1<<PB0);" ?

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, solchen Code hatte ich nicht erwartet/erhofft :(
Was macht dieses Programm eigentlich ?
 Es bleibt nämlich nicht viel übrig, falls die Compiler optimierung 
eingeschaltet wird (z.B. leere Schleifen, "0<<n").
es gibt hoffentlich ISRs für den/die?! Timer?
... (sry, aber mir fehlen die Worte)

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>/*Set MOSI and SCK output, all others input */
>DDRB |= (1<<PINB3)|(1<<PINB5);
setze den SS PIN auf ein definiertes Level am besten Output sonst 
schaltet der Controller in den Slave Modus und wartet (datenblatt lesen)


for(y=0;y<3000;y++);
Ich weiß nicht von wann dein C-Buch ist (1980/85?)
sowas funktioniert schon lange nicht mehr
for(y=0;y<3000;y++); heißt mache 3000 mal nichts
3000 mal nichts machen ist genauso wie nichts machen, damit fällt das 
weg!
zum Rest des Programmes fehlen mir auch die Worte

Autor: Joerg X. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
damit du dir nicht so angemacht vorkommst:
bei Problemen sollte ein Programm gepostet werden, dass:
1. nur die Teile enthält, die Probleme machen (in deinem Fall ohne 
Timer!)
2. kompilierbar ist (also Headerdateien, Makros, main() und alle 
aufgerufen Funktionen oder Dummies)
3. sollte die Schaltung beschrieben werden (was hängt an PB1 und PB0?)

Ich hab mal ein Prog angehängt, dass einen ADC-Wert misst und dann 1 2 3 
4 ... per SPI sendet, vor dem Senden wird ein Pin auf 0 gesetzt und 
anschließend wieder auf 1 (wie eben ein klassischer \slaveselect)

( mir stürzt allerdings der Simulator ab, wenn ich die Optimierung 
anschalte :(, bei -O0  geht's aber )

Entschuldigung, dass "wir" erwarten, dass der Fragensteller mitdenkt

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werde mich nächstens an die "Regeln" halten.
Danke für die Tipps und das Beispielprogramm, hat mir sehr geholfen.
Mein Problem lag in dem SPI teil des Programms.
Danke nochmals!!!

MfG

Benjamin

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.