Bi-Directional I/O on PICAXE-18X

hippy

Technical Support
Staff member
From provisional experiments it seems that it's possible to control the direction of PORTB, the standard Output Pins, on the 18X.

This allows an 18X to have up to 13 inputs and/or up to 8 bi-directional I/O lines.

It also opens the door for high-speed SPI receive and high-speed serial input. Timer1 should be configurable as a counter driven by an external pulse, and the 32kHz LP Osc may even be usable for time keeping. It should also be possible to us RB0(INT) as an edge-triggered latch to detect short pulses which polling or SETINT would miss, and RB4-RB7 can be used to flag input pin changes.

The 18X continually updates TRISB so poking that does no good, but it appears there's a shadow register at $AE(174) which is used to set TRISB. Poking $AE consequently sets TRISB.

There are a few caveats -

1) Don't come crying to me or Rev-Ed if your PICAXE catches fire or is destroyed etc.

2) Not exhaustively tested. Tested on Firmware 8.5 but may not work on others. There may be side-effects I haven't noticed.

3) HIGH, LOW, etc commands do not automatically make the applicable pin an output; $AE must be poked to change the pin direction.

4) I2CSLAVE and other commands which affect PORTB will likely overwrite and change $AE.

5) You <b>will </b> need a 330R or higher ( 1K or 10K is probably a good bet ) current limiting resistor in series with each input to prevent damage to the PICAXE.

6) Poke a 0 bit for Output, a 1 bit for Input ( Standard TRISB values, inverse of 'LET DIRSC=' ).

Example program ...<code><pre><font size=2 face='Courier'> POKE $AE,%11111111 ' All Inputs
DO
PEEK $06,b0 ' Read PORTB
SERTXD(#bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,CR,LF)
PAUSE 500
LOOP </font></pre></code>
 

ljg

New Member
Nice find. I'm not sure I'll actually ever use this, but it's nice to know the chip can be tweaked.
 

hippy

Technical Support
Staff member
BarryP : No, that's not something I've tried yet but will. Thanks for the reminder. It worked for SPI in, so it should also work for AUSART.
 

BarryP

Senior Member
I'm about to give it go..
I have some Hardware Currently Running On a proprietry 485 BUS @ 9600Baud.
It's an 8Byte stream with about 20..30mSecs between Packets.
It's been MOSTLY reliable over the last 8 Months Using Serin grabbing 8 bytes at time.
It Falls to pieces when the Packets change to 32 or 256 Bytes ...
will be interesting to see If the 2 Byte Buffer is enough time to save the packets ..
Suppose I could just Calculate it ...
BUT , While going thru the f88 Data Sheet ,I Had a Thought ...
mmmm I Said to myself, Hows About Connecting Up a 16Mhz Xtal to the little beastie.

Anyone Tried This YET ??
 

Dippy

Moderator
Barry, how are you setting the registers?

I've only done this with PICs so would be interested to know how you are reading the buffer.
 

BarryP

Senior Member
ha .. Wouldn't have a Clue .. yet
As Mentioned In My Previous Post ..
I've Only JUST dragged Out the data Sheets &amp; am currently changing the Hardware to suit the Experiment.
I'll Be Back :}
 

Brietech

Senior Member
I'm curious about overclocking the 18X to 16mhz with an external clock (or up to 20 mhz, but i can't think of a way to do serial at that speed, as 5x is a weird multiplier), as then it would be able to do something like 8000 instructions/sec, which is startin' to get really fast for something so easy to program! Anyone brave enough to try?
 

hippy

Technical Support
Staff member
In theory, it should be possible to re-burn the config word ( ensuring code protect is kept as it is ) without erasing the code.

In reality, I've had no success at all on an 08, but that might just be the programmer I used. The programmer won't even recognise that chip any more.
 

Technical

Technical Support
Staff member
This wouldn't work as you can only change configuration bits that are a 1 to a 0 without an erase, and that wouldnn't allow you to change to a high speed external oscillator fuse setting (XT or HS).

You are more likely just to end up with a chip that doesn't work!
 

ljg

New Member
<i>hippy, you said-

It should also be possible to us RB0(INT) as an edge-triggered latch to detect short pulses which polling or SETINT would miss, and RB4-RB7 can be used to flag input pin changes. </i>

I didn't really catch this the first time around.

<b> This </b> sounds cool! can you work up a quick example as to how this would be coded? In the past, I've had to rig up hardware to stretch pules enough to give a Picaxe time to catch them, sometimes distorting the timing sequence of events. this might be better
 

hippy

Technical Support
Staff member
Added to the list which is now ...

1) Multi-Tasking Code Template Generator ( nearly done )
2) Port B Interrupt detect
3) Port B Interrupt on Change detect
4) AUSART Receive
5) Operation as an I2C Slave device ( the hard one )

Is there anything else I've forgotten ?

Despite illusions to the contrary, I do sleep and do have a life away from my PC and PICAXE, so it may be a day or two. And it always depends on what's on TV - Usually not a lot though !
 

hippy

