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.