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.
Natürlich immer diese Anhänge ;-)
Keiner eine Idee? Habe jetzt auch schon das PEIE bit vor der WDT Schleife zurücksesetzt und dann wieder gesetzt. Aber leider ohne Besserung :-(
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.





