News:

Let's find out together what makes a PIC Tick!

Main Menu

Power saving blink

Started by keytapper, Nov 01, 2023, 09:24 AM

Previous topic - Next topic

keytapper

Hi folks,
I'm trying to make a project which should run on a battery and for some extent to have a signal by blinking shortly a LED. Later I may add other functions that are depending to the watchdog timer.
Here's the example:
Device = 12F683

Declare Xtal 8
Config FOSC_INTOSCIO, WDTE_ON, PWRTE_OFF, MCLRE_OFF, CP_OFF, CPD_OFF, _
BOREN_OFF, IESO_ON, FCMEN_ON

Symbol out GPIO.0
Symbol SWDTEN WDTCON.0
Symbol NOT_TO = STATUS.4            ' Time Out flag
$define LOWRATE %00001100           ' 1:2048 prescaler, 4 time slower
$define HIRATE 0                    ' 1:32 prescaler, 8 time faster

OPTION_REG = %00001110              ' Watchdog configured for one second
ANSEL = 0                           ' no analog
ADCON0 = 0
TRISIO = 0                          ' all outputs
Set out                             ' set signal high for led
WDTCON = HIRATE                     ' start faster wdt
Set SWDTEN                          ' enable the timer with prescaler
Do
   Clrwdt                           ' reset the wdt
   @Sleep                           ' power down
   Clear out                        ' awaken, output low
   wdtSpeed(LOWRATE)                ' wait for about 4 seconds
   Set out                          ' output high
   @Sleep                           ' wait for a new wdt overflow
   wdtSpeed(HIRATE)                 ' short wait
Loop

Proc wdtSpeed(Rate As Byte)
   Clear SWDTEN                     ' stop wdt
   WDTCON = Rate                    ' set new rate
   Set SWDTEN                       ' restart wdt
EndProc
Unfortunately it doesn't work. I appreciate if anyone will spot the flaw.
Ignorance comes with a cost

tumbleweed

One thing I noticed is if you want to use SWDTEN to control the WDT then you need to set the config to WDTE_OFF.

keytapper

#2
Quote from: tumbleweed on Nov 01, 2023, 11:13 AMOne thing to set the config to WDTE_OFF.

I was on the same POV, but the simulation seems to ignore when the fuse isn't set. Anyway the block diagram on the datasheet shows that the settings are ORed.
Even in the real world it is not doing anything.
Ignorance comes with a cost

trastikata

#3
From the datasheet looks like MC has made a mess with the WD. Couple of things I spotted:

- The datasheet clearly states:
QuoteWhen the WDTE bit in the Configuration Word register is set, the SWDTEN bit of the WDTCON register has no effect. If WDTE is clear, then the SWDTEN bit can be used to enable and disable the WDT.

- The HFINTOSC defaults to 4MHz, not 8 MHz and you don't change the HFINTOSC settings but declare 8MHz clock.

- Pay attention to this - this is with respect the TMR0 prescaler when assigned to the WDT:
QuoteWhen the prescaler is assigned to WDT, a CLRWDT instruction will clear the prescaler along with the WDT.

-After @Sleep command you need time ( few nop's ) for the HFINTOSC  to stabilize.

- In your code within the Do loop I think you might have got the incorrect sleep-on-sleep-off order, what I see is:
Do - Sleep 60ms - Low LED - High LED -  Sleep 4000ms - Loop

- Another thing is when switching from TMR0 to WDT prescaler, a special sequence has to be followed.
QuoteWhen changing the prescaler assignment from Timer0 to the WDT module, the instruction sequence shown in Example 5-1, must be executed.

keytapper

Thanks trastikata,
I'll get corrections as you spotted on.
I was skipping the Sleep, because I thought the nops were superfluous ;D
I thought that the OPTION_REG was correct. So rather than using the Sleep n command I preferred to modify the prescaler.
Ignorance comes with a cost