Guten Morgen,
also ich habe einen Atmega88, dazu habe ich auch ein Buch in dem steht
wie man den ADC-Konverter einstellt u.a wie man die Register für die
Kanäle 0-5 einstellt.
allerdings ist hier nur ein Beispiel beschrieben wie man mit einem Kanal
einen Wert einliest. Eigentlich genauso wie im AVR-Tutorial hier im
Forum.
ich möchte aber gerne zwei Kanäle nutzen nämlich Kanal 4 und 5. Wie man
das nutzt/konfiguriert finde ich im netz nichts, entweder suche ich
falsch oder es geht nicht.
Um ADC 4 und 5 zu nutzen muss ich das im AMUX Register frei schalten
ich hatte jetzt keine andere Idee, so wie unten im Code das mal zu
versuchen, das geht natürlich nicht.
nach was muss ich da suchen um das zu realisieren, oder könnte es mir
bitte jemand zeigen ?
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
#define FOSC 16000000 // Set clock Speed in Hz
5
#define BAUD 9600 // Set baud rate
6
#define UBRR_Value FOSC/16/BAUD-1 // Set baud rate value in baud rate register
7
8
voidUSART_Init(uint16_tubrr)
9
{
10
UBRR0H=(uint8_t)(ubrr>>8);// Set baud rate in high- and low-register
11
UBRR0L=(uint8_t)ubrr;// Set low-register always after high-register
12
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);// Set frame format: 8data, 1stop bit
13
UCSR0B=(1<<RXEN0)|(1<<TXEN0);// Enable receiver and transmitter
14
}
15
16
voidUSART_Transmit(uint8_tdata)
17
{
18
while(!(UCSR0A&(1<<UDRE0)));// Wait for empty transmit buffer
19
UDR0=data;// Put data into buffer, sends the data
20
}
21
22
uint8_tUSART_Receive(void)
23
{
24
while(!(UCSR0A&(1<<RXC0)));// Wait for data to be received
25
returnUDR0;// Get and return received data from buffer
Michael H. schrieb:> Um ADC 4 und 5 zu nutzen muss ich das im AMUX Register frei schalten> ADMUX |= (1<<MUX2); // ADC-Kanal 4 einstellen> ADMUX |= (1<<MUX2)|(1<<MUX0); // ADC-Kanal 5 einstellen>> ich hatte jetzt keine andere Idee, so wie unten im Code das mal zu> versuchen, das geht natürlich nicht.
Das geht schon, aber nicht auf ein Mal.
Du musst zunächst Kanal 4 einstellen und dann den ADC starten und das
Ergebnis holen.
Dann musst du mit der zweiten Zeile Kanal 5 einstellen und wieder den
ADC starten und das zweite Ergebnis ermitteln.
Also nacheinander, nicht gleichzeitig!
@Hildek
also Danke schon einmal für die Antwort, da es nicht so ganz bei
funkioniert. Ich bekomme im H-term nur einen wert angezeit der von dem
anderen etwas beeinflusst wird, wenn ich am Poti des anderen Kanal
drehe. Muss ich hier noch bei den Registern vor der while schleife dann
was ausklammern ?
aktuell sieht es jetzt so aus .:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
#define FOSC 16000000 // Set clock Speed in Hz
5
#define BAUD 9600 // Set baud rate
6
#define UBRR_Value FOSC/16/BAUD-1 // Set baud rate value in baud rate register
7
8
voidUSART_Init(uint16_tubrr)
9
{
10
UBRR0H=(uint8_t)(ubrr>>8);// Set baud rate in high- and low-register
11
UBRR0L=(uint8_t)ubrr;// Set low-register always after high-register
12
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);// Set frame format: 8data, 1stop bit
13
UCSR0B=(1<<RXEN0)|(1<<TXEN0);// Enable receiver and transmitter
14
}
15
16
voidUSART_Transmit(uint8_tdata)
17
{
18
while(!(UCSR0A&(1<<UDRE0)));// Wait for empty transmit buffer
19
UDR0=data;// Put data into buffer, sends the data
20
}
21
22
uint8_tUSART_Receive(void)
23
{
24
while(!(UCSR0A&(1<<RXC0)));// Wait for data to be received
25
returnUDR0;// Get and return received data from buffer
DIDR0|=(1<<ADC5D);// Dig. Input Kanal ADC5 deaktivieren (spart Strom)
52
53
//*** Dummy Readout ***
54
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
55
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
56
x=ADC;// Das Ergebnis der 1.Wandlung in x speichern
57
58
59
while(1)
60
{// Ausgabe ADC5
61
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
62
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
63
ergebnis=ADCH;// Inhalt von ADCH in ergebnis speichern
64
USART_Transmit(ergebnis);
65
_delay_ms(1000);
66
67
// Ausgabe ADC4
68
ADMUX&=~(1<<MUX0);// Kanal 4 (nur MUX2=1)
69
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
70
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
71
ergebnis1=ADCH;// Inhalt von ADCH in ergebnis speichern
72
USART_Transmit(ergebnis1);
73
_delay_ms(1000);
74
75
}
76
}
Simplex schrieb im Beitrag #5328761:
> Analo?> Haha, is fürn Arsch?
Was soll jetzt das heissen, ich bin gerade am testen, und so richtig
funktioniert es auch nicht, ich bekomme im H-term nur einen wert
angezeit der von dem anderen etwas beeinflusst wird, wenn ich am Poti
des anderen Kanal drehe
Michael H. schrieb:> da es nicht so ganz bei funkioniert.
Du hast noch immer vergessen, am Anfang der while-Schleife für Kanal 5
den Mux wieder auf 5 zu stellen. da, wo du "// Ausgabe ADC5" kommentiert
hast.
Die hier:
ADMUX |= (1<<MUX2)|(1<<MUX0); // Kanal 5
Ich muss aber zugeben, dass ich nicht alle Settings verifiziert habe,
weil die fehlende Anpassung der Multiplexers an den gewünschten Kanal
für mich Grund genug war für das Fehlverhalten.
>> Ich bekomme im H-term nur einen wert angezeit der von dem> anderen etwas beeinflusst wird> Du hast noch immer vergessen, am Anfang der while-Schleife> für Kanal 5 den Mux wieder auf 5 zu stellen.
Falls dein problem nach der Korrektur immer noch besteht, kann es daran
liegen, dass deine Signalquelle zu hochohmig ist (>10kΩ). Durch einen
zusätzlichen Dummy Read kann man das häufig umgehen - falls du die Zeit
dazu übrig hast.
1
int8_tread_adc(uint8_tchannel)
2
{
3
ADMUX=(ADMUX&0xF0)+channel;// Kanal wählen
4
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
5
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
6
ADCSRA|=(1<<ADSC);// Start nochmal ADC-Wandlung
7
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
@Hildek und Stefan US schon einmal herzlichen Dank
Jetzt kann ich es mir zumindest vorstellen wie es geht. Ich habe jetzt
zwei Potis mit jeweil 10K dran.
Es scheint zu funtionieren :-)
das heisst ich müsste Beim initialisieren des ADC"s vor der
While-schleife
die Registerbits für die Kanalwahl gar nicht setzen?
und jetzt genau so Habe ich ihn auf den Controller.:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
#define FOSC 16000000 // Set clock Speed in Hz
5
#define BAUD 9600 // Set baud rate
6
#define UBRR_Value FOSC/16/BAUD-1 // Set baud rate value in baud rate register
7
8
voidUSART_Init(uint16_tubrr)
9
{
10
UBRR0H=(uint8_t)(ubrr>>8);// Set baud rate in high- and low-register
11
UBRR0L=(uint8_t)ubrr;// Set low-register always after high-register
12
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);// Set frame format: 8data, 1stop bit
13
UCSR0B=(1<<RXEN0)|(1<<TXEN0);// Enable receiver and transmitter
14
}
15
16
voidUSART_Transmit(uint8_tdata)
17
{
18
while(!(UCSR0A&(1<<UDRE0)));// Wait for empty transmit buffer
19
UDR0=data;// Put data into buffer, sends the data
20
}
21
22
uint8_tUSART_Receive(void)
23
{
24
while(!(UCSR0A&(1<<RXC0)));// Wait for data to be received
25
returnUDR0;// Get and return received data from buffer
> das heisst ich müsste Beim initialisieren des ADC"s vor der> While-schleife> die Registerbits für die Kanalwahl gar nicht setzen?
Richtig, doppelt gemoppelt ist nicht besser als einfach.
>> das heisst ich müsste Beim initialisieren des ADC"s vor der>> While-schleife>> die Registerbits für die Kanalwahl gar nicht setzen?
Häufig hat so ein μC n Eingänge für Analogsignale, einen
Kanalwahlschalter n:1 (den MUX) aber nur einen ADC.
Nutzt man nur einen Kanal, reicht die Initialisierung wie deinem ersten
Beispiel, also einmal den Kanal anwählen und dann immer wieder die
Wandlung anstoßen.
Willst du aber mehrere Kanäle abfragen, dann musst du zuerst auf den
gewünschten Kanal umschalten und dann wandeln.
Eine Korrektur:
> int8_t read_adc(uint8_t channel)
Ich glaube, der Rückgabewert sollte uint8_t sein, auch wenn man den
Unterschied auf der seriellen Schnittstelle nicht bemerkt.
Guten Morgen,
jetzt möchte ich bei einem Attiny85 den Analogwert von ADC1-Kanal1 in
eine Variable übergeben. Jetzt kann ich mir das aber nicht auf dem
Terminal seriell anzeigen lassen, weil der ja keine Usart Schnittstelle
hat.Jetzt bekomme ich das einfach nicht hin.
könnte mir hier Bitte noch einmal jemand sagen was ich hier falsch
mache. Oder wie ich mir den Variablen Inhalt ansehen kann.
1
/*
2
* ATTINY_85.c
3
*
4
* Created: 03.03.2018 15:59:47
5
* Author : USER
6
*/
7
#define F_CPU 1000000UL
8
#include<avr/io.h>
9
#include<util/delay.h>
10
11
12
uint16_tt=0;// Variable für Delay ()
13
14
15
voidMyDelay(uint16_tt)
16
{
17
while(t>0)
18
{
19
_delay_ms(1);
20
t--;
21
}
22
return;
23
}
24
25
int8_tread_adc(uint8_tchannel)
26
{
27
ADMUX=(ADMUX&0xF0)+channel;// Kanal wählen
28
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
29
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
30
ADCSRA|=(1<<ADSC);// Start nochmal ADC-Wandlung
31
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
32
returnADCH;// Inhalt von ADCH lesen
33
}
34
35
intmain(void)
36
{
37
DDRB&=~(1<<PB2);// auf Eingang Bewegungsmelder
38
DDRB=(1<<PB3);// auf Ausgang Magnetventil
39
40
uint16_tx;
41
42
//*** Init ADC ***
43
ADCSRA|=(1<<ADEN);// ADC aktivieren
44
ADCSRA|=(1<<ADPS0)|(1<<ADPS1);// Vorteiler auf 8
45
ADMUX|=(1<<REFS0);// Uref = 5V
46
ADMUX|=(1<<ADLAR);// Ausgabe linksbündig
47
48
49
//*** Dummy Readout ***
50
ADCSRA|=(1<<ADSC);// Start ADC-Wandlung
51
while(ADCSRA&(1<<ADSC));// Auf Abschluss der Konvertierung warten
52
x=ADC;// Das Ergebnis der 1.Wandlung in x speichern
Danke, das ist sehr interessant, da muss ich mich mal in Ruhe umsehen.
und noch einmal zu obigen Code,da müsste doch jetzt in t 255 oder 1023
drin stehen oder ? wenn nicht wie kann ich das ändern ?