PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega8 ADC unter Bascom



didi0108
13.04.2005, 18:41
Hallo zusammen,

ich habe ien kleines Problem und hoffe jemand kann mir helfen.
Also ich versuche mit einem ATmega8 am Port PC0(ADC0) eine Spannung eizulesen und den Wert auszugeben.
Die Konfiguration kann man unter Bascom sowohl in Maschinencode als auch mit Bascom Hi-Level-Statements ausführen. Angeschlossen wird ein Poti.
Nun mein Problem:
Konfiguration im Maschinecode funktioniert bestens, sogar als Kurvenausgabe. Kommentiere ich Maschinecode aus, und verwende Bascom, ist der ausgegebene Wert IMMER 1023! Egal vohin ich das Poti stelle.



'ACC + Poti: A/D-Konverter, einfaches Beispiel
'Hardware: Poti1 an PC0/ADC0
' MAX232 an PD0/PD1, Nullmodemkabel zum PC
'----------------------------------------------------------
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 3686400 'Quarz: 3,6864 MHz
$baud = 9600 'Baudrate zum PC: 9600 Baud
'----------------------------------------------------------
Dim H As Word
Dim L As Byte

Ddrc = &B00000000 'PC7...PC0=0: PortC-Pins auf Eingang

'----------------------------------------------------------
'Register direkt gesetzt, läuft

'Admux = &B01100000 'Bits7+6=01: Aref ist intern verbunden
'Bit5=1: LeftAdjust, nur 8 Bit in ADCH
'Bits3...0=0000: Pin ADC0 wählen

'Adcsr = &B11100111 'Bit7=1:AdcOn,Bit6=1:Start,Bit5=1:Frei
'Bits2+1+0=111: AdcClock=AvrClock/128
'----------------------------------------------------------
'BASCOM Statements liefern immer nur den Wert 1023
Config Adc = Single , Prescaler = 128
Enable Interrupts
Start Adc
'----------------------------------------------------------
Do 'Hauptschleife
'udr = Adch 'Aktuelles AD-HiByte in die UART
H = Getadc(0) 'aktueelen Wert auslesen
Print H 'Print h
Waitms 200 'Datenmenge etwas begrenzen
Loop




Was mache ich Falsch????

mfg.

Dietmar

(Entschuldigt bitte die Form, aber ich weiß nicht wie ich den Code richtig reinbekomme.)

RCO
13.04.2005, 19:01
Den Code kriegst du mit [ code ] ... [/ code ]
ohne die Leerzeichen rein.
schreib mal noch "Enable Adc" rein.
und noch
Config Adc = Single , Prescaler = Auto , Reference = Avcc

RCO
13.04.2005, 19:05
Dieser Code sollte es tun:

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

'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.

didi0108
13.04.2005, 19:08
Hallo Moritz,

danke für Deine Anwort.
Dies ergibt das gleiche Erbenis: 1023.

mfg.

Dietmar

didi0108
13.04.2005, 19:14
@ Moritz
Danke für Dein Beispiel.
Das ist der Code aus der Bascom-Hilfe. Den habe ich auch schon ausprobiert. Der tuts auch nicht. Immer 1023, egal wo das Poti steht.

mfg.

Dietmar

RCO
13.04.2005, 23:32
Das verstehe ich dann leider auch nicht, hab leider gerade nix zum testen da...

Hier nochmla ein anderer Code:


$regfile = "m8def.dat"
$crystal = 8000000
$baud = 2400

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Admux = &B01100100
On Adc Onadc
Config Pind.3 = Output
Config Pinc.4 = Input
Config Pinc.0 = Input
Config Pinc.1 = Input
Portc.4 = 1
Portc.0 = 1
Portc.1 = 1
Portd.3 = 1
Dim Switch As Word
Dim Switsch As Word
Start Adc
Enable Interrupts
Enable Adc


Do
Switch = Getadc(4)
Print Switch
Switsch = Getadc(0)
Print Switsch

Waitms 100
Loop
End

Onadc:
If Getadc(4) < 1023 Then
Print "i"
End If
Print Getadc(4)
If Getadc(0) < 1023 Then
Print "i2"
End If
Print Getadc(0)
Return


Müsstest alles was du nicht brauchst streichen, der Code müsste aber laufen, meine ihn schon benutzt zu haben.

