adc interfacing

Discussion in 'Embedded Systems and Microcontrollers' started by tharunmalli, Apr 24, 2014.

  1. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    I am actually interfacing adc 0804 to p89v51rd2. My main task is to vary the analog input to adc and get the resulting value on hyper terminal in hex format.
    I know how to interface adc but the problem is how to convert the binary data to hex format and send it through serial communication.
    Please any one post the c program to convert binary data to hex in 8051.
    Please help me...
     
  2. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Ah well this some sort of school assignment is it not ;) So just posting the solutions would be wrong do you not think so?
    Hyperterm work with ACSII codes http://www.asciitable.com/ So if your ADC result is say 0xA5 You will need to send the following bytes in hex 0x41 and 0x35 Since you will be sending a series of samples sending a space 0x20 after the two bytes would be wise.
    The first thing you will need to do is isolating the ADC result into two groups of 4 bits(nibble). Then take close look at the ASCII table. You see that numbers start at 0x30 hex. So if the result for one of the nibbles is in range 0 to 9. You just add 0x30 to the nibble and send it out on the serial line. If the nibble is range 0x0A to 0x0F it is a little bit more tricky. But I leave it to you to sort that out
     
    tharunmalli and djsfantasi like this.
  3. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    I am interfacing adc 0804 with p89v51rd2. my aim is to get the adc output in the form of 00-FF on hyper terminal. I am attaching the code i wrote..I am using keil software , this program shows no error but in hardware its not working .
    the problem is adc is sending the binary data to controller . but on hyperterminal i am getting only one character i.e T=ox54.... please help to figure out whats the problem.. please help

    Code ( (Unknown Language)):
    1.  
    2. #include<reg51.h>
    3. #define input P1 //Input port to read the values of ADc
    4. sbit wr= P0^1;    // Write pin. It is used to start the conversion.
    5. sbit rd= P0^0;    // Read pin. It is used to extract the data from internal register to the output pins of ADC.
    6. sbit intr= P0^2;
    7. void delay(unsigned int msec )     // The delay function provides delay in msec.
    8. { int i,j ;
    9. for(i=0;i<msec;i++) for(j=0; j<1275; j++);
    10. }
    11.  
    12. void adc()          // Function to read the values from ADC and store it accumulator.
    13. {
    14. rd=1;
    15. wr=0;
    16. delay(1);
    17. wr=1;
    18. while(intr==1);
    19. rd=0;
    20. ACC=input;
    21. delay(1);
    22. intr=1;
    23. }
    24. void main()
    25. { unsigned char a,b,c,d,i,j,x[3],z[2];
    26. input=0xff;      
    27. while(1)
    28. { adc();
    29. delay(1);
    30. a=ACC;
    31. b=ACC;
    32. c=a&0x0F;
    33. d=b&0xF0;
    34. d=d>>4;
    35. z[0]=d;
    36. z[1]=c;
    37. delay(1);
    38. for(i=0;i<=1;i++)
    39. {
    40. switch(z[i])
    41. {
    42. case 0000:
    43. x[i]=0x30;
    44. break;
    45. case 0001:
    46. x[i]=0x31;
    47. break;
    48. case 0010:
    49. x[i]=0x32;
    50. break;
    51. case 0011:
    52. x[i]=0x33;
    53. break;
    54. case 0100:
    55. x[i]=0x34;
    56. break;
    57. case 0101:
    58. x[i]=0x35;
    59. break;
    60. case 0110:
    61. x[i]=0x36;
    62. break;
    63. case 0111:
    64. x[i]=0x37;
    65. break;
    66. case 1000:
    67. x[i]=0x38;
    68. break;
    69. case 1001:
    70. x[i]=0x39;
    71. break;
    72. case 1010:
    73. x[i]=0x41;
    74. break;
    75. case 1011:
    76. x[i]=0x42;
    77. break;
    78. case 1100:
    79. x[i]=0x43;
    80. break;
    81. case 1101:
    82. x[i]=0x44;
    83. break;
    84. case 1110:
    85. x[i]=0x45;
    86. break;
    87. case 1111:
    88. x[i]=0x46;
    89. break;
    90. }}
    91. x[2]=0x54;
    92. delay(1);
    93. TMOD=0x20;
    94. TH1=0xFD;
    95. SCON=0x50;
    96. TR1=1;
    97. for(j=0;j<=3;j++)
    98. {
    99. SBUF=x[i];
    100. while(TI==0);
    101. TI=0;
    102. delay(1);
    103. }
    104. }
    105. }
    106. [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
     
    Last edited by a moderator: Apr 30, 2014
  4. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    I am interfacing adc 0804 with p89v51rd2. my aim is to get the adc output in the form of 00-FF on hyper terminal. I am attaching the code i wrote..I am using keil software , this program shows no error but in hardware its not working .
    the problem is adc is sending the binary data to controller . but on hyperterminal i am getting only one character i.e T=ox54.... please help to figure out whats the problem.. please help

    Code ( (Unknown Language)):
    1.  
    2. #include<reg51.h>
    3. #define input P1 //Input port to read the values of ADc
    4. sbit wr= P0^1; // Write pin. It is used to start the conversion.
    5. sbit rd= P0^0; // Read pin. It is used to extract the data from internal register to the output pins of ADC.
    6. sbit intr= P0^2;
    7. void delay(unsigned int msec ) // The delay function provides delay in msec.
    8. { int i,j ;
    9. for(i=0;i<msec;i++) for(j=0; j<1275; j++);
    10. }
    11.  
    12. void adc() // Function to read the values from ADC and store it accumulator.
    13. {
    14. rd=1;
    15. wr=0;
    16. delay(1);
    17. wr=1;
    18. while(intr==1);
    19. rd=0;
    20. ACC=input;
    21. delay(1);
    22. intr=1;
    23. }
    24. void main()
    25. { unsigned char a,b,c,d,i,j,x[3],z[2];
    26. input=0xff;
    27. while(1)
    28. { adc();
    29. delay(1);
    30. a=ACC;
    31. b=ACC;
    32. c=a&0x0F;
    33. d=b&0xF0;
    34. d=d>>4;
    35. z[0]=d;
    36. z[1]=c;
    37. delay(1);
    38. for(i=0;i<=1;i++)
    39. {
    40. switch(z[i])
    41. {
    42. case 0000:
    43. x[i]=0x30;
    44. break;
    45. case 0001:
    46. x[i]=0x31;
    47. break;
    48. case 0010:
    49. x[i]=0x32;
    50. break;
    51. case 0011:
    52. x[i]=0x33;
    53. break;
    54. case 0100:
    55. x[i]=0x34;
    56. break;
    57. case 0101:
    58. x[i]=0x35;
    59. break;
    60. case 0110:
    61. x[i]=0x36;
    62. break;
    63. case 0111:
    64. x[i]=0x37;
    65. break;
    66. case 1000:
    67. x[i]=0x38;
    68. break;
    69. case 1001:
    70. x[i]=0x39;
    71. break;
    72. case 1010:
    73. x[i]=0x41;
    74. break;
    75. case 1011:
    76. x[i]=0x42;
    77. break;
    78. case 1100:
    79. x[i]=0x43;
    80. break;
    81. case 1101:
    82. x[i]=0x44;
    83. break;
    84. case 1110:
    85. x[i]=0x45;
    86. break;
    87. case 1111:
    88. x[i]=0x46;
    89. break;
    90. }}
    91. x[2]=0x54;
    92. delay(1);
    93. TMOD=0x20;
    94. TH1=0xFD;
    95. SCON=0x50;
    96. TR1=1;
    97. for(j=0;j<=3;j++)
    98. {
    99. SBUF=x[i];
    100. while(TI==0);
    101. TI=0;
    102. delay(1);
    103. }
    104. }
    105. }
    106. [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
     
    Last edited by a moderator: Apr 30, 2014
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    I am sorry for that you struggle. But have you tried some sort of debugging of your code. Like single stepping and using watches. Then you will find out at which point your code do not do what it is expected to do.
     
  6. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    I think the problem is that the switch cases are being interpreted in decimal, and you've written them as hexadecimal - if that's the problem, switching to the method referenced in post #2 will fix it, or you could fix the case statements...
     
    Last edited: Apr 30, 2014
    djsfantasi likes this.
  7. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,809
    834
    You need to separate the two nibbles and read post #2 carefully!
     
    Last edited: Apr 30, 2014
    tharunmalli likes this.
  8. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Is that not what
    Code ( (Unknown Language)):
    1. c=a&0x0F;
    2. d=b&0xF0;
    does?:)
     
    tharunmalli likes this.
  9. MaxHeadRoom

    Expert

    Jul 18, 2013
    10,548
    2,373
    You may be better off using one of the free RS232 programs to download any format you want instead of Hyperterminal.
    http://www.viddata.com/
    See RS232 Hex com.
    Max.
     
  10. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Doesn't the C compiler have a function to convert byte to ASCII Hex? That would make your code so much better.

    Or you could use a lookup table;
    ascii_data[16]
    containing the 16 chars 0-9 and A-F.
     
    djsfantasi likes this.
  11. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,809
    834
    Almost, if you include the next line. Missed that when I was trying to figure out how he was reading the ADC. I first thought he was reading the ADC twice, but now see ACC is the last reading. Still not clear on the actual read function, but as long as ACC contains the last ADC value after the call to adc().

    However, I think I see the problem. The line
    Code ( (Unknown Language)):
    1. SBUF=x(i);
    should use the variable j. The previous FOR loop leaves the value of i=2. Then, before the j FOR loop, x(2)=0x54 is executed. In the j FOR loop, x(2) is moved to SBUF repeatedly, and the ASCII values expected in x(0) and x(1) never get sent. This is consistent with the behavior the OP reported.

    Also, I totally agree with tshuck's observation. CASE 1011 is testing for decimal one thousand eleven, not decimal 11, which corresponds to 0x0B.

    RB's suggestions are excellent. There are many ways to code a problem, and only by coding yourself and reading other's code will you learn. In fact, there was one line where I thought you were going to define a lookup table, but…
     
    Last edited: Apr 30, 2014
  12. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    Thanks for ur advice.
    I am attaching the code i wrote. when I execute it only T (just to differentiate between each transmission) is displayed. so please help me out... Thanks in advance

    Code ( (Unknown Language)):
    1.  
    2. #include<reg51.h>
    3. #define input P1 //Input port to read the values of ADc
    4. sbit wr= P0^1; // Write pin. It is used to start the conversion.
    5. sbit rd= P0^0; // Read pin. It is used to extract the data from internal register to the output pins of ADC.
    6. sbit intr= P0^2;
    7. void delay(unsigned int msec ) // The delay function provides delay in msec.
    8. { int i,j ;
    9. for(i=0;i<msec;i++) for(j=0; j<1275; j++);
    10. }
    11.  
    12. void adc() // Function to read the values from ADC and store it accumulator.
    13. {
    14. rd=1;
    15. wr=0;
    16. delay(1);
    17. wr=1;
    18. while(intr==1);
    19. rd=0;
    20. ACC=input;
    21. delay(1);
    22. intr=1;
    23. }
    24. void main()
    25. { unsigned char a,b,c,d,i,j,x[3],z[2];
    26. input=0xff;
    27. while(1)
    28. { adc();
    29. delay(1);
    30. a=ACC;
    31. b=ACC;
    32. c=a&0x0F;
    33. d=b&0xF0;
    34. d=d>>4;
    35. z[0]=d;
    36. z[1]=c;
    37. delay(1);
    38. for(i=0;i<=1;i++)
    39. {
    40. switch(z[i])
    41. {
    42. case 0000:
    43. x[i]=0x30;
    44. break;
    45. case 0001:
    46. x[i]=0x31;
    47. break;
    48. case 0010:
    49. x[i]=0x32;
    50. break;
    51. case 0011:
    52. x[i]=0x33;
    53. break;
    54. case 0100:
    55. x[i]=0x34;
    56. break;
    57. case 0101:
    58. x[i]=0x35;
    59. break;
    60. case 0110:
    61. x[i]=0x36;
    62. break;
    63. case 0111:
    64. x[i]=0x37;
    65. break;
    66. case 1000:
    67. x[i]=0x38;
    68. break;
    69. case 1001:
    70. x[i]=0x39;
    71. break;
    72. case 1010:
    73. x[i]=0x41;
    74. break;
    75. case 1011:
    76. x[i]=0x42;
    77. break;
    78. case 1100:
    79. x[i]=0x43;
    80. break;
    81. case 1101:
    82. x[i]=0x44;
    83. break;
    84. case 1110:
    85. x[i]=0x45;
    86. break;
    87. case 1111:
    88. x[i]=0x46;
    89. break;
    90. }}
    91. x[2]=0x54;
    92. delay(1);
    93. TMOD=0x20;
    94. TH1=0xFD;
    95. SCON=0x50;
    96. TR1=1;
    97. for(j=0;j<=3;j++)
    98. {
    99. SBUF=x[i];
    100. while(TI==0);
    101. TI=0;
    102. delay(1);
    103. }
    104. }
    105. }
    106. [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
     
    Last edited by a moderator: May 4, 2014
  13. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    Thank u so much.. I changed the variable from i to j in SBUF= x .. But the problem is I am getting 00T even if i vary the adc.adc working properly may be some problem with program.. I am posting my modified program

    Code ( (Unknown Language)):
    1.  
    2. #include<reg51.h>
    3. #define input P1 //Input port to read the values of ADc
    4. sbit wr= P0^1;    // Write pin. It is used to start the conversion.
    5. sbit rd= P0^0;    // Read pin. It is used to extract the data from internal register to the output pins of ADC.
    6. sbit intr= P0^2;
    7. void delay(unsigned int msec )     // The delay function provides delay in msec.
    8. { int i,j ;
    9. for(i=0;i<msec;i++) for(j=0; j<1275; j++);
    10. }
    11.  
    12. void adc()          // Function to read the values from ADC and store it accumulator.
    13. {
    14. rd=1;
    15. wr=0;
    16. delay(1);
    17. wr=1;
    18. while(intr==1);
    19. rd=0;
    20. ACC=input;
    21. delay(1);
    22. intr=1;
    23. }
    24. void main()
    25. { unsigned int a,b,c,d,i,z[3],x[4],j;
    26. input=0xff;      
    27. while(1)
    28. { adc();
    29. delay(1);
    30. a=ACC;
    31. b=ACC;
    32. c=a&0x0F;
    33. d=b&0xF0;
    34. d=d>>4;
    35. z[0]=d;
    36. z[1]=c;
    37. delay(1);
    38. for(i=0;i<=1;i++)
    39. {
    40. switch(z[i])
    41. {
    42. case (0):
    43. x[i]=0x30;
    44. break;
    45. case (1):
    46. x[i]=0x31;
    47. break;
    48. case (2):
    49. x[i]=0x32;
    50. break;
    51. case (3):
    52. x[i]=0x33;
    53. break;
    54. case (4):
    55. x[i]=0x34;
    56. break;
    57. case (5):
    58. x[i]=0x35;
    59. break;
    60. case (6):
    61. x[i]=0x36;
    62. break;
    63. case (7):
    64. x[i]=0x37;
    65. break;
    66. case (8):
    67. x[i]=0x38;
    68. break;
    69. case (9):
    70. x[i]=0x39;
    71. break;
    72. case (10):
    73. x[i]=0x41;
    74. break;
    75. case (11):
    76. x[i]=0x42;
    77. break;
    78. case (12):
    79. x[i]=0x43;
    80. break;
    81. case (13):
    82. x[i]=0x44;
    83. break;
    84. case (14):
    85. x[i]=0x45;
    86. break;
    87. case (15):
    88. x[i]=0x46;
    89.  
    90. }}
    91. x[2]=0x54; // ASCII value for T just to differeciate between each transmission;
    92. delay(1);
    93. TMOD=0x20;
    94. TH1=0xFD;
    95. SCON=0x50;
    96. TR1=1;
    97. for(j=0;j<=3;j++)
    98. {
    99. SBUF=x[j];
    100. while(TI==0);
    101. TI=0;
    102. delay(1);
    103. }
    104. }
    105. }
    106. [/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]
     
    Last edited by a moderator: May 4, 2014
  14. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    You do realize that your code doesn't just magically appear in code tags(which provides a special formatting to code so it's easier to read), right? Bertus is constantly modifying your posts to do us and (by extension) you a favor. Please use code tags when you post your code(either click the "#" button while posting, or write [code ] & [/code ], without the space, around your code) so the forum knows how to format it. It is quite annoying to attempt read it without the formatting.

    That said, have you tried putting fixed values for your ADC results? That way you can tell if it is an error in your transmission/formatting code, or your ADC.

    Try the following(notice the use of code tags changes the formatting making it easier to read?;)):
    Code ( (Unknown Language)):
    1. #include<reg51.h>
    2. #define input P1 //Input port to read the values of ADc
    3. sbit wr= P0^1;    // Write pin. It is used to start the conversion.
    4. sbit rd= P0^0;    // Read pin. It is used to extract the data from internal register to the output pins of ADC.
    5. sbit intr= P0^2;
    6. void delay(unsigned int msec )     // The delay function provides delay in msec.
    7. {
    8.     int i,j ;
    9.     for(i=0;i<msec;i++)
    10.         for(j=0; j<1275; j++);
    11. }
    12.  
    13. void adc()          // Function to read the values from ADC and store it accumulator.
    14. {
    15.     rd=1;
    16.     wr=0;
    17.     delay(1);
    18.     wr=1;
    19.     while(intr==1);
    20.     rd=0;
    21.     ACC=input;
    22.     delay(1);
    23.     intr=1;
    24. }
    25. void main()
    26. {
    27.     unsigned int a,b,c,d,i,z[3],x[4],j;
    28.     input=0xff;      
    29.     while(1)
    30.     {
    31.         adc();
    32.         delay(1);
    33.         //Uncomment the following lines to use the ADC results
    34.         //a=ACC;
    35.         //b=ACC;
    36.         a=0x7F;
    37.         b=a;
    38.         c=a&0x0F;
    39.         d=b&0xF0;
    40.         d=d>>4;
    41.         z[0]=d;
    42.         z[1]=c;
    43.         delay(1);
    44.         for(i=0;i<=1;i++)
    45.         {
    46.             switch(z[i])
    47.             {
    48.                 case (0):
    49.                 {
    50.                     x[i]=0x30;
    51.                     break;
    52.                 }
    53.                 case (1):
    54.                 {
    55.                     x[i]=0x31;
    56.                     break;
    57.                 }
    58.                 case (2):
    59.                 {
    60.                     x[i]=0x32;
    61.                     break;
    62.                 }
    63.                 case (3):
    64.                 {
    65.                     x[i]=0x33;
    66.                     break;
    67.                 }
    68.                 case (4):
    69.                 {
    70.                     x[i]=0x34;
    71.                     break;
    72.                 }
    73.                 case (5):
    74.                 {
    75.                     x[i]=0x35;
    76.                     break;
    77.                 }
    78.                 case (6):
    79.                 {
    80.                     x[i]=0x36;
    81.                     break;
    82.                 }
    83.                 case (7):
    84.                 {
    85.                     x[i]=0x37;
    86.                     break;
    87.                 }
    88.                 case (8):
    89.                 {
    90.                     x[i]=0x38;
    91.                     break;
    92.                 }
    93.                 case (9):
    94.                 {
    95.                     x[i]=0x39;
    96.                     break;
    97.                 }
    98.                 case (10):
    99.                 {
    100.                     x[i]=0x41;
    101.                     break;
    102.                 }
    103.                 case (11):
    104.                 {
    105.                     x[i]=0x42;
    106.                     break;
    107.                 }
    108.                 case (12):
    109.                 {
    110.                     x[i]=0x43;
    111.                     break;
    112.                 }
    113.                 case (13):
    114.                 {
    115.                     x[i]=0x44;
    116.                     break;
    117.                 }
    118.                 case (14):
    119.                 {
    120.                     x[i]=0x45;
    121.                     break;
    122.                 }
    123.                 case (15):
    124.                 {
    125.                     x[i]=0x46;
    126.                     break;
    127.                 }
    128.  
    129.             }
    130.         }
    131.         x[2]=0x54; // ASCII value for T just to differeciate between each transmission;
    132.         delay(1);
    133.         TMOD=0x20;
    134.         TH1=0xFD;
    135.         SCON=0x50;
    136.         TR1=1;
    137.         for(j=0;j<=3;j++)
    138.         {
    139.             SBUF=x[j];
    140.             while(TI==0);
    141.             TI=0;
    142.             delay(1);
    143.         }
    144.     }
    145. }[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]


    Also note the indentation that makes it easier to read and the addition of curly braces on your case statements.

    You should see "7FT".
     
    tharunmalli likes this.
  15. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    I really don't like that huge ugly switch case statement with "magic numbers" for the ascii text characters.

    Why not use a lookup table like this;
    Code ( (Unknown Language)):
    1.  
    2. char ascii_table[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    3.  
    4.  
    5.   // this now replaces your massive 16 element switch/case statement;
    6.   x[i] = ascii_data[z[i]];
    7. [/i][/i]

    :)
     
  16. tharunmalli

    Thread Starter New Member

    Apr 7, 2014
    12
    0
    Thanks to every one.....Finally I got the output....
     
  17. MrChips

    Moderator

    Oct 2, 2009
    12,442
    3,361
    There are two simple ways to convert from 4-bit binary to ASCII.

    1) The first method consists of examining the ASCII codes for 0-9 and A-F.

    0 = 48
    :
    9 = 57

    A = 65

    Hence the mathematical algorithm is

    ADD 48 to 4-bit binary
    if the result is greater than 57, ADD 7

    2) Use a lookup table such as

    char hex_char[] = "0123456789ABCDEF";
     
Loading...