Forum: Mikrocontroller und Digitale Elektronik AD Werte abh. von PWM ?


von Dani (Gast)


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

von crazy horse (Gast)


Lesenswert?

könnte an deinem Programm liegen. Ca. Zeile 30.

von Dani (Gast)


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 !?



von Matthias S. (da_user)


Lesenswert?

EMV!?

von Dani (Gast)


Lesenswert?

Kann ich zu 99% ausschließen.

Ich habe die selbe Platine mit einem Mega8, da funktioniert es 
einwandfrei.
Der Mega 16 sitzt an der selben Stelle ...

von Dani (Gast)


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

von Dani (Gast)


Lesenswert?

Ich habe inzwischen andere Werte für ocr2 ausprobiert.
Bei ocr2=50 zeigt die Anzeige wahllos Werte zwischen 0 und 16 an ...

von axelr.[DG!RTO] (Gast)


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.

von axelr.[DG1RTO] (Gast)


Lesenswert?

natürlich im OCR Int keine Ausgabe machen, sondern ein Flag setzen, 
welches in der Hauptschleife abgearbeitet wird, klar...

ging ja auch nur um s Prinzip

XlR.

von Dani (Gast)


Lesenswert?

danke für den tip, werde ich mal ausprobieren ...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.