PDA

View Full Version : Pins, ports and variables



Scampy
- 3rd April 2015, 21:43
It's probably something really obvious, but it's been a long day and I've had so much coffee I'm bouncing off the walls and can't get my head round why this won't work.

I have four pins defined thus


dht_data1 var PORTA.0 ' RH sensor connected to pin A0
dht_data2 var PORTA.1 ' RH sensor connected to pin A1
dht_data3 var PORTA.2 ' RH sensor connected to pin A2
dht_data4 var PORTA.3 ' RH sensor connected to pin A3


If I use the following (snippet of the full code)) it compiles fine



'TRISA.0 = 0 '
high dht_data1
low dht_data1 : pause 18' send 18ms low
high dht_data1 : pauseus 30 ' send 30us hi
'TRISA.0 = 0
PulsIn PORTA1, 1, dht


However if I use the following I get a "bad expression" error at the line HIGH dht_data(y)



for y =1 to 4
'TRISA.0 = 0 '
high dht_data(y)
low dht_data(y) : pause 18' send 18ms low
high dht_data(y) : pauseus 30 ' send 30us hi
'TRISA.0 = 0
PulsIn PORTA.y, 1, dht


Someone please put me out of my misery

Archangel
- 3rd April 2015, 22:15
Hi Malcom,
I messed with your code some & tried it on a 16F690
it compiles, dont know if it works though :D


@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
DEFINE OSC 4


DEFINE DEBUG_MODE 0 ' Debug sending True serial data
DEFINE DEBUG_REG_PORTA ' Debug Port = PortA as required by PICKIT2 serial Monitor
DEFINE DEBUG_BIT 0 ' Debug.bit = PortA.0
DEFINE DEBUG_BAUD 9600 ' Default baud rate = 9600
DEFINE DEBUGIN_REG PORTA' Debug Port = PortA as required by PICKIT2 serial Monitor
DEFINE DEBUGIN_BIT 1 ' Debugin bit PortA.1
DEFINE DEBUGIN_BAUD 9600' Default baud rate = 9600
DEFINE DEBUGIN_MODE 0 ' Debugin receiving data true = 0 inverted = 1

dht_data var bit[4]
dht_data0 var PORTc.0 ' RH sensor connected to pin A0
dht_data1 var PORTc.1 ' RH sensor connected to pin A1
dht_data2 var PORTc.2 ' RH sensor connected to pin A2
dht_data3 var PORTc.3 ' RH sensor connected to pin A3
y var byte
dht var byte

for y =0 to 3
'TRISc.0 = 0 '
high dht_data[y]
low dht_data[y] : pause 180 ' send 18ms low
high dht_data[y] : pauseus 300 ' send 30us hi
TRISc = %00001111
PulsIn PORTA[y], 1, dht
debug dht
next y

Scampy
- 3rd April 2015, 23:24
Cheers,

I changed the port ref to match the hardware i'm using and it compiles... thanks

Archangel
- 3rd April 2015, 23:31
Let me know if it works . . .

HenrikOlsson
- 4th April 2015, 10:05
Hi,
It doesn't work like that - any of it I'm afraid.

First Malcolms example,
When you declare an alias to a variable or register, like dht_data1 var PORTA.0 the dht_data1 part of it is just a name for you and me to remember. For the compiler it gets converted to an adress in memory which in this case will be the exact same adress as PortA.0 has.

This means that you can not do dht_data(y) because there is no variable called dht_data, the variable is called dht_data1.

So, HIGH dht_data1 works because it's exactly equivalent to HIGH PortA.0 - no difference.

But HIGH dht_data(y) doesn't work, (and doesn't compile) because there is no variable called dht_data. If you did dht_data var PortA.0 then doing HIGH dht_data(y) would set PortA.0+y....I think....which possibly could work in this particular case since the bits are consecutive (in a row) on PortA.


When you declare an array, which is what you're doing with dht_data VAR bit[4] the compiler reserves memory, in RAM, for 4 consecutive bits.

You can then, if you want, assign an alias (which is just a different name) TO these individual bits like Bit_0_of_dht_data_bit_array VAR dht_data[0]. This means that reading/writing Bit_0_of_dht_data_bit_array accesses the same memory location as reading/Writing dht_data[0]. The key here is that it's the very same bit in RAM that is accessed in both cases. You can not have an array of bits in ram and then try to alias any of those bit to another bit (like a port pin) because then it isn't pointing at the same location any more.

In Archangels example strange things will happen because HIGH/LOW is designed to work on PORT registers only and relies on a fixed "offset" between the PORT register and the TRIS register (since HIGH/LOW clears the TRIS bit). Using HIGH/LOW on a variable in RAM will likely corrupt other parts of the memory since it will then (when trying to clear the TRIS bit) clear another bit - which you don't want.

Malcolm, you're still on PBP2.6 aren't you? That's fine but if download the PBP3 manual there's an updated section (7.6) that explains how arrays and offsets work.

/Henrik.

richard
- 4th April 2015, 10:59
this is what you want , post#3
http://www.picbasic.co.uk/forum/showthread.php?t=9749

Art
- 4th April 2015, 15:57
They are trying to solve the problem thinking and coding in C.

So the problem appears to be addressing bits as an array as you would when making a Knightrider LED bar scanner,
except that in application you don’t want to change the state of the bits other than you’re interested in.

To address a bit is easy, just multiply the step value by 2 each time (or shift it once) instead of incrementing it 0-7,
We couldn't begin at zero and begin multiplying, but fortunately address the first bit with a 1 :D


index var byte
trisb = 0

index = 1
WHILE index > 0
portb = index
index = index << 1
WEND


Unless I’m mistaken the port bits were cycled real fast with no delays, repeats etc.
But the problem is still that if port.3 happened to be initially set by something, it would now be cleared.




trisb = 0
index var byte
portbshadow var byte

index = 1
WHILE index > 0
portbshadow = portb
portbshadow = portbshadow^index
portb = portbshadow
index = index << 1
WEND


This should set port bits in sequence, leaving the previous bit set as it runs, and leaving all port bits set at the end,
but that’s because the loop has no conditionals in it. It’s not a bad idea to shadow the port with a RAM byte anyway if you have the time.
AFAIK when the pic sets any single port bit, it does a read of the whole port, then sets the bit in RAM, and writes the whole port byte back anyway.
C isn’t real good for bit manipulation and this sort of thing always has to be done.

Art
- 4th April 2015, 16:49
ps if you want to address pins as 0-7 then to turn on port b.3 without messing up the rest of the port:


bitindex = 1
bitindex = bitindex << 3
portbshadow = portb
portb = portshadow^index


It could be tighter, but I’m not sure what you can directly operate on a port value,
or if you can shift a constant to get the right result in bitindex.



bitindex = 1 << 3
portb = portb^index