Forum: Mikrocontroller und Digitale Elektronik PIC12F1572 -> Problem mit Sleep -> Wird nicht immer ausgeführt


von Sim L. (nethacks)


Lesenswert?

Hallo Leute,

Habe ein Programm geschrieben, welches einiges an Pheriperie benutzt.
Insbesondere: FVR,DAC,CMP und PWM

Nun wollte ich das Programm für einige Zeit schlafend legen:

If Decay = 0 Then                 'Nothing to do
INTCON.GIE = 0                    'Generell Interrupt disabled
WDTCON.0 = 1                      'Switch wachdog on
For LoopWord = 0 To 5             'Wait for some time (96 seconds) in 
sleepmode
clrwdt                            'Clear Watchdog timer
sleep                             'Enter sleep mode,till watchdog bite
delay_ms(1)                       'Wait during all stable
Next LoopWord
WDTCON.0 = 0                      'Switch watchdog off
INTCON.GIE = 1                    'Generell Interrupt enabled
PWM2_Set_Duty(SixtySixPwmDutyCycle) 'Set duty cycle to 66.6%
delay_ms(2000)                    'Wait to stabilize the AGC voltage
End If

Leider wird der Sleep nicht immer ausgeführt.
Ab und zu klappt es wie es soll, dann wieder mal gar nicht.
An den Überschwingern am Oszi konnte ich herausfinden, das diese
vom "PWM2_Set_Duty(SixtySixPwmDutyCycle)" ausgelöst werden.
Daher kann ich es definitiv auf diesen Codebereich  lokalisieren.

Hardware Init:
sub procedure InitHardware
    ANSELA       = %00000010             'RA1 = Analogue. All other pins 
digital.
    PORTA        = %00000000             'Reset all Port Bits
    TRISA        = %00001010             'Select inputs/outputs
   'TRISA.0      = 0                     'Output: PWM2 for AGC
   'TRISA.1      = 1                     'Input: Level from TA7642 
circuit
   'TRISA.2      = 0                     'Output: Red Green
   'TRISA.3      = 1                     'Input: MCLR / Option
   'TRISA.4      = 0                     'Output: Yellow LED + TXD
   'TRISA.5      = 0                     'Output: Red LED + RXD
    WDTCON       = %00011100             'Setup Wactdog
   'WDTCON.0     = 0                     'Watchdog is off
   'WDTCON.1     = 0                     'Setup Watchdog to 16 seconds
   'WDTCON.2     = 1                     'Setup Watchdog to 16 seconds
   'WDTCON.3     = 1                     'Setup Watchdog to 16 seconds
   'WDTCON.4     = 1                     'Setup Watchdog to 16 seconds
   'WDTCON.5     = 0                     'Setup Watchdog to 16 seconds
   'WDTCON.6     = 0                     'No function
   'WDTCON.7     = 0                     'No function
    APFCON       = %10000100             'Select alternative USART Pins
   'APFCON.7     = 1                     'RXD is on RA5 instead of RA1
   'APFCON.2     = 1                     'TXD is on RA4 instead of RA0
    FVRCON       = %10001000             'Setup the FixedVoltageBuffer
   'FVRCON.3     = 1                     'Setup FixedVoltageBuffer to 
2.028V
   'FVRCON.2     = 0                     'Setup FixedVoltageBuffer to 
2.028V
   'FVRCON.7     = 1                     'Activate FixedVoltageBuffer
    DACCON0      = %10001000             'Setup the DAC
   'DACCON0.7    = 1                     'Enable DAC
   'DACCON0.3    = 1                     'Setup DAC. Vref = 
FixedVoltageBuffer
   'DACCON0.2    = 0                     'Setup DAC. Vref = 
FixedVoltageBuffer
    DACCON1      = 16                    'SetDAC to 1.048V (64mV * 
DACCON1)
    CM1CON0      = %10000110             'Setup the comparator
   'CM1CON0.0    = 0                     'Comparator output to Timer1 
and I/O pin is asynchronous
   'CM1CON0.1    = 1                     'Comparator hysteresis is 
enabled
   'CM1CON0.2    = 1                     'Comparator mode is in Normal 
Power, Higher Speed mode
   'CM1CON0.3    = 0                     'No function
   'CM1CON0.4    = 0                     'Comparator output is not 
inverted
   'CM1CON0.5    = 0                     'Comparator out is internal 
only
   'CM1CON0.6    = 0                     'Normal polarity (because int 
on falling edge)
   'CM1CON0.7    = 1                     'Comparator is on
    CM1CON1      = %01010000             'Setup the comparator
   'CM1CON1.6    = 1                     'Comparator Interrupt on 
