PicAxe advanced features

steliosm

Senior Member
Hello all.

I'm trying to figure out the POKE and PEEK commands along with the PICmicro datasheets. It's a bit complicated for me right now. I can understand that those commands can give me access to the internals of the PicAxe chips and allow me to change a few things, but I can't figure out what is safe to POKE and how to get the addresses to POKE from the datasheet.

I was wondering is anyone had a good tutorial/pointer on this issues.

All I want to do right now is enable TIMER1 on the 08m to make is count pulses in the background. I read an article for the 18X chip from http://phanderson and I wanted to see if I could do that on an 08m chip.
 

lbenson

Senior Member
Stelios--I found this thread by Brian Lavery (after Hippy) to be very informative on the use of Timer1: http://www.picaxeforum.co.uk/showthread.php?t=5849.

I'll attach the code for one 08M program that uses this technique. The heart of the matter is in the "Tick_Dvr" subroutine. This particular program tested running the 08M at 32kHz, so you'll want to ignore that part.
Code:
; **************************************************************************
; *                                                                        *
; *     Test Timer1 timing for 08M running at 32kHz          TST32KZC.BAS  *
; *                                                                        *
; **************************************************************************

        SYMBOL VERSION_MAJOR = 1        ' 1.0
        SYMBOL VERSION_MINOR = 0

