ATtiny 861 ADC, AVR Studio

Gast #3470600
Lesenswert?

Hallo,

gleich zwei Probleme mit dem ATtiny861:

1.
Beim Auslesen der Fusebits wird ATmega8 identifiziert, obwohl ATtiny im 
Projekt ausgewählt.
Es werden 2MHz Taktfrequenz ausgelesen, obwohl 861 nachweislich mit 1MHz 
läuft. Habe bereits zwei 861 verfused, indem ich auf 1MHz (was 
eigentlich auch schon eingestellt war) umgestellt habe. Mit ext. Takt 
nicht wieder zum laufen gebracht.

2.
Der ADC gibt Werte im Bereich 900-1023 aus, obwohl die Spannung am 
ADC-Eingang zwischen 0-5V variiert wird.
Die gleichen Einstellungen des ADC haben beim mega8 funktioniert, nach 
Datenblatt des 861 sehe ich bei der Konfiguration keine Unterschiede, 
ausser zusätzlicher Möglichkeiten.

Benutze STK500, AVR Studio 4.19

Gruß
Artur
Angehängte Dateien:
Gast #3470611
Lesenswert?

Achja, Code...
1
#include    "tacho.h"
2

3

4
//Funktionen
5
void init_Tacho(void);
6

7
//////////////////////////////////
8
/////////////////////////////////////////////////////////////////
9
//////////////////////////////////////////////////////////////////////////////////////////////////
10
int main (void)
11
{
12
  init_Tacho();
13

14
  sei();                        //Interrupts an
15

16
  //Hauptschleife
17
  while(1) 
18
  { 
19
    zeige_int(ADC_result);
20

21
  } //while(1)
22

23
}//main()
24

25
void init_Tacho(void)
26
{
27
  //Registerinitialisierung
28
  TCCR1B  = (1<<CS12) | (1<<CS11);            //Prescaler 1/32
29

30
  TIMSK  = (1<<TOIE1);           //Interrupt bei Overflow von Timer 1 (Blinker)
31

32
  DDRA   = 0b11101010;            //PA0 ADC0, PA2 Hall-Sensor INT1, PA4 ADC3,
33
  DDRB   = 0b10100111;                      //PB3, PB4, PB6 sind Eingänge
34

35
  PORTA  = 0xff;          
36
  PORTB  = 0xff;  
37
  
38
  main_state = state_U_Bat;  
39
        
40
  // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
41
  ADMUX = (1<<MUX1) | (1<<MUX0);
42
}
43

44
ISR(TIMER1_OVF_vect)  //Taster, Blinker, Aktualisierung der Geschwindigkeit, ADC und Ausgabe --------- alle ca. 8ms
45
{
46
  i++;
47
  if(i == 80)  //bei 80*8ms=640ms und Prescaler=1/32 --> 0.64sec
48
  {
49
    BLINKER_PORT ^= (1<<BLINKER); //LED AUS
50

51
    i = 0;
52
  }
53

54
  if(i == 1)
55
    ADCSRA = (1<<ADEN) | (1<<ADSC);  // ADC anstossen
56
  if(i == 2)
57
    ADC_result = ADC;
58
}
#3470708
Lesenswert?

Hallo,

im Datenblatt, ja lesen, steht die Erste Wandlung dauert länger und ist 
zu verwerfen.
Diese nennt man dann auch Dummy-Wandlung.

Die Anweisung macht das aber nicht, somit ist das Ergebnis ungültig.
1
 ADCSRA = (1<<ADEN) | (1<<ADSC);

Wie niederohmig ist deine Spannungsquelle ?
1
ADC Voltage Reference
2
The voltage reference for the ADC (VREF) indicates the conversion range
3
for the ADC. Single ended channels that exceed VREF will result in codes
4
close to 0x3FF. VREF can be selected as either VCC, or
5
internal 1.1V / 2.56V voltage reference, or external AREF pin.
6
The first ADC conversion result after switching voltage reference source
7
may be inaccurate, and the user isadvised to discard this result.

Dein code enthält diese Anweisung, die aber nicht zu dem Kommentar 
passend ist.
1
// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
2
  ADMUX = (1<<MUX1) | (1<<MUX0);
Gast #3470734
Lesenswert?

Ja, das mit dem Kommentar stimmt.
Hier war auch ursprünglich der Dummy Readout.
Da die Wandlung im TIMER1_OVF_vect periodisch geschieht, ist das auch 
nicht so schlimm, wenn die erste Mist ist.

ich habe auch mal mit MUX die Pins durchgewechselt - keine Besserung.

Die Spannungsquelle ist vom Konstanter, mit Spannungsteiler von 12V auf 
ca. 2-5V runtergeteilt.
Die 12V Spannung wird variiert, der µC läuft am 7805 mit 5V.
Gast #3470766
Lesenswert?

Hi

>Super Spess, Du hattest den richtigen "Richer".

Da braucht man keinen 'Richcher'. Beide Port-Register wurden auf 0xFF 
gesetzt. Da ist zwangsläufig auch der ADC-Eingang dabei.

Aber eine passende Prescaler Einstellung fehlt immer noch. Und den Code 
für den Timer0-Overflow kann sich der TO auch sparen, da der ADC im 
Auto-Trigger-Mode direkt durch den Timer-Overflow getriggert werden 
kann.

MfG Spess
Gast #3470788
Lesenswert?

Hier der Code mit ADC-Prescaler:

1
#include    "tacho.h"
2

3

4
//Funktionen
5
void init_Tacho(void);
6

7
//////////////////////////////////
8
/////////////////////////////////////////////////////////////////
9
//////////////////////////////////////////////////////////////////////////////////////////////////
10
int main (void)
11
{
12
  init_Tacho();
13

14
  sei();                        //Interrupts an
15

16
  //Hauptschleife
17
  while(1) 
18
  { 
19
    zeige_int(ADC_result);
20

21
  } //while(1)
22

23
}//main()
24

25
void init_Tacho(void)
26
{
27
  //Registerinitialisierung
28
  TCCR1B  = (1<<CS12) | (1<<CS11);            //Prescaler 1/32
29

30
  TIMSK  = (1<<TOIE1);           //Interrupt bei Overflow von Timer 1 (Blinker)
31

32
  DDRA   = 0b11101010;            //PA0 ADC0, PA2 Hall-Sensor INT1,
33
  DDRB   = 0b10100111;                      //PB3, PB4, PB6 sind Eingänge
34

35
  PORTA  = 0xfe;          
36
  PORTB  = 0xff;  
37
  
38
  main_state = state_U_Bat;  
39
        
40
  // Den ADC aktivieren und Teilungsfaktor auf 64 stellen
41
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
42
  ADMUX = (1<<MUX1) | (1<<MUX0);
43
}
44

45
ISR(TIMER1_OVF_vect)  //Taster, Blinker, Aktualisierung der Geschwindigkeit, ADC und Ausgabe --------- alle ca. 8ms
46
{
47
  i++;
48
  if(i == 80)  //bei 80*8ms=640ms und Prescaler=1/32 --> 0.64sec
49
  {
50
    BLINKER_PORT ^= (1<<BLINKER); //LED AUS
51

52
    i = 0;
53
  }
54

55
  if(i == 1)
56
    ADCSRA = (1<<ADEN) | (1<<ADSC);  // ADC anstossen
57
  if(i == 2)
58
    ADC_result = ADC;
59
}

Die Deklaration von ADC_result ist wie bei Uwe S.:

volatile uint16_t ADC_result=0;

Jetzt arbeitet der ADC aber ungenau.
Scheint als wäre hier ein Offset von ca. 100 im Bereich 0-1023.

Ich messe die Spannung auch mit dem Multimeter nach, was die Schaltung 
natürlich belastet (um ca. -10)
Gast #3470807
Lesenswert?

Hi

>Hier der Code mit ADC-Prescaler:

>  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

Das machst du aber mit

>    ADCSRA = (1<<ADEN) | (1<<ADSC);  // ADC anstossen

beim ersten Overflow wieder platt.

MfG Spess

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