falling Flag
   'CM1CON1.5    = 0                     'Comparator + is connected DAC
   'CM1CON1.4    = 1                     'Comparator + is connected DAC
   'CM1CON1.2    = 0                     'Comparator - is connected RA1
   'CM1CON1.1    = 0                     'Comparator - is connected RA1
   'CM1CON1.0    = 0                     'Comparator - is connected RA1
    PIE2.C1IE    = 1                     'Comparator interrupt on
    INTCON       = 192                   'Setup the interrupts
   'INTCON.PEIE  = 1                     'PEIE enabled
   'INTCON.GIE   = 1                     'Generell Interrupt enabled
    PWM2_Init()                          'Init the PWM2 Output for AGC
end sub

sub procedure PWM2_Init()
    PWM2CLKCON  = 0
    PWM2LDM_bit = 0
    PWM2CON     = 0
    PWM2DCH     = 0
    PWM2DCL     = 0
    PWM2PHH     = 0
    PWM2PHL     = 0
    PWM2OFH     = 0
    PWM2OFL     = 0
    PWM2PRH     = 0
    PWM2PRL     = 200
end sub

sub procedure PWM2_Set_Duty(dim duty as word)
  dim period as word
  period      = PWM2PRH * $0100 + PWM2PRL
  duty        = word((float(duty) / $FFFF) * period)
  PWM2DCH     = duty >> 8
  PWM2DCL     = duty and $00FF
  PWM2LD_bit  = 1
end sub

Hat jemand einer eine Idee?

Ich habe den Verdacht, dass irgendein Interrupt den Sleep
verhindert bzw. sofort wieder zurücksetzt.

Wäre für weiterführende Antworten dankbar.

von Sim L. (nethacks)


Angehängte Dateien:

Lesenswert?

Natürlich immer diese Anhänge ;-)

von Sim L. (nethacks)


Lesenswert?

Keiner eine Idee?
Habe jetzt auch schon das PEIE bit vor der WDT Schleife zurücksesetzt 
und dann wieder gesetzt.
Aber leider ohne Besserung :-(

von Sim L. (nethacks)


Angehängte Dateien:

Lesenswert?

Weiterführende Informationen:

Scheinbar wird das Sleep schon ausgeführt.
Nur wird der PWM Level irgendwie gesetzt.
Vor allem: Jedesmal anders.

Bilderklärung: Das Oszilloskop ist über eine RC Kombination an den PWM 
Ausgang angeschlossen,
um aus dem PWM Signal ein Spannungssignal zu bekommen.

Die Sleep Routine sieht nun wie folgt aus:
If Decay <= 0 Then           'Nothing to do
   INTCON.GIE = 0                       'General Interrupts disabled
   INTCON.PEIE = 0              'Peripheral Interrupts disabled
   PIE2.C1IE = 0                      'Comparator Interrupt disabled
   WDTCON.0 = 1                      'Switch wachdog on
   For TempLoop = 0 To 5             'Wait for some time (96 seconds)
      sleep                             'Enter sleep mode
      NOP                               'NOP
   Next TempLoop
   WDTCON.0 = 0                         'Switch watchdog off
   INTCON.PEIE = 0                      'Peripheral Interrupt enabled
   INTCON.GIE = 1                       'General Interrupts enabled
   PIE2.C1IE = 1                        'Comparator Interrupt enabled
   PIR2.C1IF = 0                        'Reset Comparator Interrupt
   PWM2_Set_Duty(SixtySixPwmDutyCycle)  'Set duty cycle to 66.6%
   delay_ms(2000)                       'Wait to stabilize the AGC 
voltage
End If

Weiss den wirklich keiner weiter,an was das liegen kann?
Falls es wichtig ist:Der PIC12F1572 besitzt einen (eigentlich drei) 
16bit PWM.

von Fred R. (Firma: www.ramser-elektro.at/shop) (fred_ram)


Lesenswert?

Du hast etwas vergessen:
Wenn du in sleep gehst, bleibt der letzte Peripheriezustand erhalten.
Es ist niergenwo festgelegt, wie sich das PWM Modul verhält, wenn du ihm 
den Clock wegnimmst.

Lösungsvorschlag:
VOR dem Sleep das PWM2 Modul deaktivieren.
Den verwendeten Port Pin im Latch LOW setzen.
1
PWM2CON.6   = 1  'PWM output aus
2
PWM2CON.7   = 1  'PWM aus
3
PortA.?? = 0   'Port Latch Low setzen

NACH dem Sleep wieder aktivieren.
1
PWM2CON.6   = 1  'PWM output ein
2
PWM2CON.7   = 1  'PWM ein

Ausserdem:
Bei Mikrobasic ist in der Befehlsreferenz kein "sleep" command 
enthalten.
Probier es mal so:
1
asm
2
sleep
3
nop
4
end asm

Bitte um Rückmeldung.

von Sim L. (nethacks)


Lesenswert?

DAS war es.
Dankeschön :-D

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.