; .------------------------------------------------------------------------.
; |                                                                        |
; |     Version         1.0                                                |
; |     Last Update     2007-08-17                                         |
; |                                                                        |
; |     Target          PICAXE-08M                                         |
; |     Compiler Used   Revolution Programming Editor 5.1.5                |
; |     Memory Used     Approx ??? bytes of 256                            |
; |                                                                        |
; |     Author          Lance Benson                                       |
; |                                                                        |
; `------------------------------------------------------------------------'

; ---Timer Definitions per Brian Lavery after the Happy Hippy---------------
symbol PIC_TMR1H = 0x0F         ' (MSB) PIC Timer1 data (counter) register
symbol PIC_TMR1L = 0x0E         ' (LSB) PIC Timer1 data (counter) register
symbol PIC_T1CON = 0x10         ' PIC Timer1 Control Register
' GP Picaxe bit variables that must be PRESERVED at all times in your code:
symbol Tick_flag = bit0         ' set for 1 exec loop per tick (second)
symbol Tick_hi = bit1           ' hi or lo half second of each tick
symbol Mins_Flag = bit2   
symbol HalfMin_Flag = bit3       ' used for second temp sensor read--good for one main loop only      
' 1-byte peek/poke RAM variables:
' (choose suitable values in 0x50 - 0x7F area)
symbol Systime0 = 0x52          ' 6.5 bit tick counter in S S S S S S h 0         lsB
symbol Systime1 = 0x53          ' MINS counter (approx!.  1 "min" = 64 ticks!)
symbol Systime2 = 0x54          '                                                 msB
symbol TimerLast = 0x55
' 2-byte peek/poke RAM variables:
' (again choose suitable values in 0x50 - 0x7F area)
#rem
symbol LoopCounter = 0x56?
symbol LoopsPerTik = 0x58?
#endrem
; -------------------End of Timer Definitions-------------------------------

#picaxe 08M                  ' leg 8: 0V; leg 7: O0, serout, infraout; leg 6: I1, O1, ADC1; leg 5: I2, O2, ADC2, pwm2
                             ' leg 4: I3; leg 3: I4, O4; leg2: serial in; leg 1: 5V
                             ' connections: O0-transmitter; 
#define AXE08M

symbol MyId              = 1 ' picaxe ID--different for each sensor detector module

symbol SaveW6        = 0x56 ' 2-byte peek/poke Ram variable

start:
    let dirs = %00000       ' set pins 1,2,3,4 input from sensors--08M only
    disablebod              ' saves battery
  #ifndef SIMULATE
    poke PIC_T1CON, 0x31    ' Start PIC timer1 running at 524 mSec 16-bit rollover
  #else
    b1 = 5
    poke TimerLast, b1      ' For simulation. let it loop
  #endif

initiate:
  if pin3 = 1 then         ' beginning of pulse on 3
    poke PIC_TMR1H, 0      ' clear high and low bytes of Timer1
    poke PIC_TMR1L, 0
    poke PIC_T1CON, 0x31   ' Start PIC timer1 running at 524 mSec 16-bit rollover
    Tick_hi = 0            ' reset half-secont flag (524 ticks)
    Tick_flag = 0          ' reset second flag (524 ticks)
    Mins_Flag = 0          ' reset minute flag
    setint %00000000,%00001000 ' interrupt on pin3 low
    pin2 = 1               ' turn on led to mark detection of pulse
  else                     ' end of pulse on 3
    poke PIC_T1CON, 0      ' stop timer1
    gosub printTime
    setint %00001000,%00001000 ' interrupt on pin3 high
    pin2 = 0               ' turn off led
  endif

main:
  ModuleID = MyID  ' only CheckPackets will change this
  gosub Tick_Dvr
  #ifdef TEST1
    Mins_Flag = 1        ' test temperature
    MinuteCount = 59     ' test hourly time check
  #endif
  gosub readSensors
  gosub readTemps
  gosub checkTime
  if Tick_flat = 1 then
    gosub checkPackets    '  see if any packets are scheduled to be resent
  endif
  goto main

readSensors:
' #ifdef INCLUDECODE
  return

readTemps:                            ' uses b1, b2-b3 (as w1), b4-b5 (as w2), b11; saves & restores w6
  return

checkTime:               ' send checkin packet
  if Mins_flag = 1 then  ' we rolled over to a new minute
    inc MinuteCount
  endif
  if MinuteCount = 60 then  ' check in
    peek SysTime0, word w1
'    ModuleID = MyID
    MessageType = MsgTimeCk 
    PacketData1 = b2
    PacketData2 = b3
    MinuteCount = 0
    gosub sendPacket
  endif
  return

checkPackets:  ' see if there is packet in ring buffer to be resent--each is sent 4 times
  SentCount = ?
  
  return
    

    
Tick_Dvr:
    ' Note: comments below refer to 4mHz clock--this routine tests 31kHz
    '  rollover of PIC_TMR1H every 16 seconds approximately: Tick_flag=1 means 32 seconds have passed
    '
    ' 1 TICK defined as 1 second
    ' Maintain a 23 bit TICK counter at SYSTIME (in half-tix)
    ' TICK flag occurs once each tick.  All drivers may detect ONE tick-flag each second
    ' MINS flag occurs once each minute.  All drivers may detect ONE mins-flag each minute
    ' Any routine is entitled to peek the elapsed time from systime0, systime1, systime2
    ' MMMMMMMM mmmmmmmm SSSSSSh0
    ' Mm=Mins            S=Secs        h=half-tik (half sec)
    ' "Secs" is actually 524*2 = 1048 mSecs,   "Mins" is actually 64 "secs".
    ' This routine does not destroy any register values except for b0 
     '    (Tick_flag, Tick_hi, Mins_Flag, HalfMins_Flag bits (0,1,2,3)

    poke SaveW6, word w6            ' This routine uses w6,b12,b13, so save the entry value    
    Tick_flag = 0                   ' Flags last only one exec loop
    Mins_Flag = 0
    HalfMin_Flag = 0
    peek TimerLast, b13             ' What was the Timer1 value last time round the loop?
    #ifdef SIMULATE
      b12 = b13 - 1                 ' Simulate 1 tick per loop
    #else
      peek PIC_TMR1H, b12           ' Read msb of PIC's timer1
    #endif
    poke TimerLast, b12
    if b13 > b12 then               ' Test whether timer1 has started from zero again?
                                    ' Arrive here once per every 524 mSec
        tick_flag = Tick_hi         ' Flag a new tick (High only ONCE / 1048 mSec)
        Tick_hi = 1- Tick_hi        ' Toggle the Tick-hi flag. Half sec on, half sec off
        Peek systime0, b12          ' Fetch system SECS counter - format = SSSSSSh0
        b12 = b12  + 2 And 0xFE     ' Add 2 every half-tick
        Poke systime0, b12          ' Store SECS counter back again
        if b12 = 0 then             ' Byte overflow every 64 seconds
            peek systime1, word w6  ' Fetch 16-bit MINS counter 
            inc w6                  ' Rollover onto higher 16 bits (MINS counter - format = MMMMMMMM mmmmmmmm )
            poke systime1, word w6  ' Store Mins back again
            Mins_Flag = 1           ' Flag a new minute
        EndIf
        #ifdef Temp2 then           ' set a half-minute flag to trigger read of second sensor
          if b12 = $10000000 then
            HalfMin_Flag = 1        ' Flag new half-minute
          endif
        #endif
    EndIf
    peek SaveW6, word w6            ' Restore the value of w6 that we entered with

    return
    

; **************************************************************************
; *                                                                        *
; *     End of Sensor module shell for the PICAXE-08M                      *
; *                                                                        *
; **************************************************************************
 

BeanieBots

Moderator
It's OK to use peek and poke into the published user ram area but poking values into SFR to make a PICAXE do something other than that which is available through the 'regular' commands is not officially supported.
Even with reference to the PIC datasheet, there is no gaurantee that the PICAXE firmware will not overwrite what you have done or do something unexpected. Therefore, it is very unlikely that you will find any sort of formal documentation on the subject.
Having said that, there are quite a few examples buried in the archives where people have just "tried it" and published the results.
You can't break anything (except maybe making in input an output that has a strong signal on it) and any changes you make will revert back at the next reset.
 

steliosm

Senior Member
Lance thank you. I'll play a bit with the code to see how it works and understand the logic. I hope I can make the 08m work as a simple counter chip (like the DS2423 chip).
BeanieBots I'll have a go with the archived threads and see what I come up with. My main concern is to figure out how to translate datasheet information into POKE/PEEK commands/addresses.
Good to know that a reset will bring my chip from the dead :)
 

hippy

Technical Support
Staff member
Look for SFR. I think Hippy had put forth a fuller list of what could be done, but I couldn't find it in a brief search.
Nor could I last time I looked, not even on my own HDD. Must be somewhere :)

@ steliosm : The official view is don't poke anywhere outside $50-$7F and $C0-$FF except any particular SFR's Rev-Ed say are safe to use.

For the rest, it's probably easier to say what not to poke ( peeking should always be okay ).

PORT, TRIS and GPIO may cause problems in turning inputs to outputs if the output is pulled high or low externally and wants to go the other way internally; that's a short across the rails and the magic smoke will ready itself. If playing with these do it on a breadboard with nothing connected to the I/O or via R's ( 330R up, 1K is common ).

Poking some of the peripheral control registers ( ADC, I2C, UART, Timer Control ) may also reconfigure I/O, different PICAXE/PICmicros behave differently. Switching to inputs isn't a problem, but they will go back to output on reset or if the PICAXE decides it wants to do something.

One never knows when the PICAXE will walk all over what you're trying to do. Timers, PWM and peripherals are probably okay providing you steer clear of any basic commands in a PICAXE which would use a timer or the peripheral. SERIN/SEROUT don't use timers.

Trying to use FSR to peek or poke anywhere in SFR ( using INDF ) is fruitless because the Firmware definitely uses both and likely write over it almost immediately.

You cannot get at the Eeprom/Flash access registers because they are in a different SFR bank, and FSR/INDF don't work, so you can't do any 'serious cracking' that way :)

Poking PICmicro interrupt bits will likely cause problems, but shouldn't be catastrophic. Likewise altering any SFR (Ram ) the Firmware uses ($30-$4F,$A0-$BF) can cause the Firmware to go off in some weird way. The worst which can happen is that the PICAXE could potentially erase itself. That's unlikley, but you have to be prepared for the worst.
 

steliosm

Senior Member
I see. I better back off from SFR for the moment. No need to waste my 08m :)
On the other hand, TIMER1 seems to be safe.
Thanks everyone. Worst case scenario I'll try to solder the DS2423 on a board.
 

hippy

Technical Support
Staff member
I note the smiley and wouldn't be too worried about causing damage or "wasting an 08M". In fact it's only the 28A and X-range which could potentially erase themselves, and even that's very, very unlikely. Take care that the I/O is interfaced safely for what you're doing and you should be okay - You'll never get a 'will be' because that's just the nature of the world :)
 
Top