PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AD wandler bei ATmega16



SFR
17.05.2005, 22:29
erstmal hallo alle zusammen,

also zunächsteinmal zu meiner person hab so die grundlagen von microcomputer einiger masen drauf hab auch schonmal was mit einem 8035 microcontroller was zu tun gehabt dennoch so finde ich bin ich noch ein anfänger in diesem gebiet.

auf jeden fall hab ich jetzt ein problem undzwar hab ich jetzt ein ATmega 16
controller vor mir liegen und würde gerne wissen wie ich den AD wandler nutzen kann der ja in diesem controller integriert ist.

ich möchte einfach ein ganz normales analoges signal in ein digitales umwandeln. jetzt die große frage wie und was muss ich machen damit das hinhaut. Ich hab mich schon mit dem Datenblatt ausernander gesetzt ist leider in Englisch and my english is not so good... =P~

ich kenn die tools (AVR STUDIO 4.09,code vision AVR)

aber weis nicht genau was ich da programmieren muss

kann mir vieleicht einer helfen?????????


vielen dank im vorraus

gruss jonny

recycle
18.05.2005, 01:41
Von der Beschaltung her musst du dem ATMega eine Referenzspannung geben und dann deine zu messende Spannung an einen der 8 AD-Pins von Port A anlegen.
Die Referenzspannung darf maximal so gross wie die Eingangspannung sein, die zu messende Spannung darf maximal so gross wie die Referenzspannung sein.

Die komplette Grundschaltung findest du z.B. hier:
http://www.kreatives-chaos.com/index.php?seite=avrgrund
Ist zwar ein ATMega8 aber die entsprechenden Pins aus dem Datenblatt des ATMega16 rauszusuchen sollte auch ohne englisch klappen ;-)


Zur Programmierung in AVR Studio kann ich dir nichts sagen.
Kannst es ja mal mit Bascom Basic versuchen. Ist wesentlich einfacher als Assembler und wie man einen AD-Eingang einliest ist in der Online-Hilfe anhand von Beispielcodes erklärt.

pebisoft
18.05.2005, 08:02
atmega16:

aref an 5volt /pin 32
gnd masse /pin 31
avcc an 5volt /pin 30

dann an adc0 bis adc7 auslesen bis max 5volt

mfg pebisoft

Björn
20.05.2005, 08:09
Hi,

ich möchte das ganze mit einem ATmega8 machen.
Hab das noch nicht ganz verstanden mit Aref an 5Volt - Woran muss der dann?

Bei der Gelegenheit, wie lese ich in Bascom sie Spannung aus?

Grüße,
Björn

bertl100
20.05.2005, 12:45
Probiers mal damit.
NUR FÜR SPANNUNGEN BIS 5V!!!!
Richtige Hardwarebeschaltung vorausgesetzt, ist ja schon beschrieben worden.
An den Pin AREF müssen von Außen 5V angelegt werden.
Der Prozessor teilt dann diese Spannung durch den Teiler den du einstellst oder Automatisch(Siehe mein Code.....Prescaler=AUTO)








dim Dauer as integer , Spannung as single

Config Adc = Single , Prescaler = Auto , Reference = Avcc


Start Adc


Dauer = Getadc(0) ' Messung an Kanal 0
Spannung = Dauer * 0.004883 ' Umrechnung 5V/1024* Dauer


Stop Adc


Print "Kanal " ; Cnt ; Spannung ; " V"

Björn
20.05.2005, 13:36
Jo geht danke!

Björn

pebisoft
20.05.2005, 17:02
hat mit dauer nichts zu tun, ist der 1024zigste-teil mal dem wert der am adc als zahlenwert ausgegeben wird.
mfg pebisoft

bertl100
20.05.2005, 18:48
Ist nur ein Ausschnitt aus meinem Projekt.
Ist schon klar

mfg Vader

SFR
23.05.2005, 11:19
atmega16:

aref an 5volt /pin 32
gnd masse /pin 31
avcc an 5volt /pin 30

dann an adc0 bis adc7 auslesen bis max 5volt

mfg pebisoft

hi und danke für die antwort schonmal im vorraus

hab die anweisungen befolgt d.h die pins so beschaltet wie angegeben.

wenn ich jetzt aber an dem adc0 bis adc7 die spannung gegen masse messe
bekomme ich einen messwert von ca. 300 mV kann das sein oder mache ich was falsch.?????????

programmiert hab ich zunächsteinmal garnichts nur den compiler mitgteilt
das ich den ad wandler nutzen möchte.

und in den ADCH und ADCL register schreibt er auch nichts rein.

](*,)

bertl100
23.05.2005, 11:55
Was meinst du mit spannung gegen Masse messen?
Leg einfach mal 2 V oder so an die adc-Eingänge.
Stell mal deinen Code hier rein und ich kann dir helfen.

SFR
23.05.2005, 16:49
#include <mega16.h>

#define ADC_VREF_TYPE 0x20
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned char adc_data;
// Read the 8 most significant bits
// of the AD conversion result

adc_data=ADCW;
// Place your code here

}

// Declare your global variables here