pebisoft
14.04.2005, 07:54
hallo, ich gebe es auf einem lcd aus. da ich 5 volt referenz angelegt habe komme ich beim sharpsensor nur bis 512, der liefert nur 2,5v max steuerspannung.
ich könnte natürlich einen widerstand bei der referenz dazuschalten, damit ich bis 1024 komme, 512 reicht mir aus.

$regfile = "m16def.dat"
$crystal = 8000000

Enable Interrupts

Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , Rs = Portc.5 , E = Portc.4
Config Lcd = 16 * 2

Config Adc = Single , Prescaler = Auto

Dim Adc_vh As Byte
Dim W_vh As Word

Adc_vh = 0 ' pin a0

Start Adc

Do

Cls
Locate 1 , 1
W_vh = Getadc(adc_vh)
Lcd "wert:" ; W_vh
Waitms 200

Loop

mfg pebisoft

didi0108
14.04.2005, 11:53
Hallo zusammen,

ersteinmal Danke für euere Unterstützung.
Manchmal liegen die Probleme auch an der Hardware.
Ich habe soeben ein neues Modul Mega8 bekommen, und siehe es funzt.
Damit ist anzunehmen, dass das alte Modul evtl. einen Schuss hat.

Jetzt laufen auch euere Programme.
Nochmals Danke. =D>

mfg.

Dietmar

pebisoft
14.04.2005, 18:01
hallo, du hast deine programme auch ein bisschen zu gross angesetzt.
denk daran, basic ist einfach strukturiert. wenn du mit deinen ansatz programmieren möchtest, probier das einmal winavr-c. geht wunderbar.
ich glaube mit winavr bist du besser dran.
mfg pebisoft

14.04.2005, 18:11
@pebisoft

Danke für Deinen Hinweis.
Aber ich glaube, dass es sich in Basic auch recht gut programmieren läßt. Natürlich kann man statt der Bascom-HiLevel-Statements auch direkt Maschinencode schreiben, wie ich es ja auch getan habe.
Aber Bascom ist ein Basicdialekt, den ich verstehe, C müßte ich mir erst mühsam aneigen. Selbst auf die Gefahr hin, dass MEIN Basiccode etwas zu groß wird. Ich kann damit leben.
Nochmals Danke für den Hinweis. :cheesy:

mfg
Dietmar

Marko1704
15.04.2005, 20:18
Hatt ich auch, die 1023.

Habs mit

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

hinbekommen

Viktor
13.03.2007, 22:54
Hallo!
Ich hab auch das gleiche Problem mit dem ATtiny26.

Ich möchte zwei Spannungen am Pin PA0(ADC0) und PA1(ADC1) messen, aber es klappt nicht. Während ich am Pin PA1 eine Spanunng messen kann, die auch mit dem gemessenem und ausgerehnetem Wert übereinstimmt, stimmt dagegen der Wert am PA0 überhaupt nicht.
Ich kann zwar die gemessenen Werte nicht direkt anzeigen, aber ich kann eine Schaltschwelle einstellen und eine LED, beim erreichen dises Wertes ein- und ausschalten.
An den PA2 bis PA4 sind LEDs an +5V (natürlich mit Vorwiderstand :) ) angeschlossen so, dass die Ausgänge gegen GND schalten.

Als program habe ich den angepassten code von BASCOM verwendet.

patti16
14.03.2007, 13:14
poste bitte mal deine Code

Viktor
14.03.2007, 16:54
Hall!

Hier ist der code.
Könnt ihr mir sage wie das mit dem ADC Interrupt geht?

ich meine so ähnlich wie "On Int0 tue_irgendwas", denn in der neuen BASCOM Hilfe habe ich leider nichts gefunden.

Grüße Viktor


'################################################# ##############################
'#####
'##### Project: 6A-Netzteil
'##### Version: v1.0
'##### Date: 10.03.2007
'##### Projectname: 6A_Netzteil_v1.0.bas
'##### Developer: Krieger, Viktor
'#####
'################################################# ##############################

'########[ Description ]################################################## #########

'####PORT A####
' PA0 = [ADC CH0] CONTROL_SPL ( voltage control 12V )
' PA1 = [ADC CH1] PWR_SPL (voltage control 33,6V )
' PA2 = [OUT] LED_ERR (Error LED) signals an error of the power-supply
' PA3 = [OUT] LED_SDWN (Shut Down LED) signals powerdown - state
' PA4 = [OUT] LED_RDY (Ready LED) signals that all ok
' PA5 = [OUT] NC this pin is not connected
' PA6 = [OUT] REL_POWON
' PA7 = [OUT] REL_PROTECT

