PDA

View Full Version : Same code in different Pins



Josuetas
- 26th March 2007, 20:30
Hi!, i am currently developing an application with one wire devices, i have for convenience connected several DS1993 devices to different I/O pins (even from different ports), Is there a way of executing the same code on different pins?.

Can i make this code reusable (something like a funtion gosub) for different pins?

PIN var Portb.0
owout PIN, 1, ["data here"]

how can i change the I/O pin or the var PIN?

Thanks in advance!

skimask
- 26th March 2007, 21:09
Hi!, i am currently developing an application with one wire devices, i have for convenience connected several DS1993 devices to different I/O pins (even from different ports), Is there a way of executing the same code on different pins?.

Can i make this code reusable (something like a funtion gosub) for different pins?

PIN var Portb.0
owout PIN, 1, ["data here"]

how can i change the I/O pin or the var PIN?

Thanks in advance!

It's not what you want, but:

pin var byte
pin1 var portb.0
pin2 var portb.1
pin3 var portb.2...etc.etc.etc...

pin = 2
gosub outputstuff

outputstuff:
select case pin
case 1
owout pin1,1,["data here"]
case 2
owout pin2,1,["data here"]
case 3
owout pin3,1,["data here"]
end select
return

Josuetas
- 27th March 2007, 17:26
That is a simple choice, but the code i posted is just an example, my real code could use up to 800 words, an maybe the code space isnīt enough.

Come on there must be some way, I just donīt understand it, it seems to be in ASM. I really dont know.


SAME QUESTION

How can you change the definition of a variable in the middle of the execution???

PIN var PORTB.0


and later

PIN var PORTB.1


Thanks

Darrel Taylor
- 27th March 2007, 18:19
Assuming you have them on PORTB as shown. Just use Pin Numbers.

PIN VAR BYTE

for PIN = 0 to 7
owout PIN, 1, ["data here"]
next PIN

Numbers 0-7 are usually PORTB.0 thru PORTB.7, 8-15 can be PORTC, but it depends on the chip you are using.

skimask
- 27th March 2007, 18:26
Assuming you have them on PORTB as shown. Just use Pin Numbers.

PIN VAR BYTE

for PIN = 0 to 7
owout PIN, 1, ["data here"]
next PIN

Numbers 0-7 are usually PORTB.0 thru PORTB.7, 8-15 can be PORTC, but it depends on the chip you are using.

I've got no idea how this came to me...magic I suppose...
How about a variable that's 'locked' into a certain memory location (porta in this case), and it's set up as an array.
Since the ports are usually in sequential order in the memory map, it seems to me like a person should be able to access those bits as bits of a variable, like you would any other ram variable.
i.e.
PIN var byte[4] $F80 system '5 bytes to handle porta, portb, portc, portd, porte, in the case of a PIC18F4620

then you'd access the pins by pin.0[index]...

Wouldn't that work?

Darrel Taylor
- 27th March 2007, 18:45
Nope, won't work Skimask.

For instance, with this statement...

owout pin.0[index], 1, ["data here"]

PBP will do an Array Out from the indexed pin, then use that result as the "PIN number" which will be either a 0 or 1. So it will always use either PORTB.0 if the pin is low, or PORTB.1 if the Pin is high.
<br>

skimask
- 27th March 2007, 18:48
Nope, won't work.

For instance, with this statement...

owout pin.0[index], 1, ["data here"]

PBP will do an Array Out from the indexed pin, then use that result as the "PIN number" which will be either a 0 or 1. So it will always use either PORTB.0 if the pin is low, or PORTB.1 if the Pin is high.
<br>

---deleted---I don't follow you at the moment...

I got what you saying... pin.0[index] is actually a bit variable...0 or 1 correspoonding to port B
but if you say it's not going to work...then chances are good that it's not going to work...

Darrel Taylor
- 27th March 2007, 19:05
... pin.0[index] is actually a bit variable...0 or 1 correspoonding to port B

