AD Werte abh. von PWM ?

Gast #585792
Lesenswert?

Hallo,

ich lese einen AD Wandler aus, lasse das Ergebniss im Display anzeigen 
und Dimme die Displaybeleuchtung per PWM.

Beim Mega 8 funktoniert es problemlos.

Beim Mega 16 ändert sich der Wert des AD Wandlers abh. von der 
Displayhelligkeit!?

Woran kann das liegen, ich habe keine Idee mehr.

Schon mal Danke für Eure Vorschläge,

Dani
Gast #585800
Lesenswert?

Ah ja richtig, der Programmcode ...


$regfile = "m16def.dat"                                     'ATmega16
$crystal = 1000000                                          'Quarz: 1 
MHz


' 
------------------------------------------------------------------------ 
-----
' Definition des AD Wandlers

$hwstack = 32
$swstack = 10
$framesize = 40
'$framesize = 50

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


' 
------------------------------------------------------------------------ 
-----
' Definition Timer 0 als Timer


On Timer1 Pulse
Config Timer1 = Timer , Prescale = 8 
'Timer1,125kHz
Enable Interrupts
Enable Timer1

' Pulse wird jede ms aufgerufen
Timer1 = 65411                                              '1Mhz

' Definition Timer 2 als PWM (Helligkeit des Displays)

Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1
Enable Interrupts
Enable Timer2

Ocr2 = 254 
'Displaybeleuchtung 100%
.
.
.
  Z = Getadc(5)

Bei Ocr2=20 liefert getadc(5) andere Werte !?


Gast #585815
Lesenswert?

So, hier also der Komplette Bascom Code.

Bei ocr2=254 wird 0 angezeigt
Bei ocr2=20 wird 12 angezeigt

Woran kann das liegen?


' 
------------------------------------------------------------------------ 
-----
' Definition des verwendeten Kontrollers + Taktfrequenz

$regfile = "m16def.dat"                                     'ATmega16
$crystal = 1000000                                          'Quarz: 1 
MHz


' 
------------------------------------------------------------------------ 
-----
' Definition des AD Wandlers

$hwstack = 32
$swstack = 10
$framesize = 40

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


' 
------------------------------------------------------------------------ 
-----
' Definition Timer 0 als Timer


On Timer1 Pulse
Config Timer1 = Timer , Prescale = 8 
'Timer1,125kHz
Enable Interrupts
Enable Timer1

' Pulse wird jede ms aufgerufen
Timer1 = 65411                                              '1Mhz

' Definition Timer 2 als PWM (Helligkeit des Displays)

Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1
Enable Interrupts
Enable Timer2



' 
------------------------------------------------------------------------ 
-----
' Definition der benötigten Variablen

Dim Z As Integer
Dim W As Byte
Dim X As Single
Dim T1 As Integer
Dim Licht As Bit

' 
------------------------------------------------------------------------ 
-----
' Definition der Ein- und Ausgänge
' Konfiguration Port-a, 8 Bit, Eingänge mit int. PullUp

Porta = &B11111111
Ddra = &B00000001

Portb = &B11111111
Ddrb = &B11111111

Portc = &B11111111
Ddrc = &B00000000

Config Portd = Output

' 
------------------------------------------------------------------------ 
-----

Gosub Dog

Config Lcdpin = Pin , Rs = Portd.5 , E = Portd.4 , Db4 = Portd.0 , Db5 = 
Portd.1 , Db6 = Portd.2 , Db7 = Portd.3

Config Lcd = 16 * 2

Display On
Cursor Off


' 
************************************************************************ 
*****
' Hauptschleife

Do

   If Pinc.3 = 0 Then
      Waitms 5
      If Pinc.3 = 0 Then
         Gosub Taster_1
      End If
   End If
' - Aktualisieren der Anzeige 
-------------------------------------------------

      If T1 > 1000 Then
         T1 = 0
         Gosub Ausgabe
      End If

Loop

' 
************************************************************************ 
****

End

' 
------------------------------------------------------------------------ 
----
Taster_1:

   Toggle Licht
   If Licht = 0 Then
      Ocr2 = 254
         Else
            Ocr2 = 20
   End If

Return

' 
------------------------------------------------------------------------ 
----
Ausgabe:

   Z = Getadc(5)
   Locate 1 , 1
   Lcd "       "
   Locate 1 , 1
   Lcd Z

Return

' 
------------------------------------------------------------------------ 
-----
Pulse:

   Timer1 = 65411

   T1 = T1 + 1
   If T1 > 32100 Then T1 = 32100

Return

' ---------------------- LCD DOG162 Konfigurieren 
-----------------------------

Dog:

   Restore Da
   For X = 1 To 22
      Read W
      Portd = W : Waitms 2
      Set Portd.4
      Waitms 1
      Reset Portd.4
   Next

Return

Da:

' - synchronisations Bits 
-----------------------------------------------------
Data &H3 , &H3
Data &H3 , &H2
' 
------------------------------------------------------------------------ 
-----
Data &H2 , &H9
Data &H1 , &HC
Data &H5 , &H2
Data &H6 , &H9
Data &H7 , &H4
Data &H0 , &HF
Data &H0 , &H1
Data &H0 , &H6

Data &H2 , &H8
Gast #585859
Lesenswert?

Das muss in die OCR2 Interruptroutine
>>     If T1 > 1000 Then
>>         T1 = 0
>>         Gosub Ausgabe
>>      End If
so misst Du nur dann deinen Wert, wenn der PWM-BLOCK gerade geschaltet 
hat.
Wenn deine PWM-Frequenz kleiner ist, als die Wandlerlaufzeit (13Clocks 
ADC-CLK), ist der ADC fertig, bevor ein neuer PWM Zyklus gestartet hat.
so in etwa, jedenfalls musst Du den ADC mit der PWM syncronisieren.

Habe ich bei ...HanneS... seinerzeit aufgegriffen.

In seinem Fernsteuersender werden auch die Potis für die einzelnen 
Kanäle mit dem ADC abgefragt. Das macht er dort auch in den 
Impulspausen. Analog dazu müsstest Du dir eben auch eine Strategie 
ausdenken. Da bietet sich der OCR2 Interrupt an.

Allerdings solltest Du dann den Wert "Prescale" in dieser Zeile ändern.
>>Config Timer2 = Pwm , Pwm = On , Compare Pwm = Clear Up , Prescale = 1
So hoch, das die LEDs eben gerade noch nicht flackern.

Viel Spass
XlR.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren