little trick in the 8051

Discussion in 'Programmer's Corner' started by FBorges22, Apr 9, 2009.

  1. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    Greetings,

    I am looking for way to read the P1 Port in the 8051 and send to the serial port when the uC receives the "a" character. However I need to send a decimal string that corresponds to the state of the P1 Port. What is the correct way to do that?

    I tried those methods below however I always receive a ASCII character istead of a decimal string.

    Code ( (Unknown Language)):
    1.  
    2. void send_serial()
    3. {
    4.     SBUF=P1;
    5.     while(!TI);
    6.     TI=0;
    7.     SBUF=0x0A; // sends the "\n" ascii character
    8.     while(!TI);
    9.     TI=0;
    10. }
    11.  
    12. void receive_serial() interrupt 4 using 0
    13. {
    14.     while(!RI);
    15.     RI=0;
    16.     sbuffer=SBUF;
    17.     if (sbuffer == 0x61)
    18.     {
    19.         send_serial();
    20.     }
    21. }
    22.  
    To clarify even more... For example, consider that P1 register is at 7D and when I press the "a" character in the hyperterminal I need to see the number 125 on the screen and not the "}" symbol.

    Thanks,
    FBorges22
     
  2. RiJoRI

    Well-Known Member

    Aug 15, 2007
    536
    26
    I bet that the "ASCII character" you receive translates to the data on P1. You'll need to use a function that changes the hex value to a decimal one. There may be something in your C compiler's library. Basically, you want the effect of printf("%d\n",P1);" without the overhead of the printf() function.

    --Rich
     
  3. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    I tried to import the stdio.h library to use the printf function... However I am experiencing a compiling error in my program. Note I am using the SDCC compiler.

    Here is a sample of my code:

    Code ( (Unknown Language)):
    1. #include <at89s8252.h>
    2. #include <stdio.h>
    3.  
    4. #define s115200 65530 // Baudrate Set
    5.  
    6. char sbuffer; // Received serial data
    7.  
    8. void init_serial(void) // Baud-rate: 115200 - crystal 22.1184MHz
    9. {
    10.     TCON=0x00;
    11.     PCON=0x00;
    12.     SCON=0x50;
    13.     TCLK=1;
    14.     RCLK=1;
    15.     C_T2=0;
    16.     TR2=0;
    17.     RCAP2H=(s115200/256);
    18.     RCAP2L=(s115200%256);
    19.     IE=0x90;
    20.     IP=0x01;
    21.     TR2=1;
    22. }
    23.  
    24. void send_serial()
    25. {
    26.     SBUF=printf("%d\n",P1);
    27.     while(!TI);
    28.     TI=0;
    29. }
    30.  
    31. void receive_serial() interrupt 4 using 0
    32. {
    33.     while(!RI);
    34.     RI=0;
    35.     sbuffer=SBUF;
    36.     if (sbuffer == 0x61)
    37.     {
    38.         send_serial(); // send the P1 port status
    39.     }
    40. }
    41.  
    42. void main()
    43. {
    44.     init_serial(); // Initialize the serial port
    45.     while(1);
    46. }
    47.  
    The output error is:

    ?ASlink-Warning-Undefined Global '_putchar' referenced by module 'vprintf'
     
  4. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    Is there any olther way to do this conversion istead of printf function? Because the SDCC is not recognizing the printf command even with stdio.h library...
     
  5. RiJoRI

    Well-Known Member

    Aug 15, 2007
    536
    26
    "The effect" means you want what it does, without actually using it. Here is one way:
    Code ( (Unknown Language)):
    1.  
    2.  
    3. char Hundreds_Cnt;
    4. char Tens_Cnt;
    5. char Ones_Cnt;
    6.  
    7. void xtod(char Hex_Num)
    8. {
    9.     /* Clear holders */
    10.     Hundreds_Cnt = 0;
    11.     Tens_Cnt = 0;
    12.     Ones_Cnt = 0;
    13.  
    14.     /* Count the hundreds we have */
    15.     while(Hex_Num > 99) /* same as >= 100 */
    16.     {
    17.         Hundreds_Cnt++;
    18.         Hex_Num -= 100;
    19.     }
    20.  
    21.     /* Count the tens we have */
    22.     while(Hex_Num > 9)
    23.     {
    24.         Tens_Cnt++;
    25.         Hex_Num -= 10;
    26.     }
    27.  
    28.     /* Counting the ones would be silly */
    29.     Ones_Cnt = Hex_Num;
    30. }
    31.  
    --Rich
     
  6. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    Let me check if I understand correctly...

    I need to call the xtod function with P1 value with this?

    Code ( (Unknown Language)):
    1. xtod(P1)
    And after that I need to send all the three parameters to the serial port using this function:

    Code ( (Unknown Language)):
    1.  
    2. void send_serial()
    3. {
    4.     SBUF=Hundreds_Cnt;
    5.     while(!TI);
    6.     TI=0;
    7.     SBUF=Tens_Cnt;
    8.     while(!TI);
    9.     TI=0;
    10.     SBUF=Ones_Cnt;
    11.     while(!TI);
    12.     TI=0;
    13. }
     
  7. RiJoRI

    Well-Known Member

    Aug 15, 2007
    536
    26
    Looks like it should work!

    --Rich
     
  8. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    I am still receiving a ASCII character in the hyperterminal... :(

    I need to receive a decimal number that correspond to the state of the P1 Port...

    For example, if the P1 port register is at 0xFF I need to receive the "255" number in the HyperTerminal when I press the "a" key.

    That problem is sure very tricky... Any olther ideas to correct this?
     
  9. RiJoRI

    Well-Known Member

    Aug 15, 2007
    536
    26
    OK, so now it looks like it shouldn't work! :(

    The function changes 255 into 2,5,5. And HT sees 3 characters, I'm guessing -- 0x02, 0x05, 0x05.

    Before sending the characters out, add 0x30 to them -- the ASCII value for zero -- "SBUF = '0' + Hundreds_Cnt;". Then HT should see 0x32, 0x35, 0x35, or "255"

    --Rich
     
  10. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    We are almost there...

    I modified the send_serial function to this:

    Code ( (Unknown Language)):
    1. void send_serial()
    2. {
    3.     //SBUF=printf("%d\n",P1);
    4.     xtod(P1);
    5.     SBUF='0'+Hundreds_Cnt;
    6.     while(!TI);
    7.     TI=0;
    8.     SBUF=0x30+Tens_Cnt;
    9.     while(!TI);
    10.     TI=0;
    11.     SBUF=0x30+Ones_Cnt;
    12.     while(!TI);
    13.     TI=0;
    14.     SBUF=0x0A; // sends the "\n" character to change the line in HT
    15.     while(!TI);
    16.     TI=0;
    17. }
    And I am receiving a "00/" when I press the "a" key in the HT. I was expecting "255" because the P1 register is at 0xFF. What we should do next?
     
  11. FBorges22

    Thread Starter Active Member

    Sep 11, 2008
    104
    0
    RiJoRI,

    I corrected the problem. The error was in the declaration of the char variables. In this application we need to use the unsigned keyword because the char has a range of -127 to +127 and I need a range of 0 to 255.

    The function xtod was correct and the program is working now and now I have to develop and take care of the rest. Thanks for the tips :)
     
Loading...