Reading ports and modifying data quickly

Discussion in 'Embedded Systems and Microcontrollers' started by Dave_, May 16, 2007.

  1. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    This follows on from this topic:
    http://forum.allaboutcircuits.com/showthread.php?t=5918
    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
     
  2. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    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? :)
     
  3. Dave_

    Thread Starter Member

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



    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
    ?
     
  4. beenthere

    Retired Moderator

    Apr 20, 2004
    15,815
    282
    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.
     
  5. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    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?
     
  6. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    4
    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? :D)

    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:

    Code ( (Unknown Language)):
    1.  
    2. char a, b;
    3. int c, d = 0;
    4.  
    5. while(1) {
    6.   a = Port0; // lower 8 bits
    7.   b = Port1 & 0x0F; // higher 4 bits
    8.   c = (b << 8) | a;
    9.  
    10.   if(c > d) {
    11.     // do whatever you need to do when the new value
    12.     // is bigger than the last one here.
    13.   }
    14.  
    15.   d = c; // save the last value
    16. }
    17.  
    Or, as beenthere suggested, you could compare the higher 4 bits first, then only process the lower 8 bits when necessary.
     
  7. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    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:
    http://forum.allaboutcircuits.com/showthread.php?t=5376
    Apparantly it's the 'in' word for joining now :D
     
  8. Papabravo

    Expert

    Feb 24, 2006
    10,135
    1,786
    Yes, but it's a string thing. Ever written a program in SNOBOL 4?
     
  9. n9352527

    AAC Fanatic!

    Oct 14, 2005
    1,198
    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 :D
     
  10. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    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?
     
  11. n9352527

    AAC Fanatic!

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

    c = (((int)b) << 8) | ((int)a);
     
  12. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    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

    Code ( (Unknown Language)):
    1.         a = P1;
    2.                           P3 = a;
    3.         P3 = ((int)a << 5);
    4.         P3 = ((int)a >> 5);
    P3 = 0xE0
    then
    P3 = 0x07

    Thanks for your replys so far :)
     
  13. Papabravo

    Expert

    Feb 24, 2006
    10,135
    1,786
    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
    Code ( (Unknown Language)):
    1.  
    2. c = (b<<8) | a ;
    3.  
    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?
     
  14. Dave_

    Thread Starter Member

    Mar 22, 2007
    28
    0
    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.
     
  15. Papabravo

    Expert

    Feb 24, 2006
    10,135
    1,786
    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.
     
Loading...