# Reading ports and modifying data quickly

#### Dave_

Joined Mar 22, 2007
28
This follows on from this topic:
C code for concatenation.

I'm interfacing my XA microcontroller with an ADC which has a 12 bit parallel output. My main goal was to quickly read the pins, and determine what number they are at (0 to 8191), then holding this value, and repeating the step, and compare which number is highest.

Is the answer still going to be the same, use strings to merge all the bits together into their correct order?

Cheers

#### n9352527

Joined Oct 14, 2005
1,198
I won't use any string operation, they need too many cycles. Just shift the high 4 bits 8 places to the left, and then bit-or it with the low 8 bits. Something like:

value = (high_4_bits << 8) | low_8_bits

Incidentally, the maximum decimal value for 12-bit number is 4095 (0xFFF) and not 8191. A typo?

#### Dave_

Joined Mar 22, 2007
28
Thanks. I was trying that earlier but getting no luck with the '10' chance. Here's my code:

# include<regxag49.h>
#define ON 1
#define OFF 0
// Set bit port 1
sbit Port1_Pin0 = P1^0;
sbit Port1_Pin1 = P1^1;
sbit Port1_Pin2 = P1^2;
sbit Port1_Pin3 = P1^3;
sbit Port1_Pin4 = P1^4;
sbit Port1_Pin5 = P1^5;
sbit Port1_Pin6 = P1^6;
sbit Port1_Pin7 = P1^7;

// Set bit port 0
sbit Port0_Pin0 = P0^0;
sbit Port0_Pin1 = P0^1;
sbit Port0_Pin2 = P0^2;
sbit Port0_Pin3 = P0^3;
sbit Port0_Pin4 = P0^4;
sbit Port0_Pin5 = P0^5;
sbit Port0_Pin6 = P0^6;
sbit Port0_Pin7 = P0^7;

char Decision;
int Counter1;
int b;
char a;

void main()
{
Counter1 = 100; // Initialise counter

while(1) /* repeat forever */
{
a = Port1_Pin0;
b = Port1_Pin1;

Decision = (a << 1) | b;

if (Decision == 00){

Port0_Pin0 = Port1_Pin0;
Port0_Pin1 = Port1_Pin1;
Port0_Pin2 = Port1_Pin2;
Port0_Pin3 = Port1_Pin3;
Port0_Pin4 = Port1_Pin4;
Port0_Pin5 = Port1_Pin5;
Port0_Pin6 = Port1_Pin6;
Port0_Pin7 = Port1_Pin7;
}
else if (Decision == 01){
while (Counter1 != 0){
Port0_Pin0 = 0;
Port0_Pin1 = 0;
Port0_Pin2 = 0;
Port0_Pin3 = 0;
Port0_Pin4 = 0;
Port0_Pin5 = 0;
Port0_Pin6 = 0;
Port0_Pin7 = 0;
Counter1 = Counter1 - 1;
Port0_Pin0 = 1;
Port0_Pin1 = 1;
Port0_Pin2 = 1;
Port0_Pin3 = 1;
Port0_Pin4 = 1;
Port0_Pin5 = 1;
Port0_Pin6 = 1;
Port0_Pin7 = 1;
}
}
else if (Decision == 10){
Port0_Pin0 = 0;
Port0_Pin1 = 1;
Port0_Pin2 = 0;
Port0_Pin3 = 1;
Port0_Pin4 = 0;
Port0_Pin5 = 1;
Port0_Pin6 = 0;
Port0_Pin7 = 1;
}
else {

Port0_Pin0 = !Port1_Pin0;
Port0_Pin1 = !Port1_Pin1;
Port0_Pin2 = !Port1_Pin2;
Port0_Pin3 = !Port1_Pin3;
Port0_Pin4 = !Port1_Pin4;
Port0_Pin5 = !Port1_Pin5;
Port0_Pin6 = !Port1_Pin6;
Port0_Pin7 = !Port1_Pin7;
}
}

}

It works fine for when decision is 00 and 01, but doesn't for 10.

Also, you did it in one step, was that just to show how it worked or I really can say
a = P1
b = P2
?

#### beenthere

Joined Apr 20, 2004
15,819
Might it be faster to load the bits into two locations (ADCHi - ADClo) and compare the high nibbles. Only if they are equal do you have to compare the low bytes.

