Forum: Mikrocontroller und Digitale Elektronik attiny adc macht nicht was er soll


von Philipp Karbach (Gast)


Lesenswert?

Hallo, ich lese gerade einen Beschleunigungssensor aus. Mit einem mega16 
klappt das wie gewünscht. Die Werte im Ruhezustand der drei Achsen 
liegen bei etwa 400.

Nun muss ich die ganze Anwendung aber auf einem attiny84 laufen lassen.
Dieser soll per software UART die achsenwerte rausschicken. Die Software 
UART (dannegger code) funktioniert. Der ADC macht aber zicken:

ich initialisiere den PORTA folgendermaßen:

DDRA = 0x0;
PORTA = 0x0;

den ADC lese ich mit meiner Standardfunktion die beim mega16 klappt:

int ReadChannel(int channel)
{
  int i;
  int result = 0;
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
  ADMUX = channel;
  ADMUX |= (1<<REFS1) | (1<<REFS0);
  ADCSRA |= (1<<ADSC);
  while (ADCSRA&(1<<ADSC));
  for(i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC);
    while (ADCSRA&(1<<ADSC));
    result += ADCW;
  }
  ADCSRA &= ~(1<<ADEN);
  result /= 4;
  return result;
}

Lese ich nun den ADC stürzt der tiny scheinbar ab, es wird nichts mehr 
an die UART gegeben. Ich sehe im Datenblatt keinen großen unterschied 
zwischen mega16 und tiny in bezug auf den adc... Was mache ich 
möglicherweise falsch?

von Hubert G. (hubertg)


Lesenswert?

In meinem Datenblatt steht bei ADMUX |= (1<<REFS1) | (1<<REFS0);
reserved.

von Philipp Karbach (Gast)


Lesenswert?

oh du hast recht! kann es gerade nicht testen aber vielleicht ist das 
genau mein problem!

von Dimon11/09 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo allerseits,

Hab mich gerade mit selben Problem beschäftigt - Attiny24 ADC.

Nun Buch nachgelesen, Datenblat durchgewühlt und diesen Forum auch. Das 
obige Beispiel, sehr identisch mit meinen außer Filterung vielleich. Die 
Registereinstellungen 1:1. Hab einfach keinen Plan wie ich das zum 
laufem Bringe.

Bin sehr dankbar für jede Art der Anregung.

von holger (Gast)


Lesenswert?

>Hab einfach keinen Plan wie ich das zum laufem Bringe.

Was soll passieren? Was passiert?
Lass mich raten: Alle LEDs leuchten?

von Karl H. (kbuchegg)


Lesenswert?

Dimon11/09 schrieb:

> obige Beispiel, sehr identisch mit meinen außer Filterung vielleich. Die
> Registereinstellungen 1:1.

Das kann jeder sagen.
Ich hab aber jetzt absolut keine Lust, die Bits der Hex-Zahlen 
auseinanderzupfriemeln und nachzusehen, was du da eigentlich alles 
gesetzt hast. Nimm dir ein Beispiel am Code weiter oben, wie man sowas 
lesbar macht

>  // ADC Enable, ADC Clock = F_CPU/2

4Mhz ADC Takt?
Kann das der Tiny überhaupt?

von Dimon11/09 (Gast)


Lesenswert?

Hey, ging flott!

Ich lege den PA7 zu Testzwecken mal auf die Masse mal auf Vcc. Es sollte 
sich was mit LED's was tun (mal alle mal keine bzw. nur eine an). Egal 
was ich mit der Spannung mache leuchten alle Leds ^^ (gut geraten :-). 
Obwohl ich die Funktion vergleich(); getestet hab.

Ja so ist der Stand.

von MWS (Gast)


Lesenswert?

>>  // Interne SpannungsReferenz von 1,1V und PA7 Analog-Eingang
>>  ADMUX = 0x83;

Nicht PA7, sondern PA3 ist damit der Eingang.

>>  // Ergebniss Links In dem DATA REGISTER ausgerichtet ADCH = ADC9
>> ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2
>>  //                           ADCL = ADC1 ADC0
>>  ADCSRB = 0x00;

Hier stimmt der Kommentar (left adjust) nicht zum Register (right 
adjust)

Würdest Du nicht Hexwerte hinschreiben, würdest Du selber besser 
durchblicken.

von holger (Gast)


Lesenswert?

>Egal was ich mit der Spannung mache leuchten alle Leds ^^ (gut geraten :-).

Das war nicht wirklich geraten ;)

Probier doch mal sowas:

    if(Data>100){SET_LED_A(1);}
    else {CLEAR_LED_A(1);}


    if(Data>200){SET_LED_A(2);}
    else {CLEAR_LED_A(2);}

von MWS (Gast)


Lesenswert?

>> 4Mhz ADC Takt?
>> Kann das der Tiny überhaupt?

Wenn nicht die CKDIV8 Fuse umprogrammiert wurde, läuft der ATiny24 
frisch aus der Schachtel mit 1MHz, / 2 = 500kHz kann der ADC schon 
packen.

von Dimon11/09 (Gast)


Lesenswert?

@MWS
HAb während der Experimente vergessen die Komentare zu ändern.

Und haupsache MANN Vielen Dank hab vor lauter Binär unh Hex den 
Überblick verloren. Natürlich falscher Eingang jeztz funzt auch wie es 
soll!!!

ADC3 (PA3) 10000011 = 0x83

ADC7 (PA7) 10000111 = 0x87