This is another one of those examples where arrays act differently depending on whether a Constant or a Variable is used as the index.

Using the same statement...

owout pin.0[index], 1, ["data here"]

If index is a Constant, it does what you thought, and will use the index to select the Pin as an offset from PORTA.0. So 8 would be PORTB.0. But then, you can't change it at run-time.

IF index is a variable, then it makes it an Array operation that will read the value of the indexed Pin (0 or 1), that value then becomes the "PIN Number".

When a statement works 2 different ways like that it's hard to grasp sometimes.
Not sure why meLabs did things that way.
<br>

skimask
- 27th March 2007, 19:29
This is another one of those examples where arrays act differently depending on whether a Constant or a Variable is used as the index.
Using the same statement...
owout pin.0[index], 1, ["data here"]
If index is a Constant, it does what you thought, and will use the index to select the Pin as an offset from PORTA.0. So 8 would be PORTB.0. But then, you can't change it at run-time.
IF index is a variable, then it makes it an Array operation that will read the value of the indexed Pin (0 or 1), that value then becomes the "PIN Number".
When a statement works 2 different ways like that it's hard to grasp sometimes.
Not sure why meLabs did things that way.
<br>

Might be the difference between a $250 compiler and a $2,500 compiler.
But I got what you were getting at.

I think the original post'ers only option is to do the SELECT CASE thing, combine all OWOUT's into one place, use a generic "data here" string type array variable and go with it.

Darrel Taylor
- 27th March 2007, 19:33
I think the original post'ers only option is to do the SELECT CASE thing,

Well, I think Josuetas' best option can be found in Post #4
<br>

skimask
- 27th March 2007, 19:41
Well, I think Josuetas' best option can be found in Post #4
<br>

True, but what if the pins are on PortA, or D, or E, or F, or G, or H, or J :)

Darrel Taylor
- 27th March 2007, 19:51
True, but what if the pins are on PortA, or D, or E, or F, or G, or H, or J

Then you would change the PORTL and or PORTH assignments in the .bas file for the chip you are using.

PORTL and PORTH determine which ports are used for "Pin Numbers".
PORTL is 0-7
PORTH is 8-15
<br>

skimask
- 27th March 2007, 20:11
Then you would change the PORTL and or PORTH assignments in the .bas file for the chip you are using.

PORTL and PORTH determine which ports are used for "Pin Numbers".
PORTL is 0-7
PORTH is 8-15
<br>

Are you talking about the .bas file in the PBP directory?
I would've thought the compiler would go nuts if you changed anything in those .bas files... I know you can change the .inc files....hmm... interesting thoughts brewing in my head now...
Thanks a lot...now I got more crap to think about! :)

Darrel Taylor
- 27th March 2007, 20:23
Yes, the .bas file in the PBP folder. ie. 16F877.BAS

And, just like you do with the Config lines in the .inc file.
You can comment out the PORTL/H and TRISL/H lines, which allows you to define them in your main program.

Then you can...

PORTL VAR PORTA
TRISL VAR TRISA
PORTH VAR PORTD
TRISH VAR TRISD

Which puts 0-7 on PORTA, and 8-15 on PORTD.

Or to whichever ports you wanted.

keithdoxey
- 27th March 2007, 20:34
Then you would change the PORTL and or PORTH assignments in the .bas file for the chip you are using.

PORTL and PORTH determine which ports are used for "Pin Numbers".
PORTL is 0-7
PORTH is 8-15
<br>

Hi Darrel,

I have looked in the .bas file for the 18F452 and located the following code



PORTL VAR PORTB
PORTH VAR PORTC
TRISL VAR TRISB
TRISH VAR TRISC


Would I be correct in assuming that you also have to "adjust" the TRISL and TRISH aliases as well?

I take it that the ports dont have to be consecutive so that I could put




PORTL VAR PORTB
PORTH VAR PORTD
TRISL VAR TRISB
TRISH VAR TRISD