#### Dave_

Joined Mar 22, 2007
28
Yep, that sounds like a good plan. Still my concatenate code isn't working though. Also is it possible to read a whole port instead of each pin in that port concatenating each time?

#### n9352527

Joined Oct 14, 2005
1,198
I don't understand what you are trying to do in your code. Why do you only read two bits (P1.0 and P1.1) and then concatenate them? (Is concatenate even a word? )

What you should do is to read a whole 8 bits from a port, then another 4 bits from another port, then concatenate them. Make sure that the data lines from the ADC are connected in order to the right pins/port, i.e. bit 0-7 to P0.0 to P0.7, bit 8-11 to P1.0 to P1.3.

Something like:

Rich (BB code):
char a, b;
int c, d = 0;

while(1) {
a = Port0; // lower 8 bits
b = Port1 & 0x0F; // higher 4 bits
c = (b << 8) | a;

if(c > d) {
// do whatever you need to do when the new value
// is bigger than the last one here.
}

d = c; // save the last value
}
Or, as beenthere suggested, you could compare the higher 4 bits first, then only process the lower 8 bits when necessary.

#### Dave_

Joined Mar 22, 2007
28
Brilliant. Thanks for that, I will try it right away

As for my code, I was using just two bits for experimental purposes really. Sorry, should of said that, as if it works with two bits it should work with two bytes

As for concatenate, I got it from here:
Apparantly it's the 'in' word for joining now

#### Papabravo

Joined Feb 24, 2006
14,872
...(Is concatenate even a word? )
...
Yes, but it's a string thing. Ever written a program in SNOBOL 4?

#### n9352527

Joined Oct 14, 2005
1,198
Yes, but it's a string thing. Ever written a program in SNOBOL 4?
Haven't even heard of SNOBOL before. According to Wiki, it was popular in 70s and 80s. Back then I still wore nappy or wet my bed or both

#### Dave_

Joined Mar 22, 2007
28
Implemented that, but getting some wiping out. Like I can't get the 8 bits at 'b' to become 12 bits. When I shift the binary up, it doesnt exceed the 8 bit boundry, but it still adds zeroes, then when shifting down zeroes get added from the top. I am viewing the port to see what it does at various stages, and I understand I can only see the lower 8 bits of the port, but when returning back to normal, this error still occurs:
Start
1 1 1 1 1 1 1 1
Shift 5 bits to the left
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
Shift 5 bits to the right
0 1 1 1 0 0 0 0
0 0 1 1 1 0 0 0
0 0 0 1 1 1 0 0
0 0 0 0 1 1 1 0
0 0 0 0 0 1 1 1
Finish

And so what started off as 0xFF is now 0x03.
I really need something that will tell the variable b that it is 12 bits long.
Any ideas?

#### n9352527

Joined Oct 14, 2005
1,198
Yeah, I forgot to cast the variable. This is why we need to debug a system

c = (((int)b) << 8) | ((int)a);

#### Dave_

Joined Mar 22, 2007
28
I tried that and got up some bracket errors. And I get the same error with the erasing of numbers on shifting right. I'm using this just for this specific test as the whole thing wasnt working (concatenation).

P1 = 0xFF

Rich (BB code):
		a = P1;
P3 = a;
P3 = ((int)a << 5);
P3 = ((int)a >> 5);
P3 = 0xE0
then
P3 = 0x07

#### Papabravo

Joined Feb 24, 2006
14,872
Then perhaps your compiler is generating bad code. Look at the declarations and the expression. a and b are declared a chars - nominally eight bits. c is declared as an int. In the expression
Rich (BB code):
c = (b<<8) | a ;
both b and a should be promoted to int before the operations. As another point, both char and int are probably signed. You are aware that shifting a signed quantity behaves differently then shifting an unsigned quantity. Can you look at the compilers assembly language output?

#### Dave_

Joined Mar 22, 2007
28
I'm using Raisonence RIDE software. Version 06.10.12

I don't think I can convert this into an assembler language. I think I'll just download the program straight to the microcontroller and see if it works on that.
Hopefully should get a chance to do that on Friday.

#### Papabravo

Joined Feb 24, 2006
14,872
You don't convert anything. The compiler should have a way for you to view the assembly language code it produces. That is how the compiler writers check the compiler for proper operation. You should learn how to do this too.