Danke euch allen!

von Karl H. (kbuchegg)


Lesenswert?

MWS schrieb:
>>> 4Mhz ADC Takt?
>>> Kann das der Tiny überhaupt?
>
> Wenn nicht die CKDIV8 Fuse umprogrammiert wurde, läuft der ATiny24
> frisch aus der Schachtel mit 1MHz,

:-)
Der F_CPU Wert behauptet aber was anderes
:-)

von Karl H. (kbuchegg)


Lesenswert?

Dimon11/09 schrieb:
> @MWS
> HAb während der Experimente vergessen die Komentare zu ändern.
>
> Und haupsache MANN Vielen Dank hab vor lauter Binär unh Hex den
> Überblick verloren. Natürlich falscher Eingang jeztz funzt auch wie es
> soll!!!
>
> ADC3 (PA3) 10000011 = 0x83
>
> ADC7 (PA7) 10000111 = 0x87

Und nochmal:
Schreib das alles nicht als HEX-Zahl, dann hast du diese Probleme erst 
gar nicht. Schreib deinen Code, so, dass der Code sein eigener Kommentar 
ist, dann pasiiert dir auch nicht, dass der Kommentar falsch ist.

Was ist so schlimm an

   ADMUX = ( 1 << REFS1 ) |        // 1.1V Referenz
           PA7;

ausser, das man es lesen könnte und weniger Fehler macht?

von MWS (Gast)


Lesenswert?

>> :-)
>> Der F_CPU Wert behauptet aber was anderes
>> :-)

Yep, da hatte der Poster wohl Glück, daß das auch nicht gestimmt hat, 
denn mit 4 MHz Clcok würde der ADC jetzt ganz bestimmt nicht laufen :D

Da keine Delays vorkommen, ist die F_CPU Angabe zumindest in diesem Code 
nicht von Belang.

von Thomas (kosmos)


Lesenswert?

wenn alle LEDs leuchten deutet das darauf hin das die Pullups noch nicht 
deaktiviert wurden, so liegt an jedem Pin über den internen Pullup die 
Versorgungsspannung an. Such mal nach PUD im Datenblatt oder unter I/Os 
steht auch was dazu

von Dimon11/09 (Gast)


Lesenswert?

@Karl heinz Buchegger

Ich mag diese Schreibweise auch, genau aus dem Grund, dass der Code sein 
eigener Kommentar ist. Hab mich aber mal böse auf die Schnauze damit 
gelegt.

Hab versucht so die Pins zu setzen, es ging um WGM02-Bit. AVR-Studio hat 
es einfach nicht gesetzt in TCCR0A und in TCCR0B (wo es sich normaler 
weise befindet) hat es gemeckert, dass es dort nicht vorhanden ist. Mit 
TCCR0B = 0x08 hat prima funktioniert.

Gruß.

von Dimon11/09 (Gast)


Lesenswert?

Mal andere Frage:

Hab die Zeile    data = ADCW;   auf   data = ADCW/1024;

und              ADMUX = (1<<REFS1)|(0<<REFS0);  // 1,1V Ref   auf

                 ADMUX = (0<<REFS1)|(0<<REFS0);  // Vcc  Ref

ersetzt.

Mann könnte meinen dass bei Vcc = 5V und 5V an PA7    data ~5 ist. 
Allerdings ist das bei mir nur bei:

                                     data = ADCW/176;

Was habe ich übersehen bzw. wo könnte der Denkfehler sein?

von holger (Gast)


Lesenswert?

Überleg mal wie groß dein maximaler Wert für
ADCW werden kann! Tip: 10Bit

von Karl H. (kbuchegg)


Lesenswert?

Dimon11/09 schrieb:
> @Karl heinz Buchegger
>
> Ich mag diese Schreibweise auch, genau aus dem Grund, dass der Code sein
> eigener Kommentar ist. Hab mich aber mal böse auf die Schnauze damit
> gelegt.
>
> Hab versucht so die Pins zu setzen, es ging um WGM02-Bit. AVR-Studio hat
> es einfach nicht gesetzt in TCCR0A und in TCCR0B (wo es sich normaler
> weise befindet) hat es gemeckert, dass es dort nicht vorhanden ist. Mit
> TCCR0B = 0x08 hat prima funktioniert.

Die Schreibweise

    TCCR0B = ( 1 << WGM02 );

ist nur eine andere Schreibweise für

    TCCR0B = 0x08;

Wenn WGM02 als
#define WGM02   3
definiert ist, dann gibt es aus C-Sicht keinen Unterschied zwischen den 
beiden Schreibweisen. Beides produziert identischen Code!

Das ist ungefähr so, wie wenn du schreiben würdest
1
   seconds_per_day = 86200;

und
1
#define SEC_PER_MIN  60
2
#define MIN_PER_HOUR 60
3
#define HOUR_PER_DAY 24
4
5
   seconds_per_day = (long)SEC_PER_MIN * (long)MIN_PER_HOUR * (long)HOUR_PER_DAY;

wären fundamental unterschiedlich.
In der zweiten Version sieht man viel besser, wie sich der Zahlenwert 
zusammensetzt (BTW: Hast du bemerkt, dass ich mich mit den 86200 
verrechnet habe :-)


Wenn also dein AVR-Studio-Simulator angezeigt hat, dass das Bit nicht 
gestezt wurde, dann war irgendetwas anderes faul.

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
Noch kein Account? Hier anmelden.