Which would give me 0-7 = PortB.0-PortB.7 and 8-15 = PortD.0-PortD.7

If so that greatly simplifies something I am trying to impliment. The reason I want to change PORTH from C to D is that I need to use the USART which is on C6 and C7 so that would only give me 14 useable pins.


DOH !!!!

Thatll teach me not to make sure I have a newly refreshed view of a thread before I post a reply !!!!

Darrel Taylor
- 27th March 2007, 21:27
I hate when that happens!

At least everything you said was correct.
Could have been worse. :)

Hey Josuetas,
Still with us?
<br>

Josuetas
- 28th March 2007, 00:59
Thanks Darrel, yes i am here.... i wasnt but now i am....

Well that is great that at least helps me reduce everything, bad thing is that i already made the PCB, i should get it by thursday... :P

God thing is i Used Portb(ALL) and PortC(2Bits) and portD (2 bits), and PORTA (4bits) 16 1Wire devices.

So i Guess by now i will use Darrel`s recomendation for all portb and change the .bas to use portb A, and maybe handle the rest of the bits with select case :'(.

Darrel by the way.. How then do you use DEFINES to work with your include files? (i dont relly know if yours :p), does this mean that once the defined is set one is supposed to stay with it and not change it?

Thanks to all for your replies, I am still hoping something better could be done

Bye

Darrel Taylor
- 28th March 2007, 01:35
Oh good, there you are.
Sometimes I go off on a tangent when there's no more input to the original question.

And there's always another way to skin a porcupine. (sorry, but dogs and cats have enough problems right now with the rat poison and all. Time to skin porcupines) :eek:

But since the pins are all scattered across ports, I need some more info.
Can you list the pins used?
What data, "Exactly", are you sending. Probably not a string like the example.
Using 16F or 18F?
(yes, it's assembly language time)

Josuetas
- 29th March 2007, 04:45
Well this device is some kind of 16 ports 1Wire to Serial HUB, it sends serial
data to a pc with the info requested by the PC, maybe write the pages of a 1wire device (0-15 pages), read de Identification from a 1Wire, read some temperatures, you should be able to do anything to any device on the port.

Why?: well in this development I am using up to 16 i-buttons, actually they where read directly through the PC. And i am in Colombia, it is not easy at all to find DS parts, even more it is really expensive.

What kind of info? well mostly OW commands with data bytes, since each page is 32 bytes it would be interesting to receive and send everything in an array 32 bytes long. Exactly?... well $F0, $cc, some bytes... typical protocol bytes for 1wire

Pins used: PORTB (ALL), portA (0-3... i hate pin4 :p), portC(2,3), portd (0,1)

Thats all.... its simpler than it seems i guess.... i might do other simple tasks, but iīm sure i dont need help with that.

I really want to learn this, i m sure you have a great tip behind this request.

Thanks Again

skimask
- 29th March 2007, 05:05
Well this device is some kind of 16 ports 1Wire to Serial HUB, it sends serial
data to a pc with the info requested by the PC, maybe write the pages of a 1wire device (0-15 pages), read de Identification from a 1Wire, read some temperatures, you should be able to do anything to any device on the port.

Why?: well in this development I am using up to 16 i-buttons, actually they where read directly through the PC. And i am in Colombia, it is not easy at all to find DS parts, even more it is really expensive.

What kind of info? well mostly OW commands with data bytes, since each page is 32 bytes it would be interesting to receive and send everything in an array 32 bytes long. Exactly?... well $F0, $cc, some bytes... typical protocol bytes for 1wire

Pins used: PORTB (ALL), portA (0-3... i hate pin4 :p), portC(2,3), portd (0,1)

Thats all.... its simpler than it seems i guess.... i might do other simple tasks, but iīm sure i dont need help with that.

I really want to learn this, i m sure you have a great tip behind this request.

Thanks Again

How about using a 74138 (3-8 decoder) or 74154 (4-16 decoder), controlled by either 3 or 4 address lines, to apply a ground to the O.W. device desired (thereby powering it up) and using the same one-wire read/write pin in common to all of them? Surely setting porta.0-porta.3 for an address takes a lot less code space than multiple types of OW commands...

Might not be such a good idea since it'll only save you 3 pins out of your 'Pins used:' list.
And heck, I don't even know if it'll work...

Darrel Taylor
- 29th March 2007, 06:30
I really want to learn this, i m sure you have a great tip behind this request.

Well of course I do. :cool:
And it's a scary one. Yet oh so cool.

But to make it work, I still need to know...

16F or 18F ?
<br>

Archangel
- 29th March 2007, 06:37
And there's always another way to skin a porcupine. (sorry, but dogs and cats have enough problems right now with the rat poison and all. Time to skin porcupines) :eek:



Naw, porcupines need love too . . . let's skin Bureaucrats, nobody loves them . . . anyway this post gets filed into my bookmarks

Darrel Taylor
- 31st March 2007, 00:42
Joe,

Ok, but you can Hug the porcupines. :eek:
Unfortunately, the Bureaucrats have already made sure it's illegal to skin them.
And they're usually followed by bodyguards. :)

Josuetas,

I know things are slow in Columbia, but come on, get with the program.
Simple question.
16F or 18F ?????
<br>

Josuetas
- 2nd April 2007, 00:53
Hello, i am back from a small holiday.

Well i guess 16f877 is a solid choice.

I have been working in the code already, will post if something is wrong, but by now i guess everything is quite simple.

Anyway, i guess that if i really intend to find something new here, it would be interesting to discuss both 16 and 18 options, maybe for some other project the 18F would be required.

I promise to stay more tuned to this thread now :D

by the Way is not Columbia, i am in Colombia ;). And things arent THAT slow here....

Josuetas
- 2nd April 2007, 01:01
How about using a 74138 (3-8 decoder) or 74154 (4-16 decoder), controlled by either 3 or 4 address lines, to apply a ground to the O.W. device desired (thereby powering it up) and using the same one-wire read/write pin in common to all of them? Surely setting porta.0-porta.3 for an address takes a lot less code space than multiple types of OW commands...

Might not be such a good idea since it'll only save you 3 pins out of your 'Pins used:' list.
And heck, I don't even know if it'll work...

This seems like an idea but it also appeals to me like a waste since i have the micro and i can aviod using more ics.

What is really interesting and almost a need is to discuss if it is posible to use several OW devices conected to the same wire with the OWOUT OWIN commands, i havent really got into the subject but.... how do you assign addreses(ids) to each device conected to the line? I would have to read the document about the OW protocol by maxim, it dont seems to be simple at all.

Darrel Taylor
- 2nd April 2007, 01:47
Colombia!
Sorry for the misspelling, but I'm used to hearing a RED or GOLD after it. So it seemed different. :eek:

And since I've been sitting on this answer for 4 days now, ...Not "THAT slow" is still slower than UPS ground. :)
So here goes...

As a reminder ...
And it's a scary one. Yet oh so cool.
<hr>
So here's the SCaRy part ...
I'm going to ask you to modify a PBP macro file. AAAhhhhh!!!!

Ohhh, stop screaming, It's easy!

And, since it's easier to Do, than to explain, I'll start with the "HOW TO". Then comes the explanation.

<hr>
In your PBP folder, there is a file named PBPPIC14.MAC

WARNING! Before making any changes to this file, Make a backup copy first.
Don't blame me if it gets messed up and you have nothing to replace it with!

Now that the legal issues are over :)<hr>
Open the PBPPIC14.MAC file with NotePad.

Do a Search for OWPIN?W

You should see a section that looks like this...
OWPIN?T macro Regin, Bitin
BIT?R1 Regin, Bitin
endm
endmod

OWPIN?W macro Win
MOVE?WA Win
L?CALL PINR1
endm
PINR1_USED = 1
endmod

;************************************************* ***************
;* OWMODE?X : Macro - Assign One-wire mode, check for reset *


Comment out the OWPIN?W macro with semicolons, and replace it with a new routine.
It should look like this afterwards...(without the colors, of course)
Blue is the OLD, Red is the NEW.
OWPIN?T macro Regin, Bitin
BIT?R1 Regin, Bitin
endm
endmod

;OWPIN?W macro Win
; MOVE?WA Win
; L?CALL PINR1
; endm
;PINR1_USED = 1
; endmod

;-- changed for addressing any pin with a word variable --
;-- highbyte = Offset from PORTA, lowbyte = PIN --
OWPIN?W macro Win
MOVE?CB PORTA, RR1
MOVE?BA Win+1
CHK?RP RR1
addwf RR1, F
MOVE?BB Win, R4
L?CALL CONVBIT
MOVE?AB RM1
endm
CONVBIT_USED = 1
endmod

;************************************************* ***************
;* OWMODE?X : Macro - Assign One-wire mode, check for reset *


That's It! .. Well, almost.<hr>
Now the OWIN/OUT commands will accept a WORD variable that can address ANY pin on the chip.
The next part is to figure out what that WORD is.

You want the HighByte to be an Offset from PORTA. (0 is PORTA, 1 is PORTB, 2 is PORTC, etc.)
The LowByte of the word is the BIT number (0-7).

I'm sure there's a hundred ways to go about it, but here's one possibility.
Create an array of WORDs, with each element specifying a different PIN.


OWpins VAR WORD[16] ; assign pins for OneWire commands.
OWpins(0) = $0000 ; PORTA is 0, bit 0 ; Assignments can be in any order
OWpins(1) = $0002 ; bit 2 ; Shown sequentially here for clarity
OWpins(2) = $0100 ; PORTB is 1, bit 0
OWpins(3) = $0101 ; bit 1
OWpins(4) = $0102 ; bit 2
OWpins(5) = $0103 ; bit 3
OWpins(6) = $0104 ; bit 4
OWpins(7) = $0105 ; bit 5
OWpins(8) = $0106 ; bit 6
OWpins(9) = $0107 ; bit 7
...
OWpins(15) = $0307 ; PORTD is 3, bit 7


Which then allows you to do the original request ...
<font color="#000000"><b>PIN </b><font color="#008000"><b>VAR BYTE

FOR </b></font><b>PIN </b>= <b>0 </b><font color="#008000"><b>TO </b></font><b>15
</b><font color="#008000"><b>OWOUT </b></font><b>OWpins</b>(<b>PIN</b>), <b>1</b>, [<font color="#FF0000">&quot;data here&quot;</font>]
<font color="#008000"><b>NEXT </b></font><b>PIN</b>

That really is IT.
<hr>
The Explanation.

When compiling.., PBP chooses the correct macro to use depending on what type of variable you pass to the statement.
If you pass a BYTE variable as the PIN, it assumes it's a "PIN Number" (0-15) and uses the macro OWPIN?B

If you pass a PORTB.0 type, it hard codes the pin and bit with the OWPIN?T macro.

These choices are made by the PBP(W).EXE compiler, and we have no way to change that.
However, the actual macro's that are called, are "Open Source", so we are free to change the way the commands behave, even though the compiler doesn't know about it.

Now it's probably not a good idea to go around changing the way things work on a general basis, but sometimes it can make a big difference.

And in the case of OWPIN? there's a macro that really should never be used. It's OWPIN?W
While it allows you to use a WORD variable for the "PIN Number", it's value is limited to 0-15, so a word variable doesn't make a whole lot of sense.

Since it's already built in to the compiler, and it'll never be used. If we re-write the macro that goes with it, we can use it to select any pin we want, and still have OWIN/OUT work exactly the same way it did before.

*** I was going to go further into the macros here, but, in case you already understand, I'll wait. **

The only problem, is that on the next Upgrade to PBP, any changes will be overwritten.
So you'll have to remember what you've changed. I usually make a .txt file in the same folder as the project, and make notes on any changes required for that program.
Or, like Joe S. did, you can just bookmark this thread for future reference.

<HR>
Now then, I can see the wheels turning in a couple people's minds. And you're right!

The same concept can work for any command that uses "PIN Numbers".
SERIN/OUT, PULSIN/OUT, FREQOUT, DTMF, BUTTON, ... ok, well just about all of them.
You simply need to change the appropriate macro for the specific command.

If you have PINs scattered all over the place, it's an easy way to address ANY of them in a sequential (or random) manor.
But, if your PINs can fit into 2 ports, the PORTL/H approach shown in the previous posts is preferred.

skimask
- 2nd April 2007, 04:01
And since I've been sitting on this answer for 4 days now, ...Not "THAT slow" is still slower than UPS ground. :)
So here goes...


Brilliant! Absolutely BRILLIANT!
You really should fire that off to MeLabs...
Maybe end up making a SEROUT3/OWOUT2 or something along those lines.

Darrel Taylor
- 2nd April 2007, 05:35
Woohoo!

Does that mean I can have a Guinness now?

http://www.youtube.com/watch?v=2WqO0Q_zNKA

http://www.youtube.com/watch?v=iWqGLVaITsk

Watch this one last.
http://www.youtube.com/watch?v=1t4sdgvy-pk
<br>

Josuetas
- 2nd April 2007, 23:25
Oh my God this is awesome, i am going to work on it right now!!! will post as soon as i am finished.

And ...

BRILLIANT!.... by the way. jeje

Josuetas
- 3rd April 2007, 01:56
I have already wrote and read from each device with this method.

Darrel, Why would i go back to the previous version of the Macro? this is a real question, do you think of any reason?

And since life is a Learning HighWay... can you explain a bit of the asm code and can you lead me to do it on 18F devices?

Thanks Again



________
DJC

Darrel Taylor
- 3rd April 2007, 22:13
I have already wrote and read from each device with this method.

Darrel, Why would i go back to the previous version of the Macro? this is a real question, do you think of any reason?

Great! Glad you got it working. :)

There's really no reason at all to go back.
As mentioned before, since the "PIN Numbers" are limited to 0-15, there should never be a reason to have the OWPIN?W macro the way it was before.
Even if you must use a word variable for some reason or another, you can just use the .LowByte modifier and PBP will use the OWPIN?B macro instead.


And since life is a Learning HighWay... can you explain a bit of the asm code and can you lead me to do it on 18F devices?

OK, well I should have done the 18F version at the same time I did the 16F. The differences in the chips, makes things different for these routines too. It would be too confusing the way it was, so I've changed the way my last example works so that they will work the same for both 16F and 18F's.

Up in Post #26, I've modified the macro to use an Offset from PORTA, instead of just the Address of PORTx.
This way, the actual usage of the WORD variables will be the same for both chips.

And here's the macro for the 18F's. This one goes in the PBPPIC18.MAC file.
;-- changed for addressing any pin with a word variable --
;-- highbyte = Offset from PORTA, lowbyte = PIN --
OWPIN?W macro Win
MOVE?CB high(PORTA), RS1
MOVE?CB low(PORTA), RR1
MOVE?BA Win+1
CHK?RP RR1
addwf RR1, F
MOVE?BB Win, R4
L?CALL CONVBIT
MOVE?AB RM1
endm
CONVBIT_USED = 1
endmod

The usage will be the same as in Post #26 for the 16F's. (please go back and review it again)

I'm still trying to figure out how I can explain the macro's. :o
<br>

Josuetas
- 4th April 2007, 02:40
My head is telling me somehow: "You donīt really wanna know":D
Man it seems thought..

I will hold my breath and just go with my happy new versions of the OWPIN? macro.

Gracias otra vez