copy a port into a variabele

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello, 

my question is a little bit different.

 

i have on PORTC 8 times a IR receiver. and i want the status of them in a variable, called for example: savebyte

but i can not copy the PORTC at once into savebyte.

i have to do it one by one, so

first PINC7 in to  savebyte  -----> result: 0b10000000

first PINC6 in to  savebyte  -----> result: 0b01000000 

first PINC5 in to  savebyte  -----> result: 0b00100000 

.

.

.

first PINC0 in to  savebyte  -----> result: 0b00000001

 

every step is 4 mS

 

i hope some one can help me,......thanks in advance  

Last Edited: Fri. Apr 3, 2020 - 08:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

trixo wrote:
but i can not copy the PORTC at once into savebyte.
Why not? Usually you would do it in one read:

savebyte = PINC;

even if for some mysterious reason you wanted to do it a bit at a time you would still tend to use:

uint8_t portcopy = PINC;
savebyte = 0;
savebyte |= (portcopy & 0x80);
savebyte |= (portcopy & 0x40);
savebyte |= (portcopy & 0x20);
savebyte |= (portcopy & 0x10);
savebyte |= (portcopy & 0x08);
savebyte |= (portcopy & 0x04);
savebyte |= (portcopy & 0x02);
savebyte |= (portcopy & 0x01);

so that the PINC register itself only needs to be read once at the start, though if you really want to do 8 separate reads then:

savebyte |= (PINC & 0x08);
savebyte |= (PINC & 0x40);
savebyte |= (PINC & 0x20);
savebyte |= (PINC & 0x10);
savebyte |= (PINC & 0x08);
savebyte |= (PINC & 0x04);
savebyte |= (PINC & 0x02);
savebyte |= (PINC & 0x01);

but every byte in PINC could have changed between one read and the next as you really are reading it at 8 different times.

Last Edited: Fri. Apr 3, 2020 - 08:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

trixo wrote:

...every step is 4 mS...

 

Please explain that statment.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, that is the way to do it, i checked in the simmulator, and it works as i expected.

 

the reason i have to do it one by one, is that i don't want that IR-LED no: 4 lightning receiver nu: 3 or 5.

 

thank you very much for your help. yes 

Last Edited: Fri. Apr 3, 2020 - 08:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

but i can not copy the PORTC at once into savebyt,e  i have to do it one by one, so

Why?  All you have to do is read PINC and it will give you all 8 bits at once (to put wherever you want). 

 

Do you mean you WANT to do it one bit at a time?  That's what it sounds like.

   You should get familiar with the bit manipulation operators (and's, or's)

    One "logical" method

    1) Clear the desired bit in the storage using an and operator on the desired bit position (bit becomes zero)

    2) Read port (PINC) register into temp variable

    3) Using and, clear all the temp bits you are not interested in, leaving only  the  chosen bit position (same position as in step 1)

    4) "Or" step  #3 into #1  ...now the storage bit is the same as the corresponding port bit.

 

