Forum: Mikrocontroller und Digitale Elektronik Kanalumschaltung ADC ATMEGA644


von Marco G. (grmg2010)


Lesenswert?

Moin,

nachdem mein ADC nun läuft würde ich gerne eine Kanalumschaltung per 
Knopfdruck einbauen. Mein Problem ist allerdings, dass die 
Kanalumschaltung nicht funktioniert. Hier mal die Initialisierung des 
ADC und mein Versuch den Kanal zu wechsel:
1
#define F_CPU 8000000UL
2
  #define Vref 4.94
3
  
4
  
5
  #include <avr/io.h>                  //einbinden der Bibliothek 'io.h'
6
  #include <util/delay.h>                //einbinden der Bibliothek 'delay.h'
7
  #include <avr/interrupt.h>
8
  #include <stdlib.h>
9
  #include "avr.h"
10
  #include "SPI.h"
11
  #include "UART.h"
12
  
13
  
14
  void ADC_init(void)
15
  {
16
    uint16_t first_result = 0;
17
    
18
    DIDR0 = (1<<ADC0D);
19
    
20
    ADMUX = (1<<REFS0); // | (1<<REFS1); //Einschalten der Referenzspannung: Vref = AVCC
21
    ADMUX |=(MUX0);
22
    
23
    ADCSRA = (1<<ADEN) | (1<<ADIE); // ADC aktivieren und Interrupt einschalten
24
    ADCSRA |= ((ADPS0) | (1<<ADPS1) | (1<<ADPS2)); //Prescaler 128
25
    
26
    
27
    _delay_ms(1);
28
    
29
    sei();
30
    
31
    ADCSRA |= (1<<ADSC);
32
    while (ADCSRA & (1<<ADSC))
33
    {
34
      
35
    }
36
    
37
    first_result = (ADCL + (ADCH<<8));
38
    
39
  }
40
41
  double calculate_adc(uint16_t value)
42
  {
43
    double result = 0.0;
44
    
45
    result = (value / 1024.0) * Vref;
46
    return result;
47
    
48
  }
49
50
  void start_converting(void)
51
  {
52
    ADCSRA |= (1<<ADSC);
53
    _delay_ms(1);
54
  }
55
  
56
  void select_adc(void)
57
  {
58
    int adc_number, adc_counter;
59
    
60
    if (!(PINC &(1<<PC0)))
61
    {
62
      adc_counter = 0;
63
      ADCSRA &= ~(1<<ADEN);
64
      ADMUX &= ~0x03; 
65
      ADMUX =(1<<MUX0);
66
      _delay_ms(1);
67
      ADCSRA |= (1<<ADEN);
68
      start_converting();
69
    }
70
    if (!(PINC &(1<<PC1)))
71
    {
72
      adc_counter = 1;
73
      ADCSRA &= ~(1<<ADEN);
74
      ADMUX &= ~0x03;
75
      ADMUX |=(1<<MUX1);
76
      _delay_ms(1);
77
      ADCSRA |= (1<<ADEN);
78
      start_converting();
79
    }
80
    
81
    if (adc_counter == 0)
82
    {
83
      adc_number = 0;
84
    }
85
    
86
    if (adc_counter == 1)
87
    {
88
      adc_number = 1;
89
    }
90
    
91
    if (adc_number == 0)
92
    {
93
      PORTD |=(1<<PD7);
94
      uart_putc(0x1b);
95
      uart_puts("[04;2H");
96
      Send_UART_Char("Aktiver ADC: ADC0");
97
98
    }
99
    
100
    if (adc_number == 1)
101
    {
102
      PORTD &= ~(1<<PD7);
103
      uart_putc(0x1b);
104
      uart_puts("[04;2H");
105
      Send_UART_Char("Aktiver ADC: ADC1");
106
  
107
    }
108
    
109
    
110
  }

von spess53 (Gast)


Lesenswert?

Hi

Zwischen welchen Kanälen willst du eigentlich umschalten?

MfG Spess

von S. Landolt (Gast)


Lesenswert?

Fehlt nicht, um das
> if (!(PINC &(1<<PC0)))
> if (!(PINC &(1<<PC1)))
beurteilen zu können, noch ein Stück Programm und/oder eine 
Schaltungsbeschreibung?