void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=Out Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=0 State0=T
PORTA=0x00;
DDRA=0x02;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
// ADC High Speed Mode: Off
// ADC Auto Trigger Source: None
// Only the 8 most significant bits of
// the AD conversion result are used
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x8D;
SFIOR&=0xEF;

// Global enable interrupts
#asm("sei")

while (1)
{
// Place your code here

};
}

PS : ich habe aber keinen code geschrieben den code den du hier siehst hat der (durch die voreinstellung von mir) compiler selber erzeugt

ich habe ausserdem an AREF und AVCC 5V anliegen sowie GND mit masse verbunden und an ADC0 (pin40) zusätzlich noch 2.5V angelegt. muss ich jetzt dazu den code noch ändern oder kann ich jetzt schon ein ergebnis erhalten??? wenn ja wie?

mfg

SFR ](*,)

bertl100
23.05.2005, 18:52
Mein Code ist in Bascom geschrieben.
Mit C kann ich auch nichts anfangen.

Vorteile von Basic bzw Bascom:

-High Levelbefehle wie "Start ADC" erleichtern das Programmieren in der Lernphase erheblich.

-Fast keine Register müssen in Bascom direkt gesetzt werden.

-Für kleine Versuche ist die Demoversion ausreichend und gut dokumentiert.

Um die Struktur der allgemeinen efizienten Programmierung zu erlernen
kann ich Bascom nur empfehlen. Habe auch damit angefangen und programmiere jetzt den MEga128 mit etwa 30Kb Code.
Außerdem finde ich auch, dass Bascom, sauber programmiert übersichtlicher ist als C.
Der einzigeGrund, warum ich C lernen würde ist die Tatsache, dass man in C komplexere Programme schreiben kann, die aber weit von denen eines Anfängers entfernt sind.

MFG

Vader

SFR
25.05.2005, 09:04
hier mein code in bascom:


'--------------------------------------------------------------------
' ADC.BAS
' demonstration of GETADC() function for 8535 micro
' Getadc() will also work for other AVR chips that have an ADC converter
'--------------------------------------------------------------------
$regfile = "m16def.dat"

'configure single mode and auto prescaler setting
'The single mode must be used with the GETADC() function

'The prescaler divides the internal clock by 2,4,8,15,32,64 or 128
'Because the ADC needs a clock from 50-200 KHz
'The AUTO feature, will select the highest clockrate possible
Config Adc = Single , Prescaler = Auto
'Now give power to the chip
Start Adc

'With STOP ADC, you can remove the power from the chip
'Stop Adc

Dim W As Word , Channel As Byte

Channel = 0
'now read A/D value from channel 0
Do
W = Getadc(channel)
Print "Channel " ; Channel ; " value " ; W
Incr Channel
If Channel > 7 Then Channel = 0
Loop
End

'The new M163 has options for the reference voltage
'For this chip you can use the additional param :
'Config Adc = Single , Prescaler = Auto, Reference = Internal
'The reference param may be :
'OFF : AREF, internal reference turned off
'AVCC : AVCC, with external capacitor at AREF pin
'INTERNAL : Internal 2.56 voltage reference with external capacitor ar AREF pin

'Using the additional param on chip that do not have the internal reference will have no effect.

wieso schreibt er nichts in die register ADCH und ADCL hinein ?

mfg

sfr

bertl100
25.05.2005, 16:21
Du darfst den Code nicht irgendwie einfach kopieren.
die baudrate hast vergessen und keine geschwindigkeit deklariert=$crystal
Hier der korregierte Code.
Probier aus.
Bei deinem und bei meinem Code kommt vorerst nur der Binärwert raus, da die Umrechnung in Volt noch fehlt.
Das können Werte von 0 bis 1024 sein.




$regfile = "m16def.dat"
$crystal = 3000000
$baud = 9600


Config Adc = Single , Prescaler = Auto


Start Adc

'

Dim W As Word , Channel As Byte

Channel = 0

Do
W = Getadc(channel)
Print "Channel " ; Channel ; " Wert= " ; W
Incr Channel
If Channel > 7 Then Channel = 0
Loop
End

weiterfahrn
25.05.2005, 22:41
"...die zu messende Spannung darf maximal so gross wie die Referenzspannung sein."

sonst passiert was?

dankbar für antworten

Alter Knacker
25.05.2005, 23:17
erm......
du legst maximal +5v an und dann kannst du per spannungsteiler messen.
leg mehr an und der µC raucht dir ab ;-)
mfg knacki

//edit:

poti, links +5v, rechts gnd, mitte an den adc-port, dann kannst du werte auslesen.
ist das verständlicher für den anfang?

weiterfahrn
26.05.2005, 09:10
das heißt wenn ich die interne 2,56V Referenz benutze, darf am pin nicht mehr als eben diese 2,56V anliegen, richtig?
wenn dort mal eben 5V anliegen war es die letzte messung?

wär noch schön wenn ich wüßte unter welchem punkt im datenblatt dies beschrieben ist, bisher nix gefunden

p.s.: folgendes Szenario liegt vor: Spannungsteiler, wenn ich aber den GND-seitigen widerstand entferne(aufsteckbarer Tempsensor), dann hab ich auf grund des hohen eingangswiderstandes des adc knapp 5V anliegen

weiterfahrn
26.05.2005, 09:12
ok, jzt hab ichs gefunden