Array and port problem.

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

[moderator note: two threads have been merged here - the initial posts were appended on the "101" thread and have been split off and prepended to this "Array and port problem" thread]

I want to shorten down one part of the code where I check "one cell" in the vector bit by bit. I change PortB2 depending if it is a 1 or a 0. Any suggestions?
And I dont want to use shift (<<)

Quote:

if(numbers_in_bin[0] & (1<<j)) //j goes from 0 to 7
{
bla bla bla
}
else
{
jada jada jada
}

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

Unroll the loop? (that is hard code separate 1<<0, 1<<1, 1<<2 cases)

Or how about a table of masks:

uint8_t bm_s[] = {1,2,4,8,16,32,64,128};

if(numbers_in_bin[0] & bm_s[j]) //j goes from 0 to 7

Or have a mask that's shifted in the loop:

uint8_ mask = 1;

for (j=0;j <7; j++) {
  if(numbers_in_bin[0] & mask) //j goes from 0 to 7
  mask <<= 1;
}

At least this probably just pans out to an:

ADD Rn,Rn

for each loop iteration.

But in all cases you need to look at the generated Asm to see which is "tighter" and which is "faster" (the simulator cycle counter helps a lot for this).

BTW a question like this should be asked in AVR Forum not hijacked onto the end of a tutorial. Tell me what you want the thread called and I'll split these last few posts off into a new thread in AVR Forum. (moderator)

Last Edited: Thu. Apr 8, 2010 - 02:23 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Blipp-Blopp-Bob wrote:

And I dont want to use shift (<<)

Fear you, that the code would be to fast or to tight with using the shift? :shock:

Shift a register cost only 1 CPU cycle.
So it is the most efficient way to shift in/out bits of a byte.

Peter

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

Maybe I've should explained better. :)

I want to use a[0 to 2] arrays and if a[0]'s bit(7) is 1 I want PORTB2 to be 1, and 0 if bit(7) was 0. :)
so a[0] controll PORTB2, a[1] controll PORTB1, and a[2] controll PORTB0. :/

It would be easier to write it in asm but the rest of the prog is better in C. :)

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

Then do you mean:

PORTB = ((a[0] & 0x80)?1:0 << 2) | ((a[1] & 0x80)?1:0 << 1) | ((a[2] & 0x80)?1:0 << 0);

Maybe if you DO write it in Asm we can tell you what the C would be.

My previous offer to split this thread hijack into a separate thread stands BTW - I just need a thread name (so you don't lose it).

Cliff

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

Blipp-Blopp-Bob wrote:
It would be easier to write it in asm but the rest of the prog is better in C. :)

I think, its hard in c and even in assembler.
Since there exist no easy instruction to do so.

You must read 3 different variables and set/clear 3 different pins.
So it seems the easiest, write the 3 functions successive.

It would be many times easier, if all 3 pins collected only into a single variable and already in the right order and on the right position.
Then a simple AND/OR would do the job.

Peter

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

It was a while since I worked with asm and espacially c/c++. :/
But Im working on a project now and I got stuck on one thing maybe you guys can help me code it or come up with another solution. :)

I got one array numbers[].

Quote:
numbers[0] = 0b10101010
numbers[1] = 0b01010101
numbers[2] = 0b11001100
and so one, (the numbers in the array are an example:P)

My second array is selection[0] which goes from 0..2 and they represent the selaction made on a keypad.

Now to the problem I want to set/cler PB0, PB1 and PB2 depending on the bit in the array. For example lets say we use the numbers in the qoute. Then we will gett PB2, PB1 and PB0 going like this:
PB2: 1 - 0 - 1 - 0 - 1 - 0 - 1 - 0
PB1: 0 - 1 - 0 - 1 - 0 - 1 - 0 - 1
PB0: 1 - 1 - 0 - 0 - 1 - 1 - 0 - 0
...bit7 bit6 ...................bit0

So I was thinking of a for-loop to count all the bits and the set PORTB. Any suggestions on code cause I can't get it to work. Maybe I need a new pair of eyes. :)

Best regards
bbb

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

This was mine solution. It kinda works but looks like it can be optimized. But Im no guru. ;)

Quote:
for(uint8_t j = 0x0; j<8;j++)
{
//Världens största if-sats. Klura ut nått bättre
//111
if((segment_F[0] & (1<<j)) && (segment_F[1] & (1<<j)) && (segment_F[2] & (1<<j)))
{PORTB = (1<<2) | (1<<1) | (1<<0);}
//110
else if((segment_F[0] & (1<<j)) && (segment_F[1] & (1<<j)))
{PORTB = (1<<2) | (1<<1) | (0<<0);}
//101
else if((segment_F[0] & (1<<j)) && (segment_F[2] & (1<<j)))
{PORTB = (1<<2) | (0<<1) | (1<<0);}
//100
else if((segment_F[0] & (1<<j)) )
{PORTB = (1<<2) | (0<<1) | (0<<0);}
//011
else if((segment_F[1] & (1<<j)) && (segment_F[2] & (1<<j)))
{PORTB = (0<<2) | (1<<1) | (1<<0);}
//010
else if(segment_F[1] & (1<<j))
{PORTB = (0<<2) | (1<<1) | (0<<0);}
//001
else if(segment_F[2] & (1<<j))
{PORTB = (0<<2) | (0<<1) | (1<<0);}
//000
else
{PORTB = (0<<2) | (0<<1) | (0<<0);}

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

So why don't you "rotate" the numbers[] array? Instead of:

numbers[0] = 0b10101010 
numbers[1] = 0b01010101 
numbers[2] = 0b11001100

use:

data[] = { 0b101, 0b011, 0b100, 0b010, 0b101, 0b011, 0b100, 0b010};

in which case you can just output these to the bottom 3 bits of PORTB:

PORTB = (PORTB & 0xF8) | data[n];

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

The number[1..12], and number[0] = zero on a segment of my display.

I got a uint8_t (call it selected) which is returned from a a keypad function. So I got this so far:
Segment[] = numbers[selected].
So if selected = 0 gives me
Segment[] = number[0] which is 0b00111111 (zero on the display) and it will be in segment 1 och 3.

And now when I get a for-loop that makes my muxes count from 1 to 7, for every line in the segment. And I want PB2, PB1 and PB0 to be high when the bit is set and zero when the bit is cleared.

Just like the example I made in the qoute.

Do you understand my bad english? :)

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

I'm afraid I have a hard time visualising this - can you post a schematic to show how the display is connected? One thing I'm not clear about is why only 3 bits are involved - are you talking about THREE seven segment displays and the 3 bits on PORTB are attached to three shift registers or something?

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

Yes, its three seven segment display. :/

I have 3 mux:s with pins Y0-Y7 connected to one segment ea on the three seven segment displays.
And PB2 is connected to Z on mux0, and PB1 is connected to Z on mux1 and last PB0 is connected to z on mux 3.

So I use a counter 000 to 111 to controll all three mux:s at once and then I set Z or clear Z on the mux:s depending on the bits in my array.

I can see if I got a schematic around. :/