Note these 4 steps can be combined into one statement, this just breaks it down for easy understanding.

 

 

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Fri. Apr 3, 2020 - 08:55 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
 You should get familiar with the bit manipulation operators (
+1

 

I agree you only need to read the register once then pick out the individual bits as you need them (&).

 

In my example I used 0x80, 0x40, 0x20 etc to access single bits. These are called "masks". Each one in this sequence has just 1 bit set. Another way to create masks is with (1 << n) so I could have written:

savebyte |= (PINC & (1 << 7));
savebyte |= (PINC & (1 << 6));
savebyte |= (PINC & (1 << 5));
savebyte |= (PINC & (1 << 4));
savebyte |= (PINC & (1 << 3));
savebyte |= (PINC & (1 << 2));
savebyte |= (PINC & (1 << 1));
savebyte |= (PINC & (1 << 0));

The only reason I didn't do it that way and chose 0x80, 0x40.. instead was that it is less typing !

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the method of clawson is working so far.

 

i explained in my last post, why i have to do it one by one.

tnx.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

trixo wrote:
why i have to
Nope you don't "have to". It's just because you don't yet know other ways to achieve the same.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i'm not really understand the last post, but thanks for your help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Reading a PINx register once and picking out desired bits from the

copy is pretty much always better than reading PINx multiple times.

It gets you the assurance of consistent results.

In cases where inconsistencies do not matter or cannot happen,

ascertaining that and then documenting it requires

intellectual effort that will not be expended on other things.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 4 ms might be a clue to what is going on in OP's brain.

He might possibly have 8 devices synchronized to provide data 4 ms apart.

How he knows when data is available, I do not know.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i have: 8 times a IR led and 8 times a IR receiver: who's gonna create a "scanner"

to prevent that led # 3 lighting receiver #2 and/or #4.

i gonna steer de led's one by one for 4mS (for each led), so i also have to reed the receivers one by one.

when the scan is ready i want the result some where in a byte.

 

IR led #1..................800mm..................receiver #1

IR led #2..................800mm..................receiver #2

IR led #3..................800mm..................receiver #3

IR led #4..................800mm..................receiver #4

IR led #5..................800mm..................receiver #5

IR led #6..................800mm..................receiver #6

IR led #7..................800mm..................receiver #7

IR led #8..................800mm..................receiver #8

 

thanx for the reactions yes

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think i understood what OP means , correct me if I'm wrong :
He is sending a signal from an led and waiting for the feedback from the corresponding sensor but he don't want another sensor other then the corresponding one to receive it.

as the pervious said u can just turn on and led then detect the feedback from the corresponding sensor using :
(sorry i'm on my phone now)

// code
savebyte |= (PINC & (1 << 0)); // where 0 is the pin number where the sensor is
// code end

then u can add somekind of a delay, maybe u would use a timer interrupt on fixed frequency to match ur desires.

A Beam of Light out of the War

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@OP A PINC bit is not used up by reading it.

There is no mechanism for directly copying just one bit of PINC.

ANDI Rtarget, ~mask $ SBIC PINC, bit $ ORI Rtarget, mask

would seem to do what you want for a single bit.

Apparently you want eight of these.

Their timing and the selection of masks, bits and Rtargets are left as an exercise for the reader.

Probably all the ANDIs can be replaced by a single LDI Rtarget, 0 .

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm with AbDoO_ on this one.

 

The reason why he (she?) can't receive them all simultaneously is because he can't fire them all simultaneously, because each sensor will interfere with the others - receiving signal from the wrong transmitter. 

 

Somewhere out there he has eight sequential transmitters.

 

He needs to read the register many times and do 'AND' to the result register, as in:

 

clr r17
in r16, PORTC          ; Get the first bit
cbr r16, 0b01111111    ; Masking out spurious inputs
and r17, r16           ; store the first bit
; wait for the next sensor firing
in r16, PORTC          ; Get the next bit
cbr r16, 0b10111111    ; Masking out spurious inputs 
and r17, r16           ; store the next bit
; and wait for the next.  
; Et cetera.
; There's faster ways using rolls and shifts, but given 4ms per, I don't think I'd care.

Does that help any?  S.

 

Edited to add:  There ought to be some masking in there as well, to remove spurious signals from the incorrect receiver(s)  The code got edited to add it.  S.

Last Edited: Thu. Apr 9, 2020 - 05:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:

in r16, PORTC          ; Get the first bit

I'm rather guessing that was meant to be:

in r16, PINC          ; Get the first bit

BTW unless this CPU is running very, very slowly I have a feeling those INs are not going to be spaced 4ms apart !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Scroungre wrote:

 

in r16, PORTC          ; Get the first bit

I'm rather guessing that was meant to be:

in r16, PINC          ; Get the first bit

BTW unless this CPU is running very, very slowly I have a feeling those INs are not going to be spaced 4ms apart !!

 

It was.  My bad!!   Otherwise, I was thinking there would be a delay loop in the ; wait for next bit.  S.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:

 

clr r17
in r16, PORTC          ; Get the first bit
cbr r16, 0b01111111    ; Masking out spurious inputs
and r17, r16           ; store the first bit
; wait for the next sensor firing
in r16, PORTC          ; Get the next bit
cbr r16, 0b10111111    ; Masking out spurious inputs
and r17, r16           ; store the next bit
; and wait for the next.
; Et cetera.
; There's faster ways using rolls and shifts, but given 4ms per, I don't think I'd care.This code 

This code will leave r17 at 0 regardless of the contents of PORTC or PINC.

SBIC PINC, 0 $ ORI r17, 0x01 ...

does what you seem to intend.

From OP's examples, he does not intend to accumulate bits.

savebyte=PINC & 0x01 ...

should be adequate for his needs.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, that code was all screwed up.  Should have been OR not AND.  Whatever I was smoking when I wrote that I should go get some more...  S.