Bascom ADC Werte auf ein Display ausgeben

  • Friedenstaube
    "Es gibt keinen Weg zum Frieden, denn Frieden ist der Weg." - Mahatma Gandhi

Holger

Mitglied
2 Jul 2012
37
0
6
73
Sprachen
Hallo,
ich habe versucht das von Euch beschriebene umzusetzen.
Das ist dabei rausgekommen:
Code:
ADC-Werte-einlesen
'Dateiname: ADC-Werte-einlesen5.bas

'-------------------------------------------------------
'Hardware: Poti1 an PC5/ADC5
'          MAX232 an PD0/PD1, Nullmodemkabel zum PC
'-------------------------------------------------------
$regfile = "m8def.dat"                                      'ATmega8-Deklarationen
$crystal = 3686400                                          'Quarz: 3,6864 MHz



Dim Wert As Word

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
                       Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off

Cls


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


On Timer1 Ontimer1                                          'Interrupt-Routine für Timer1-Overflow
                                                            'Bis 0..2: Timer Takt ist Quarz/64 =
Tccr1b = &B00000011                                         ',87 sek pro Impuls
Timsk.toie1 = 1                                             ' Timer1-Overflow-Interrupt ein
Sreg.7 = 1                                                  'Globale Interrupfreigabe


Admux = &B01100000                                          'Bit 6und 7 =01=AVCC ist Refenzspannug
                                                            'Bit 5 =1=nur 8 Bit Genauigkeit
                                                            'Bit4 nicht belegt
                                                            'Bit 3...0 = 0000 =Pin ADC0 = PC0

Adcsra = &B10000111                                         'Bit 7 =1=ADC an
                                                            'Bit 6 =1=ADC gestartet
                                                            'Bit 5 =0 keine fortlaufende Wandlung
                                                            'Bit 4 =0 ADIF =ADC Interrupt Flag
                                                            'Bit 3 =0 ADIE =ADC Interrupt Enable
                                                            'Bits 2..0 = AVRClock/128

Wert = Adif

Do
      If Wert = 1 Then
      Locate 1 , 1
      Lcd "Temperatur  " ; Adch
      End If
Loop


Ontimer1:
Adcsra.6 = 1                                                'Bit 6 =1 jede Messung wird einzeln gestartet


Return

läuft aber leider nicht. Ist es nicht richtig, dass ich das Bit 6 im Register Adcsra auf 0 setze, um dann bei Timerinterrup auf 1 zu gehen und damit die Einzelwandlung anstoße?
Gruß
Holger
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4,326
159
63
Mittelhessen, Giessen
Sprachen
  1. ANSI C
  2. C++
  3. C#
  4. Java
  5. Kotlin
  6. Pascal
  7. Assembler
  8. PHP
Hallo Holger,

ich gehe davon aus, dass der Timer-Interrupt funktioniert und zyklisch eine einzelne Wandlung startet.

Im Hauptprogramm müsstest du innerhalb der Do-Loop Schleife das Interrupt-Anforderungsflag des ADC überprüfen (und wenn gesetzt, dann durch setzen der Bitposition "manuell" löschen), das passiert bei dir nicht. Vor der Do-Loop Schleife weist du der Variable "Wert" (WORD) das ADIF-Bit zu (denke ich mir zumindest). Ich weiß nicht ob das so geht, bzw was Bascom da genau macht (ich programmiere selber nicht in Bascom, da fehlt mir ein bisschen die Erfahrung). Jedenfalls in der Do-Loop Schleife dürfte sich "Wert" nie mehr ändern.

Dirk :ciao:
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3,505
65
48
Marwitz
Sprachen
  1. BascomAVR
  2. Assembler
Genau.
ADIF ist einfach nur die Konstante 4 (dezimal). Definiert in der inkludierten Prozessordefinitionsdatei-
Mit Wert=ADIF weist Du der Word-Variable also den Wert 4 zu (also 0000_0000_0000_0100 binär). Da der Wert nie geändert wird, wird der If-Zweig auch nie abgearbeitet.
Übrigens sind die ganzen Bitnamen genau dafür in der inkludierten Prozessordefinitionsdatei, damit Du eben nicht die einzelbits mit ihrer Wertigkeit ansprechen mußt. Bascom bietet Dir ja die Bitschreibweise - ADIF erreichst du (als Bit in ADCSRA) eben über ADCSRA.ADIF. Laß Wert komplett raus, und ersetze die If-Bedingung durch ADCSRA.ADIF=1. Dann sollte es erstmal stimmen. Allerdings bleibt das ADIF jetzt nach der ersten Wandlung (wo es gesetzt wird) immer auf 1, wird nie gelöscht. Folglich wird der If-Zweig danach bei jedem Durchlauf der Hauptschleife abgearbeitet, auch wenn gar keine neue Wandlung abgeschlossen ist. also viel zu oft. Du mußt es also selbst löschen. Lies Dir mal bitte im Datenblatt die Beschreibung zu ADCSRA, speziell zu ADIF durch, und sag uns wie.
 

