2015 nominee for best computer generated animations.
Robert
2015 nominee for best computer generated animations.
Robert
I know of the 4MHz RC clock. What’s the other?
It got figured out on another forum. A better way actually, without writing to the on-chip EEPROM at all.
Code:'*********************************************************************************** '* * '* Microchip Pic 16F628 @ 8,16 or 24MHz * '* Art 2015 * '* * '* [email protected] * '* * '*********************************************************************************** ' ' DEFINE OSC 20 ' DEFINE NO_CLRWDT 'watchdog is cleared manually ' INCLUDE "Elapsed.bas" ‘modified to take a variable ' ' execution time! ' ' percount var byte ' wrtcount var byte ' clkvalue var byte ' xdata var byte ' 'oscfreq var word ‘this is declared in Elapsed Timer file notreset var bit ' ' CMCON = 7 'set ports digital trisb.4 = 0 'set led output portb.4 = 0 ' ' percount = 0 ' clkvalue = 0 ' ' ' notreset = status.bit4 'check wdt reset occured - 0 is did reset ' ' if notreset = 1 then 'was not reset by watchdog portb.4 = 1 'turn led on for percount = 0 to 255 'do eeprom writes until wdt reset pause 100 ' write percount,$00 ' next percount ' makereset: 'failsafe to make reset occur @ nop ; goto makereset ' else 'was reset by watchdog @ clrwdt ;clear the watchdog from now on wrtcount = 0 'reset write counter countwrites: 'count eeprom writes read wrtcount,xdata 'read byte @ clrwdt ; pause 10 ' if xdata != $00 then ' goto donecount 'exit counting loop endif ' wrtcount = wrtcount + 1 'increment count goto countwrites ' donecount: ' for percount = 0 to 255 'erase the eeprom for next time pause 10 ' @ clrwdt ; write percount,$FF ' next percount ' endif ' ' 'gosub flashout 'for testing only ' oscfreq = 0 'reset oscillator frequency ' if wrtcount > 8 then '11 oscfreq = $B1E7 'set oscillator frequency endif ' if wrtcount > 18 then '21 oscfreq = $63C7 'set oscillator frequency endif ' if wrtcount > 27 then '30 oscfreq = $15A7 'set oscillator frequency endif ' ' ' gosub ResetTime 'reset time 00:00:00 gosub StartTimer 'start clock timer ' ' ' cycle: @ clrwdt if Ticks > 49 then portb.4 = 1 else portb.4 = 0 endif goto cycle ' ' ' flashout: 'flash out the count of eeprom writes before wdt reset for percount = 0 to wrtcount 'with the red led portb.4 = 1 'flash rate will still depend on oscillator frequency pause 250 'at this stage @ clrwdt ' pause 350 ' @ clrwdt ' portb.4 = 0 ' pause 250 ' @ clrwdt ' pause 350 ' @ clrwdt ' next percount ' pause 500 ' @ clrwdt ' pause 500 ' @ clrwdt ' pause 500 ' @ clrwdt ' return ‘ '
Actually there are three, 4 Mhz and 48Khz internal clocks and the WDTI know of the 4MHz RC clock. What’s the other?
I always thought the wdt clock was derived from the internal RC clock, but some Googling confirms it's not.
Fortunately it appears Timer1 does not get reset with the wdt, so the byte values in the timer register
could be used instead of writing to EEPROM.
Pretty clever Art!
Regards,
TABSoft
Thanks
It wasn’t my idea to use timer1 values as RAM that survives WDT reset,
but I figure as long as you haven’t started timer1, you could just write the count into
one of the timer1 bytes instead of on-chip EEPROM and read the value after the reset.
For my clock board I have swapped the 8MHz crystal with a 20MHz crystal,
and added a dual flip flop to divide two of the clocks, so now have:
8,12,16,20 & 24MHz. One dual more flip flop, and I’ll have 6 & 10MHz as well.
It has been reliable so far with the freqs I can test, bust suspect any 1MHz increment is easy to detect.
Ok, after a little experimentation today, finding the frequency without any use of EEPROM at all is really this easy:
Then you have a number in wrtcount that represents the crystal frequency i.e. a couple of values either side of 25 = 20MHz.Code:' DEFINE OSC 20 ‘needed so the 100ms pause period is known ' if status.bit4 = 1 then 'was not reset by watchdog for percount = 0 to 255 'do eeprom writes until wdt reset pause 100 ' @ MOVF _percount ,W ;copy counter value to timer low byte @ MOVWF TMR1L ;load timer with count value next percount ' makereset: 'failsafe to make reset occur goto makereset ' ' else 'hardware was reset by watchdog @ clrwdt ; @ MOVF TMR1L ,W ;copy counter value to timer low byte @ MOVWF _wrtcount ;reload timer with correct value endif ' '
This is with the power timer also set, but I doubt that matters as the pic isn’t doing anything in power timer period.
In any case, it’s very handy to know that if you’re not using Timer1,
you have an ordinary word variable that survives WDT for certain.
If your program was going to use Timer1 after this, the values should probably be reset to zero, then the clock started.
DT’s Elapsed Timer code does have a Reset feature which probably does this as well as clearing it's real time variables.
Last edited by Art; - 3rd April 2015 at 08:43.
Bookmarks