attiny adc macht nicht was er soll

Gast #1392839
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?
Gast #1400991
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.
Angehängte Dateien:
#1401018
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?
Gast #1401019
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.
Gast #1401020
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.
Gast #1401026
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);}
Gast #1401039
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!
#1401079
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?
Gast #1401099
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.
Gast #1403787
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ß.
Gast #1403797
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?
#1403873
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren