Forum: Mikrocontroller und Digitale Elektronik ADC bei Attiny25 geht nicht


von Halgn H. (Gast)


Lesenswert?

Hallo,

mein Problem ist das ich dauernt 1024 hab... das stimmt nicht habe 
eigentlich 341(1024/3V*1V).

Hab so gefühl das ich ADC nicht verstanden hab;

VCC sind 3V
PB2 mein Sensor 0,5-2,8V

Was es macht:
Stoppt die DC-Motoren

Was es nicht macht:
Wenn z.B. 1V an PB2 anliegen das die Motoren angehen

Der code hab ich teilweise koppiert und abgeändert. Ich habe es auch 
versucht selbst zu schreiben aber immer das gleiche ergebnis.

Der Teiler ist auf 8 und 8mhz läuft der Attiny25(intern).
1
/*
2
 * ATtiny25
3
 * File: main.c
4
 */
5
#define F_CPU 8000000UL
6
7
#include <avr/io.h>
8
#include <stdlib.h>
9
#include <inttypes.h>
10
#include <util/delay.h>
11
12
13
uint16_t adc_value;            //Variable used to store the value read from the ADC
14
void adc_init(void);            //Function to initialize/configure the ADC
15
uint16_t read_adc(uint8_t channel);    //Function to read an arbitrary analogic channel/pin
16
17
18
void Motor_Stop()
19
{
20
  PORTB &= ~(1 << PB0);
21
  PORTB &= ~(1 << PB1);
22
  PORTB &= ~(1 << PB3);
23
  PORTB &= ~(1 << PB4);
24
}
25
26
void Motor_Forward()
27
{
28
  /* Vorwärts */
29
  PORTB ^= 1<<PB3;
30
  PORTB &= ~(1 << PB4);
31
32
33
  PORTB ^= 1<<PB0;
34
  PORTB &= ~(1 << PB1);
35
  return;
36
}
37
38
void Motor_Backward()
39
{
40
  /* Rückwärts*/
41
  PORTB &= ~(1 << PB3);
42
  PORTB ^= 1<<PB4;
43
44
  PORTB &= ~(1 << PB0);
45
  PORTB ^= 1<<PB1;
46
  return;
47
}
48
49
50
int main(void)
51
{
52
  uint16_t result;
53
54
    // Set up Ports to output
55
  DDRB = (1 << DDB0) | (1 << DDB1) | (1 << DDB3) | (1 << DDB4);
56
57
  _delay_ms (1000);
58
59
    // Set up Port B data to be all low
60
   // PORTB = 0; 
61
62
  while (1)
63
  {
64
    adc_value = read_adc(1);
65
66
    if (adc_value > 1023)
67
    {
68
      Motor_Stop();
69
    }
70
    else
71
    {
72
      Motor_Forward();
73
    }
74
    _delay_ms (250);
75
  }
76
77
  return 0;
78
}
79
80
void adc_init(void)
81
{
82
83
 ADCSRA |= ((0<<ADPS2)|(1<<ADPS1)|(1<<ADPS1));    //8Mhz/8 = 1Mhz the ADC reference clock
84
 ADMUX |= (1<<REFS0);                //Voltage reference from Avcc -> VCC (3v)
85
 ADCSRA |= (1<<ADEN);                //Turn on ADC
86
 ADCSRA |= (1<<ADSC);                //Do an initial conversion because this one is the slowest and to ensure that everything is up and running
87
}
88
89
uint16_t read_adc(uint8_t channel){
90
 ADMUX &= 0xF0;                    //Clear the older channel that was read
91
 ADMUX |= channel;                //Defines the new ADC channel to be read
92
 ADCSRA |= (1<<ADSC);                //Starts a new conversion
93
 while(ADCSRA & (1<<ADSC));            //Wait until the conversion is done
94
 return ADCW;                    //Returns the ADC value of the chosen channel
95
}

: Verschoben durch Moderator
von Halgn H. (Gast)


Lesenswert?

Boar... kann es nicht verschieben es gehört nicht zu "GCC" kann ein 
Admin bitte verschieben?

von Walter S. (avatar)


Lesenswert?

Alexander Herberg schrieb:
> if (adc_value > 1023)

wird nie erfüllt sein !

von Walter S. (avatar)


Lesenswert?

und du solltest adcinit irgendwo aufrufen ...

von DB (Gast)


Lesenswert?

ADCSRA |= ((0<<ADPS2)|(1<<ADPS1)|(1<<ADPS1));
Würde einem Prescaler von 4 entsprechen und nicht 8 (zwei mal ADPS1).
Besser wäre sowieso ADPS2 und ADPS1, ein Prescaler von 64.
8 Mhz / 64 = 125 khZ.

ADCW ist für den Attiny25 wohl auch nicht vorgesehen, ADCH und ADCL 
sollten das Ergebniss beinhalten, weiß aber nicht ob es auch so 
funktioniert.

Dann wäre noch ein Schaltplan interessant.
ADMUX |= (1<<REFS0); //Voltage reference from Avcc -> VCC (3v)

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.