'####PORT B####
'
' PB0 = [DEF] MOSI *
' PB1 = [DEF] MISO *
' PB2 = [DEF] SCK *
' PB3 = [IN] JP1 jumper 1
' PB4 = [IN] JP2 jumper 2
' PB5 = [OUT] ERROR signals other devices an error (no error = 1/ on error = 0)
' PB6 = [IN] SDWN input for standby sequence (active 0)
' PB7 = [DEF] RESET *
'
' * Default configuration of the portpin's by using of hardware SPI !!!

'################################################# ##############################
$regfile = "at26def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 16
$framesize = 24

'########[ Hardware Configuration ]#################################################

' Configurate ADC's
' Single - as single ended inputs
' Auto - for the fastest possible samplingrate
' Internal - set Vref @ 2,56V
Config ADC = Single , Prescaler = Auto , Reference = Internal

' Cofigurate Interrupts
Config Int0 = Low Level ' coonfigurate Int0 at Low Level
On Int0 ISR_Int0 ' jump to ISR_Int0 label

' Enable Global Interrupts
Enable Interrupts 'enable all Interrupts
Enable Int0 'enable Interrupt Int0



' Port's Directions & PullUp's
DDRa = &B1111_1100 ' configurate I/O's 1-OUT/ 0-IN
DDRb = &B0010_0000 ' configurate I/O's 1-OUT/ 0-IN
PORTa = &B0000_0000 ' internal PullUps 1/0 on/off
PORTb = &B1100_0000 ' internal PullUps 1/0 on/off

' Output's PORT A
LED_ERR Alias PORTa.2
LED_SDWN Alias PORTa.3
LED_RDY Alias PORTa.4
REL_POWON Alias PORTa.6
REL_PROTECT Alias PORTa.7

' Input's PORT B
JP1 Alias PINb.3
JP2 Alias PINb.4
SDWN Alias PINb.6

' Output's PORT B
ERROR Alias PORTb.5

'########[ Constants ]################################################## ###########

Const PowerUp_Delay = 25 ' const x 100ms = powerup delay time [ms]
Const minThresoldCh0 = 690 ' 690
Const minThresoldCh1 = 700 ' 700

'########[ Variables ]################################################## ###########

Dim Overload_Flag As Bit
Dim Value_Ch0 As Word
Dim Value_Ch1 As Word

'########[ Initialisation ]################################################## #########

Overload_Flag = 0
Gosub LED_TEST
Gosub POWER_UP

'########[ Main Code ]################################################## ##########

Main:
Do
Value_Ch1 = GetAdc(1)
Waitms 10
Value_Ch1 = GetAdc(1)
Waitms 10
Value_Ch0 = GetAdc(0)
Waitms 10
Value_Ch0 = GetAdc(0)
Waitms 10
If Value_Ch0 < minThresoldCh0 Then
GoSub OVERLOAD
EndIf
If Value_Ch1 < minThresoldCh1 Then
GoSub OVERLOAD
EndIf
Loop
End

'########[ Subroutines ]################################################## #########

LED_Test:
LED_ERR = 0
LED_SDWN = 0
LED_RDY = 0
Waitms 1000
LED_ERR = 1
LED_SDWN = 1
LED_RDY = 1
Return

Power_Up:
Dim i As Byte
Start Adc
LED_RDY = 0
REL_PROTECT = 1
Do
Toggle LED_RDY
Waitms 100
Incr i
Loop Until i = PowerUp_Delay
REL_POWON = 1
Waitms 100
REL_PROTECT = 0
LED_RDY = 0
Goto MAIN

Power_Down:
Stop Adc
LED_RDY = 1
LED_SDWN = 0
REL_POWON = 0
Do
Waitms 400
Toggle LED_SDWN
Loop Until SDWN = 1
LED_SDWN = 1
Return

Overload:
Overload_Flag = 1
REL_POWON = 0
REL_PROTECT = 0
LED_RDY = 1
LED_ERR = 0
Do
Toggle LED_ERR
Waitms 1000
Loop
Return

'########[ ISR Routines ]################################################## ########

ISR_Int0:
Disable Int0
If Overload_Flag = 1 Then
Gosub OVERLOAD
EndIf
Gosub POWER_DOWN
Enable Interrupts
Enable Int0
Gosub POWER_UP
End