PDA

View Full Version : Addressing ports via offset using lookup command



longpole001
- 31st October 2013, 06:46
HI GUYS ,

Hendrik some time ago showed a little trick where by port may be accessed via the lookup command using an offset

This works because most of the ports are usually memory mapped sequentially from the base port of portA.0

How ever if they are not can the other ports not in memory sequence be addressed in this manor , if so how ?

cheers

sheldon



example chip 16f1947 has ports A-G
portA.0 - portE.7 are arranged in memory

Memloc - Port - Lookup offset value from portA
00Ch port A.0-7 , 0-7
00Dh port B.0-7 . 8-15
00Eh Port C.0-7 , 16-23
00Fh Port D.0-7 , 24-31
010h Port E.0-7 , 32-39

28Ch Port F.0-7 , ???
28Dh Port G0.5 , ????


As such ports A- E can be used in lookup command like this



For T = 0 to 10 ' Select 10 ports for Pulses
LOOKUP T, [1,1,2,4,5,16,17,18,19,20,21],PortOffset ' Offsets from Port A to point to PortA & PortsC ( value of offset relates to Port bits in mem map of chip)
next T

HenrikOlsson
- 31st October 2013, 08:48
Since PortA is at 00Ch and PortF is at 28Ch the "distance" between them would be 28Ch - 00Ch = 280h or 640 in decimal.

Now, LOOKUP can only retrieve 8bit values from its table so it's not going to work. You'll have to use LOOKUP2.
Next possible issue is that the registers for Ports F and G are not in the same bank as those for Ports A-E so I'm not sure it's work....

/Henrik.

longpole001
- 31st October 2013, 09:30
well it compiles ,after making the change to lookup2 , and portoffset to a word variable

but ill have to wait for the pcbs to arrive to test it

cheers hendrick

Darrel Taylor
- 31st October 2013, 16:07
When you are using the "Bit Offset from Port" method, it is using "BIT Array" operations internally.

BIT array's have a limit of 256 elements.
Giving it a WORD sized offset will not work.

It will compile using a WORD, but it will only use the LowByte of that value.

longpole001
- 31st October 2013, 23:50
ok thanks darrel is there another coding method to solve this



T = 0 ' Ensure 0

For T = 0 to 10 ' Select IR LED for Pulses
LOOKUP2 T, [32,32,33,34,35,36,37,38,39,640,641],PortOffset ' Offsets from Port A to point to PortE(32- 39) & PortsF (640,641) ( value of offset relats to Port bits in mem map of chip)
Cycles = 0 ' Set to 0

if T = 0 then
Pulse_cnt = 38 ' add 1ms(adj) Header pause ( pulse on time ) before start of IR1 only so to show its the its the Start of the scan
else
Pulse_cnt = Pulsetmp ' restore value set from Volts get routin when changed by pulse T = 0
endif ' add 1ms(adj) Header pause ( pulse on time ) before start of IR1 only so to show its the its the Start of the scan

for Cycles = 1 to Pulse_cnt ' Set base pulse count cycles for IR lEDs ( 9 x 26uS) -17us = 217us
PORTA.0[PortOffset] = 1 ' Set IR LED High
pauseus 2 ' Remain on for 9uS (adj)
PORTA.0[PortOffset] = 0 ' Set IR LED Low
pauseus 9 ' remain off for 17uS ( adj)
next Cycles

pauseus Pulse_off ' Wait 300us (Adj 276) between pulse bursts and selecting next IR LED
Next T

pedja089
- 1st November 2013, 00:19
You can offset from PORTE or PORTF.
For example:

for Cycles = 1 to Pulse_cnt ' Set base pulse count cycles for IR lEDs ( 9 x 26uS) -17us = 217us
IF T<9 THEN
PORTE.0[PortOffset] = 1 ' Set IR LED High
pauseus 2 ' Remain on for 9uS (adj)
PORTE.0[PortOffset] = 0 ' Set IR LED Low
pauseus 9 ' remain off for 17uS ( adj)
ELSE
PORTF.0[PortOffset] = 1 ' Set IR LED High
pauseus 2 ' Remain on for 9uS (adj)
PORTF.0[PortOffset] = 0 ' Set IR LED Low
pauseus 9 ' remain off for 17uS ( adj)
ENDIF
next Cycles
And you need 2 lookup tables, one for PORTE another for PORTF.

Darrel Taylor
- 1st November 2013, 00:32
Treat them as if all the ports were contiguous.

A = 0-7
B = 8-15
C = 16-23
D = 24-31
E = 32-39
F = 40-47
G = 48-55

Then if the offset is greater than 39 ... change the port that it offsets from, and subtract 40 from the offset.


IF PortOffset < 40 THEN
PORTA.0(PortOffset) = 1
ELSE
PORTF.0(PortOffset-40) = 1
ENDIF

longpole001
- 1st November 2013, 01:08
thanks guys ,
darrel i did not think to treat them as contiguous when they are not , but by changing the start port solves that issue

the extra if then ,else commands , may cause some delays in the timing ill have to see the output it creates to check it

cheers sheldon

Darrel Taylor
- 1st November 2013, 01:29
the extra if then ,else commands , may cause some delays in the timing ill have to see the output it creates to check it
Ha! That's funny. :)

By using a PORT offset to begin with, it's doing "Array" operations that will take more time than a simple BYTE comparison and subtraction.

The comparison takes 4 cycles if true, 5 if false.
The subtraction takes 4 cycles if >= 40.

The array operation takes ... 30 instruction cycles.

longpole001
- 1st November 2013, 03:26
if you can recommend a better way to do it , please show , as it worked not aware of better way when i started to do it

longpole001
- 1st November 2013, 03:50
because the on and off time is short , normally would need to do it in assembler , but my asm sucks and need to learn more for sure , even more so when multi ports have to be addressed , this seemed to work ok and is still likely to as you say its only a few more cycles , and i still have pauses in this routine anyway, which can be removed