Technical Support
Staff member
Interrupt on input to 'Output Pin 0' and interrupt on change of input to 'Output Pins 4 through 7' work. These aren't interrupts per se on the PICAXE ( they don't - and won't - call the 'interrupt:' routine ), but set flags to indicate the event has occurred which can be checked by normal PICAXE code.

I'm not sure how the interrupt on change is interacted with by the PICAXE Firmware updating its outputs regularly, but cannot see any major problems. By reading PORTB, one then knows how the signal changed when interrupt occurs by reference to the previous value read.

Don't connect any signal to a PICAXE Output Pin used as an input unless it is passed through a suitable current limiting rsistor.

http://homepage.ntlworld.com/the.happy.hippy/picaxe/rb0int.zip
 

hippy

Technical Support
Staff member
BarryP : Now tested AUSART receive on 'Output pin 2', and I can report it worked fine. Haven't tested 9-bit comms mode but cannot see any reason it wouldn't work.

This gives a solution, for 18X ( and almost certainly 28X/40X ) users, who want to have single/dual byte non-blocking serial transfers. An 18X can of course receive data this way from any PICAXE ( 08 upwards ) if they send using Txxxx baud rates.

http://homepage.ntlworld.com/the.happy.hippy/picaxe/uartecho.zip
 

hippy

Technical Support
Staff member
And while I remember ... Weak Pull-Ups on PORTB Input Pins work as well, although resistor-less button input isn't possible because a current limiting R is needed to stop the initial 'Output' from shorting through a held button to 0V.
 

BarryP

Senior Member
Howdy Once Again Hippy.
Perhaps I should posted a bit earlier ..
I tried the Idea with my Hardware &amp; was somewhat disapointed with the results.
There doesn't appear to be enough time to process &amp; save a stream of data @9600 Baud,
With the OSC @ 8M.
Perhaps with a few Millisecs between Bytes , It May work for me.
I Also noted that with a stream of data present on RB2 , With Uart enabled &amp; CREN Set, My Normal RX Comms Routine Failed.
I Haven't tracked down the reason Yet.
It's a Fairly busy Program with Lots of I2C
&amp; some serial code for a DS2480 with 4 Temps On It.
I'm Not writing it off Yet , But Need To spend more time on it.

Just Thought I Might Add a word of thanks to Rev-Ed for adding the Compiler Directives functionality.
It Makes a Big Difference !!!

Edited by - barryp on 13/01/2007 08:32:02
 

hippy

Technical Support
Staff member
I guess usable doesn't necessarily mean useful in some cases. It's always hard taking in continuous streams of serial if there's no access to internal interrupts and no buffering.

At 9600 baud, back-to-back data turns up about every 1mS, which is probably no more than eight PICAXE commands at 8MHz, so it would get hard unless gaps can be added to the data stream.
 

ljg

New Member
hippy-

I noticed today that an RB6 input now allows access to Timer1 as an external event counter. Looks like I'll be using your latest find after all! (odometry)

Might access to Timer1 also be a path out of the dreaded SERIN lock up? (just thought I'd add to your list.
 

BarryP

Senior Member
I've been Reading about the Recieve Method.
It appears to me that there is no need to reset the Uart if there is a Framing error.
Also , When there an Overrun , There are 2 Bytes still to retrieve.
I'm Modifing yet Another Project To Try This Out.
The Current Method Of Comms In The Other Project is Bit-Bashing 600Baud.
ANY Improvement will Be a Bonus.

Here Is My Untested Rx Routine.
A Test for Frame Errors Is Done In The ProcessByte Sub.

;***************************************************************************************
CHECK_UART_RX:
;***************************************************************************************
Poke mBitVar0,BitVar0
Poke mTmpVar,BitVar1

DoUartCheck:
PEEK PIR1, BitVar1
IF RCIF_BIT = 0 THEN CHECK_UART_RX_Leave
PEEK RCSTA, BitVar1
IF OERR_BIT = 1 THEN Get2BytesAndReset
' IF FERR_BIT = 1 THEN IgnoreThisByte
PEEK RCREG,BitVar0
Gosub ProcessByte
goto DoUartCheck

Get2BytesAndReset:
PEEK RCREG,BitVar0
PEEK RCSTA, Y
PEEK RCREG, X
POKE RCSTA, SPEN
POKE RCSTA, RCSTA_INIT
Gosub ProcessByte
BitVar0 = X
BitVar1 = Y
Gosub ProcessByte
goto DoUartCheck

CHECK_UART_RX_Leave:
Peek mBitVar0,BitVar0
Peek mTmpVar,BitVar1
RETURN
 

hippy

Technical Support
Staff member
Larry : Interesting thought on Timer 1 rescuing a SERIN which is stuck waiting for data not to arrive. The best I can think of is to use the Timer 1 overflow to set / clear an output line which can either reset the PICAXE or be diode mixed with the serial stream to fake a byte ( $00 ) being received.

BarryP : I have to admit that I am not that familiar with AUSART operation beyond what I've done, so I am very interested in seeing what you are discovering.
 
Top