PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : A/D und serielle DÜ beissen sich



vajk
18.04.2006, 15:59
Hilfe :-)

Ich hab ein merkwürdiges Problem, ich hab zwei atmega128 via RS485-Bus verbunden ... Datenübertragung (DÜ) per RS485 ... klappt alles prima ..

Jetzt aktiviere ich bei einem davon die A/D-Wandlung und messe im Wechsel an vier Ports eben Spannungen und auf einmal geht die DÜ nicht mehr (wobei ich glaube, daß er keine Daten mehr empfängt) ...

... wenn die Meßwerte genau 0 sind, dann gehts ohne Probleme ... (Meßwerte werden zusätzlich auf LCD ausgegeben, Wandlung funktioniert prima) ....
.. sobald die Werte flackern, bzw. nicht 0 - keine DÜ ????

Hat mir jemand einen Tipp ?

Liebe Grüße,
Vajk

P.S.: Ich hoffe ihr könnt mir - mit dem Blick in die virtuelle Glaskugel - ohne Code und Schaltplan einen Tipp geben ...

ogni42
18.04.2006, 16:04
Schaltplan? Code(schnipsel)?

vajk
19.04.2006, 13:38
... neue Fragestellung:

Wenn ich den A/D-Wandler nach Wertespeichern im Interrupt wieder starte, bleibt keine Zeit mehr für RS232 und ähnliches ?

Da der Messknecht im RS485-Slave-Modus nicht bestimmen kann, wann er abgefragt wird - und er binnen 100 ms Antworten muß - und ich gleichzeitig auch noch zwei Schrittmotoren ansteuere .. sollte ich für die A/D-Messung wohl einen zweiten Controller hernehmen ? Oder eben seltener messen ?

Grübel ? .. liege ich da richtig ?

Hier meine Codes:


int main(void)
{
avr_init(); // incl LCD_Init() und LCD_Clear() !
AD_Messung_AN();
for(;;)
{
if(UART_rx_loop())
UART_DATA_Auswertung();

MesswertVerarbeitung(); // wenn flagloopjob gesetzt

MesswertAusgabe(); // eben wenn fällig
DATA_Verarbeitung();
}
return(0);
}

static void avr_init(void)
{
...
ADCSRA = (1 << ADEN); // A/D-Wandlung ein
}

//-------------------------------------------------------
void AD_Messung_AN()
{
ADMUX = 0; // AREF ext, left Adj.,NoGain
// nicht permanente Messung aber mit Interrupt
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 1 << ADIF) | (
}

//-------------------------------------------------------
SIGNAL(SIG_ADC)
{
switch(ADMUX)
{
case 0x0 :
{
UmessVor = ADC; // UmessVor = ADCL; UmessVor += (ADCH << 8); // LSB/MSB
ADMUX = 0x1; // (1 << AD_U_VOR);
}
break;
case 0x1 :
{
UmessRueck = ADC; // UmessRueck = ADCL; UmessRueck += (ADCH << 8); // LSB/MSB
ADMUX = 0x2; // (1 << AD_U_RUECK);
}
break;
case 0x2 :
{
UmessPosition = ADC; // UmessPosition = ADCL; UmessPosition += (ADCH << 8); // LSB/MSB
ADMUX = 0x4; // (1 << AD_U_RUECK);
}
break;
case 0x4 :
{
UmessTemperatur = ADC; // UmessTemperatur = ADCL; UmessTemperatur += (ADCH << 8); // LSB/MSB
ADMUX = 0x0; // (1 << AD_U_RUECK);
}
break;
}

ADCSRA |= (1 << ADSC); // neue Messung starten
}

-------------------------------------------------------
void MesswertAusgabe(void)
{
if(old_UmessVor != UmessVor)
{
old_UmessVor = UmessVor;
sprintf(bufi, "%04x", UmessVor);
LCD_WritePosString(2, 2, bufi, 0);
}

......
}

ogni42
19.04.2006, 18:11
Mit Deinen Einstellungen bekommst Du alle 100us einen ADC Interrupt.

Wenn Du die Messwerte nicht in dieser Frequenz benötigst, solltest Du das Starten der nächsten Messung aus der ISR rausnehmen und nur bei Bedarf anstossen (oder über einen Timer).

vajk
19.04.2006, 18:40
Hallo ogni,
ja Du hast Recht !

Hatte auch zwischenzeitlich die Doku nochmal durchgelesen und meine Vorgehensweise analysiert ...

Eine Messung dauert ja nicht so lange bei 16 MHz und 128 teilung = 104 us ... das war das Problem, der "Permanentinterrupt" läßt einem dann keine Zeit mehr für die schönen Dinge des uC ;-)

Hab ihn jetzt in die Timer-Jobs eingereiht, jetzt wird alle 137 ms eine Messung angestoßen, das reicht ...

.. und siehe da, die Messung zappelt auch nimmer in den Werten .. mal ein Digit, mehr nicht .. das o.k.

(Hatte mich über das erhebliche Zappeln auch schon gewundert und es auf den Versuchsaufbau ohne 10uH-Spule und C geschlossen ... )

Danke

Alles Gute weiterhin,
Vajk

ogni42
20.04.2006, 20:09
Schön, dass es jetzt funktioniert.

Das LC-Glied solltest Du, wenn es Dir auf die Genauigkeit der Messwerte ankommt, auf jeden Fall noch einbauen. Das bringt nochmal eine erhebliche Verbesserung.

vajk
20.04.2006, 21:04
Ja, Danke, werd ich .. der Versuchsaufbau tut jetzt in fast allem, wie ich es brauche .. dann kommts Layout dran, da wird das berücksichtigt ... inkl. Beschleunigung der Schrittmotoren usw. nur in bestimmten Kombinationen, findet keine Beschleunigung statt .. daß muß ich noch mal überarbeiten ...
Liebe Dank,
Vajk