PDA

View Full Version : Bitwise not working



Ioannis
- 18th October 2006, 11:25
I know it is silly but cannot see why is not working the bitwise function. The code is:

for i=240 to 250
temp=portb
portb=temp & i
pause 100
next i

Port B high nibble is input while the low nibble is output. I read the whole port and want to keep the upper since they are related to Interrupt on change. So on the lower I want to follow the counting of i.

The lower nibble always reads and presents as 0000 !

If anyone sees what I don't please reply. It drives me mad!

Ioannis

sayzer
- 18th October 2006, 12:07
Hi Ioannis,

Here I made it clear to see.
But, as you said, it should not provide 0000.



Ignore high nibble on Portb. PORTB is just an example here.
.
.
i=240 to 250 11110000 11110001 11110010 11110011 11110100 11110101 11110110 11110111 11111000 11111001 11111010
PORTB (example) 11110000 11110001 11110011 11110111 11111111 11111110 11111100 11111000 11111010 11110101 11111101
Temp=PORTB 11110000 11110001 11110011 11110111 11111111 11111110 11111100 11111000 11111010 11110101 11111101
PORTB=Temp & i 11110000 11110001 11110010 11110011 11110100 11110100 11110100 11110000 11111000 11110001 11111000




.
.
.




Note:
The & (bitwise AND) operator compares each bit of its first operand to the corresponding bit of the second operand. If both bits are 1's, the corresponding bit of the result is set to 1. Otherwise, it sets the corresponding result bit to 0.

---------------------------

Acetronics2
- 18th October 2006, 12:54
Hi, Ioannis

And what about your I/O "defines" ( TRISB = ??? ) did you declare the input and output pins ???

Or use individual "HIGH" 's .or "LOW" 's..

Just an idea ...

Alain

sayzer
- 18th October 2006, 13:09
I think I found the problem.

Here it is.



1st i=240 11110000
PortB 11110000 'an example.
Temp=PORTB 11110000
PORTB=Temp & i 11110000

2nd i=241 11110001
PORTB 11110000
Temp=PORTB 11110000
PORTB=Temp & i 11110000

3rd i=242 11110010
PORTB 11110000
Temp=PORTB 11110000
PORTB=Temp & i 11110000
.
..
...
Etc..





The first time you get i=240 in decimal. Which is 11110000.
Then, whatever you "bitwise AND" it with, you will always get 11110000.

Thus, after 240, you will always have 11110000 because each time loop increments, you assign the previous PORTB value to the temp variable.


-------------------

mister_e
- 18th October 2006, 13:12
For i=0 to $0F
PORTB= i
next

Ioannis
- 18th October 2006, 13:31
Thanks everyone for the response.

Well sayzer gave me the kick-start!

What I was needed was to keep the upper bits while setting or reseting the lower according to the counter in the for - next loop. This is done first by clearing the lower bits, then OR-ing with the new value. I was too tired to see it immediatly. But, thanks for the try...

The new code should look like this:

for i=240 to 250
temp=portb
temp=temp & $F0
temp=temp|i
portb=temp
pause 1000
next i

Thanks again,

Ioannis

mister_e
- 18th October 2006, 13:37
DEFINE OSC 20
DEFINE LOADER_USED 1
RCSTA = $90 ' Enable serial port & continuous receive
TXSTA = $20 ' Enable transmit, BRGH = 0
SPBRG = 64 ' 19200 Baud @ 0.16%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

PORTB=0
TRISB=%11110000
i var byte
Temp var byte

Hserout ["***** Waiting PORTB.7 = 0 *****",13,10]
While PORTB.7=1 : wend

hserout ["------------------------Start",13,10]
for i = 0 to 15
PORTB=i
Temp=PORTB
hserout ["PORTB=",bin8 temp,13,10]
next
hserout ["------------------------Stop",13,10]

Spin: goto Spin

if i hold PORTB.7=0

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1137&stc=1&d=1161175253">

mister_e
- 18th October 2006, 13:43
looks like the attachement didn't work...

this is the copy/paste


***** Waiting PORTB.7 = 0 *****
------------------------Start
PORTB=01110000
PORTB=01110001
PORTB=01110010
PORTB=01110011
PORTB=01110100
PORTB=01110101
PORTB=01110110
PORTB=01110111
PORTB=01111000
PORTB=01111001
PORTB=01111010
PORTB=01111011
PORTB=01111100
PORTB=01111101
PORTB=01111110
PORTB=01111111
------------------------Stop

paul borgmeier
- 18th October 2006, 13:45
Steve's does it... but if you do not want to fiddle with the upper nibble latch



For i=0 to $0F
temp = PORTB & $F0 ' keep upper nibble
PORTB= temp | i ' keep upper, set lower to i
next

EDIT - Wow - a lot happens in 10 minutes - I was replying to Steve's #5 and 3 more got in there! :-)
and attachments did not work for me yesterday - I got corrupt error when tried to open

Ioannis
- 18th October 2006, 14:01
Thanks Paul and Steve.

The solution I was expressing at #6 was the one Paul was describing. That is the solution. Steve clever but you do not keep the upper bits.

I have not checked if the interrupt flag for the 4:7 of port b is affected if one is trying to write on input bits of the port. That renains to be checked.

Thanks again,
Ioannis

sayzer
- 18th October 2006, 16:11
Why not using Grandpa's traditional way?





i VAR BYTE


for i=0 to 15
PORTB.0 = i.0
PORTB.1 = i.1
PORTB.2 = i.2
PORTB.3 = i.3
NEXT i





mister_e's #5 code is indeed short. Now it keeps upper ones unchanged.

mister_e
- 19th October 2006, 00:25
As the pin are set to input.... if you write to them, the result stay unchanged... as i posted. Not sure with the interrupt.

Why do you think that PORTB.7=1 or PORTB.7=0 no nothing if the TRIS.7 is not set to 0?

One thing is sure, you will clear the RBIF bit just by reading PORTB, so the above solution using Temp=PORTB will certainely cause some strange interrupt behaviour (at least you will miss some). All in the datasheet in INTCON register description.

Ioannis
- 19th October 2006, 06:23
Steve, yes I know reading the port, RBIF will get reset. But what about writing to the port if the upper nibble is input? Will the write cause Interrupt?

I can tolerate to loose a few while writing to the port. But producing Int's for this reason is not welcome.

Sayzer, nice idea the old recipe. I am just looking too shorten my code. I 'll see which method is shortest.


Thanks,
Ioannis

paul borgmeier
- 19th October 2006, 06:48
Both “Temp = PortB” and “PortB = i” read the Port . Both allow for a chance of missing a change and therefore an interrupt. Steve is right in that preserving the state of the upper four pins does not appear necessary since it does not change the input values when the port is written – just the latched values should the pin directions be changed from inputs to outputs. Go with #5.

Ioannis
- 19th October 2006, 07:31
OK guys. I thought of preservint the interrupts. Anyway, sometimes your thoughts are silly without the ability to see further...

Thanks,
Ioannis