Holger

Mitglied
2 Jul 2012
37
0
6
73
Sprachen
Fein,fein ich glaube jetzt klappt es richtig!
Ich hatte vorher bei der If Anwendung "ADIF" eingesetzt, das funktionierte jedoch nicht, daher habe ich es mit der Variablen "Wert" versucht.
Mit "ADCSRA.ADIF" funktionierte es aber. Daher habe ich jetzt die Variable rausgenommen. Mit Else habe ich dann wieder "ADCSRA.ADIF" auf 1 gesetzt. Laut Datenblatt soll zum Löschen eine logische 1 gesetzt werden.

Code:
'ADC-Werte-einlesen
'Dateiname: ADC-Werte-einlesen6.bas

'-------------------------------------------------------
'Hardware: Poti1 an PC5/ADC5
'          MAX232 an PD0/PD1, Nullmodemkabel zum PC
'-------------------------------------------------------
$regfile = "m8def.dat"                                      'ATmega8-Deklarationen
$crystal = 3686400                                          'Quarz: 3,6864 MHz


Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
                       Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off

Cls


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


On Timer1 Ontimer1                                          'Interrupt-Routine für Timer1-Overflow
                                                            'Bis 0..2: Timer Takt ist Quarz/64 =
Tccr1b = &B00000011                                         ',87 sek pro Impuls
Timsk.toie1 = 1                                             ' Timer1-Overflow-Interrupt ein
Sreg.7 = 1                                                  'Globale Interrupfreigabe


Admux = &B01100000                                          'Bit 6und 7 =01=AVCC ist Refenzspannug
                                                            'Bit 5 =1=nur 8 Bit Genauigkeit
                                                            'Bit4 nicht belegt
                                                            'Bit 3...0 = 0000 =Pin ADC0 = PC0

Adcsra = &B10000111                                         'Bit 7 =1=ADC an
                                                            'Bit 6 =1=ADC gestartet
                                                            'Bit 5 =0 keine fortlaufende Wandlung
                                                            'Bit 4 =0 ADIF =ADC Interrupt Flag
                                                            'Bit 3 =0 ADIE =ADC Interrupt Enable
                                                            'Bits 2..0 = AVRClock/128


Do                                                          'ADIF: ADV Interrupt Flag wird nach
      If Adcsra.adif = 1 Then                               'der Conversion automatisch auf 1 gesetzt.
      Locate 1 , 1
      Lcd "Temperatur  " ; Adch
      Else
      Adcsra.adif = 1                                       'ADIF: ADV Interrupt Flag wieder auf 0 setzen
      End If                                                'zum Löschen soll lt Datenblatt eine
Loop                                                        'logische 1 gesetzt werden


Ontimer1:
Adcsra.6 = 1                                                'Bit 6 =1 jede Messung wird einzeln gestartet


Return

Ist das so richtig?

Gruß
Holger
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4,326
159
63
Mittelhessen, Giessen
Sprachen
  1. ANSI C
  2. C++
  3. C#
  4. Java
  5. Kotlin
  6. Pascal
  7. Assembler
  8. PHP
Hallo Holger,

Den Bereich Else entfernst du. Innerhalb If-EndIf musst du das Bit ADIF löschen. Das machst du tatsächlich so, indem du die Bitposition auf 1 setzt.

Dirk :ciao:
 

Holger

Mitglied
2 Jul 2012
37
0
6
73
Sprachen
Hallo Dirk,

habe ich durchgeführt.
Sieht jetzt so aus.

Code:
Do                                                          'ADIF: ADV Interrupt Flag wird nach
      If Adcsra.adif = 1 Then                               'der Conversion automatisch auf 1 gesetzt.
      Locate 1 , 1
      Lcd "Temperatur  " ; Adch
            Adcsra.adif = 1                                 'ADIF: ADV Interrupt Flag wieder auf 0 setzen
      End If                                                'zum Löschen soll lt Datenblatt eine
Loop                                                        'logische 1 gesetzt werden

Danke für Eure Hilfe.

Gruß
Holger
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)