von Marco G. (grmg2010)


Lesenswert?

Testweise wollte ich zwischen Kanal 0 und 1 umschalten, später wollte 
ich alle Kanäle nutzen.

S. Landolt schrieb:
> if (!(PINC &(1<<PC0)))

Nicht unbedingt, das sollte nur verdeutlichen, dass ich z.B. durch 
Taster oder Schalter den Kanal wählen. Das ist aber erstmal zweitrangig, 
wie ich die Umschaltung realisiere, wichtig ist für mich im ersten 
Schritt, die Umschaltung des ADCs generell durchführen zu können.

von spess53 (Gast)


Lesenswert?

Hi

>Testweise wollte ich zwischen Kanal 0 und 1 umschalten, später wollte
>ich alle Kanäle nutzen.

ADMUX =(1<<MUX0);           Schaltet Kanal 1 ein
ADMUX |=(1<<MUX1);          Schaltet Kanal 2 ein

Außerdem solltest du dich mal über Tastenentprellung schlau machen.

MfG Spess

von Marco G. (grmg2010)


Lesenswert?

Das hatte ich bereits probiert, führte Leider nicht zum Erfolg.

Ich möchte aber auch von 1 -> 0, dann geht es auf diesem Wege ja nicht.

Die Taster sind nur eine erste Lösung zum Teten. Ich möchte das final 
über die UART Schnittstelle (Terminal) steuern können.

von spess53 (Gast)


Lesenswert?

Hi

>Das hatte ich bereits probiert, führte Leider nicht zum Erfolg.
>Ich möchte aber auch von 1 -> 0, dann geht es auf diesem Wege ja nicht.

Und was macht

ADMUX &= ~0x03;

wohl?

Aber um das komplette ADMUX auf 0 zu setzen sollte es besser

ADMUX &= ~0x0F;

heißen.

MfG Spess

von MWS (Gast)


Lesenswert?

Marco G. schrieb:
> S. Landolt schrieb:
>> if (!(PINC &(1<<PC0)))
>
> Das ist aber erstmal zweitrangig,

Nicht wirklich, wenn der Code und damit das Ergebnis unsinnig ist. 
Überleg', wann das wahr wird.

von Marco G. (grmg2010)


Lesenswert?

spess53 schrieb:
> ADMUX &= ~0x03;

Genau das hatte ich auch gedacht, im ersten Moment funktioniert das 
auch, wenn ich dann jedoch auf Kanal 1 umschalte, auf dem 0,825V 
anliegen wird irgendeine Spannung gemessen, aber nicht die anliegende. 
Wenn ich wieder auf Kanal 0 umschalte, an dem 3.3V anliegen messe ich 
nur 2,9V. Vorher waren es 3.22V.

@MWS
Die Abfrage funktioniert, zum Testen habe ich eine LED angebracht, die 
eingeschaltet wird, wenn die Funktion betreten wird. Da sie leuchtet, 
wird der Abschnitt auch betreten.

: Bearbeitet durch User
von MWS (Gast)


Lesenswert?

Marco G. schrieb:
> Die Abfrage funktioniert, zum Testen habe ich eine LED angebracht, die
> eingeschaltet wird, wenn die Funktion betreten wird. Da sie leuchtet,
> wird der Abschnitt auch betreten.

Funktion oder If-Block?
Es ist dann Absicht, dass der If-Block nicht ausgeführt wird, wenn der 
Pin High ist?

von Marco G. (grmg2010)


Lesenswert?

Ich meinte den Block. Ja, wenn ich den Pin extern auf low ziehe, soll 
die enthaltenen Anweisungen ausgeführt werden.

von BirgerT (Gast)


Lesenswert?

Wenn Du auch Deine main() zeigen würdest..?
Und was ist mit der ISR für den ADC (warum ADIEN Bit gesetzt)?
Bei 8MHz wäre ein Prescaler von 64 besser als 128 (ADPS0 nicht setzen).

Soll die Messung nur solange erfolgen, wie der Taster gedrückt ist 
(Taster losgelassen, dann auch keine Messung)?

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.