2 pins ADC conversion pic18f4550

Thread Starter

AnnePriscilla

Joined Apr 11, 2016
4
Hey guys!

I've an assignment that requires me to connect 2 sensors on the same PORT A. So I was thinking of using bit0 and bit1 for the ADC conversion. I looked through all the sample codes and my school's textbook, however, can't find a way to configure 2 pins at the same time. Currently I am using Mplabv8.63 compiler.

So far, I have only managed to get my temperature sensor(Lm35) working and to display the output reading. However, I can't seem to integrate another sensor onto the same codes. This codes were taken from http://forum.allaboutcircuits.com/threads/lm35-temperature-sensor.59885/


  1. //Temperature Sensor - Convert the Analog signal to Digital and Display it to the LCD Display Board

  2. #include <p18F4550.h>
  3. #include <delays.h>
  4. #include "lcd.h"
  5. // ************** ErnieM Addition Start ****************
  6. #include <stdlib.h> // added to get itoa() function to convert t into a string
  7. // ************** ErnieM Addition End ****************



  8. // Include this when using Bootloader Program ================================
  9. #pragma udata

  10. extern void _startup (void); // See c018i.c in your C18 compiler dir
  11. #pragma code _RESET_INTERRUPT_VECTOR = 0x000800
  12. void _reset (void)
  13. {
  14. _asm goto _startup _endasm
  15. }
  16. #pragma code

  17. #pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
  18. void _high_ISR (void)
  19. {
  20. ;
  21. }

  22. #pragma code _LOW_INTERRUPT_VECTOR = 0x000818
  23. void _low_ISR (void)
  24. {
  25. ;
  26. }
  27. #pragma code

  28. #pragma code

  29. // additional codes ends here ===============================================================

  30. // Your program declarations start here:====


  31. #define LCD_RS PORTDbits.RD6 // Register Select on LCD
  32. #define LCD_EN PORTDbits.RD4 // Enable on LCD controller
  33. #define LCD_WR PORTDbits.RD5 // Write on LCD controller


  34. //--- Function for writing a command byte to the LCD in 4 bit mode -------------

  35. void lcd_write_cmd(signed char cmd)
  36. {
  37. unsigned char temp2;
  38. LCD_RS = 0; // Select LCD for command mode
  39. Delay10TCYx(4); // 40us delay for LCD to settle down
  40. temp2 = cmd;
  41. temp2 = temp2 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
  42. PORTD = temp2 & 0x0F; // Output to PORTD which is connected to LCD

  43. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing
  44. lcd_strobe();
  45. Delay1KTCYx(10); // 10ms - Delay at least 1 ms after strobing

  46. temp2 = cmd; // Re-initialise temp2
  47. PORTD = temp2 & 0x0F; // Mask out upper 4 bits

  48. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing
  49. lcd_strobe();
  50. Delay1KTCYx(10); // 10ms - Delay at least 1 ms before strobing

  51. }

  52. //---- Function to write a character data to the LCD ---------------------------

  53. void lcd_write_data(char data)
  54. {
  55. char temp1;

  56. LCD_RS = 1; // Select LCD for data mode
  57. Delay10TCYx(4); // 40us delay for LCD to settle down

  58. temp1 = data;
  59. temp1 = temp1 >> 4;
  60. PORTD = temp1 & 0x0F;
  61. Delay1KTCYx(10);
  62. LCD_RS = 1;
  63. Delay1KTCYx(10); //_-_ strobe data in

  64. lcd_strobe();
  65. Delay1KTCYx(10);

  66. temp1 = data;
  67. PORTD = temp1 & 0x0F;
  68. Delay1KTCYx(10);
  69. LCD_RS = 1;
  70. Delay1KTCYx(10); //_-_ strobe data in

  71. lcd_strobe();
  72. Delay1KTCYx(10);
  73. }

  74. //-- Function to generate the strobe signal for command and character----------

  75. void lcd_strobe(void) // Generate the E pulse
  76. {
  77. LCD_EN = 1; // E = 0
  78. Delay1KTCYx(100); // 10ms delay for LCD_EN to settle
  79. LCD_EN = 0; // E = 1
  80. Delay1KTCYx(100); // 10ms delay for LCD_EN to settle
  81. }


  82. //---- Function to initialise LCD module ----------------------------------------
  83. void lcd_init(void)
  84. {
  85. TRISD = 0x00;
  86. PORTD = 0x00; // PORTD is connected to LCD data pin
  87. LCD_EN = 0;
  88. LCD_RS = 0; // Select LCD for command mode
  89. LCD_WR = 0; // Select LCD for write mode

  90. Delay10KTCYx(250); // Delay a total of 1 s for LCD module to
  91. Delay10KTCYx(250); //
  92. Delay10KTCYx(250); //
  93. Delay10KTCYx(250); // finish its own internal initialisation

  94. /* The data sheets warn that the LCD module may fail to initialise properly when
  95. power is first applied. This is particularly likely if the Vdd
  96. supply does not rise to its correct operating voltage quickly enough.

  97. It is recommended that after power is applied, a command sequence of
  98. 3 bytes of 30h be sent to the module. This will ensure that the module is in
  99. 8-bit mode and is properly initialised. Following this, the LCD module can be
  100. switched to 4-bit mode.
  101. */

  102. lcd_write_cmd(0x33);
  103. lcd_write_cmd(0x32);
  104. lcd_write_cmd(0x28); // 001010xx – Function Set instruction
  105. // DL=0 :4-bit interface,N=1 :2 lines,F=0 :5x7 dots

  106. lcd_write_cmd(0x0E); // 00001110 – Display On/Off Control instruction
  107. // D=1 :Display on,C=1 :Cursor on,B=0 :Cursor Blink on

  108. lcd_write_cmd(0x06); // 00000110 – Entry Mode Set instruction
  109. // I/D=1 :Increment Cursor position
  110. // S=0 : No display shift

  111. lcd_write_cmd(0x01); // 00000001 Clear Display instruction

  112. Delay1KTCYx(20); // 20 ms delay

  113. }

  114. void main(void)
  115. {
  116. // ************** ErnieM Addition Start ****************
  117. // add these variables
  118. char Buffer[10]; // buffer to hold your temperature character string
  119. unsigned int i; // index variable
  120. // moved your "t" variable up here, C18 wants to see variables defined at the
  121. // very start of a block. Other compilers let you make a definition anywhere,
  122. // this C28 compiler seems to want them up top like this
  123. unsigned int t; // variable for temperature
  124. // ************** ErnieM Addition End ****************

  125. // Do not remove these as well=============
  126. ADCON1 = 0x0F; // Configure PORTA to be digital I/O
  127. CMCON = 0x07;
  128. // ========================================
  129. // Your MAIN program Starts here: =========
  130. lcd_init(); // Initialise LCD module

  131. LCD_RS = 1; // Select LCD for character data mode
  132. Delay1KTCYx(1); // 1 ms delay

  133. /* Initialise analog to digital conversion setting */

  134. ADCON0 = 0b00000001; // bit5-2 0000 select channel 0 conversion
  135. // bit1 A/D conversion status bit
  136. // 1- GO to starts the conversion
  137. // 0 - DONE when A/D is completed
  138. // bit0 Set to 1 to power up A/D

  139. ADCON1 = 0b00001100; // bit5 reference is VSS
  140. // bit4 reference is VDD
  141. // bit3-0 AN2 to AN0 Analog, the rest Digital

  142. ADCON2 = 0b10010110; // bit7 : A/D Result Format. 0 Left, 1 Right justified ( Set it to 1, Right Justified)
  143. // bit5-3 : 010 acquisition time = 4 TAD
  144. // bit2-0 : 110 conversion clock = Tosc / 16
  145. // ************** ErnieM Addition Start ****************
  146. // I'm going to change your loops so it measures the temperature every second
  147. // then displays it.
  148. // for(;;)
  149. // {
  150. // ************** ErnieM Addition End ****************

  151. // ************** ErnieM Addition Start ****************
  152. // this code moved down below into the once a second loop
  153. // ADCON0bits.GO = 1; // This is bit2 of ADCON0, START CONVERSION NOW
  154. // while(ADCON0bits.GO == 1); // Waiting for DONE

  155. // t = (ADRES * 500) / 255; //Convert to Degree Celcius - ADRES (16bit) is the output of ADC
  156. // ************** ErnieM Addition End ****************
  157. // ************** ErnieM Addition Start ****************
  158. // removed this loop
  159. // while(1)
  160. // {
  161. // ************** ErnieM Addition End ****************
  162. lcd_write_cmd(0x80); // Move cursor to line 1 position 1

  163. lcd_write_data('T');
  164. lcd_write_data('E');
  165. lcd_write_data('M');
  166. lcd_write_data('P');
  167. lcd_write_data('E');
  168. lcd_write_data('R');
  169. lcd_write_data('A');
  170. lcd_write_data('T');
  171. lcd_write_data('U');
  172. lcd_write_data('R');
  173. lcd_write_data('E');
  174. lcd_write_data(':');
  175. // ************** ErnieM Addition Start ****************
  176. // HERE is where we'll loop
  177. while(1)
  178. {
  179. // measure temperature
  180. ADCON0bits.GO = 1; // This is bit2 of ADCON0, START CONVERSION NOW
  181. while(ADCON0bits.GO == 1); // Waiting for DONE
  182. t = (ADRES * 500) / 255; //Convert to Degree Celcius - ADRES (16bit) is the output of ADC
  183. lcd_write_cmd(0xC0); // Move cursor to line 2 position 1

  184. // lcd_write_data(t); // Display the temperature

  185. // we can't just drint the integer, need to first convert the number into a character string
  186. // convert t to a string
  187. itoa(t,Buffer);
  188. // print that string!
  189. i = 0;
  190. while (Buffer != 0) lcd_write_data(Buffer[i++]);
    [*]

    [*]

    [*] lcd_write_data(0xDF);
    [*] lcd_write_data('C');
    [*]

    [*] Delay10KTCYx(250); // Delay a total of 1 s
    [*] Delay10KTCYx(250); //
    [*] Delay10KTCYx(250); //
    [*] Delay10KTCYx(250); // so the screen doesn't "flash" too much on updates
    [*]// for the future: Save the old value of t, and only update the screen
    [*]// when a new temperature is measured. That way you don't need that 1 sec delay
    [*]
    [*]

    [*] }
    [*]// ************** ErnieM Addition End ****************
    [*]

    [*]
    [*]

    [*]
    [*]// ************** ErnieM Addition Start ****************
    [*]// removed infinite "stop here" loop
    [*]// while(1); //stop here for now
    [*]

    [*]

    [*]// }
    [*]// }
    [*]

    [*]// ************** ErnieM Addition End ****************
    [*]} // end of main()


Can somebody please advise me on how to configure another pin so I can add another sensor on the same port.(If it's even possible)

Thankyou!
 

Thread Starter

AnnePriscilla

Joined Apr 11, 2016
4
Hey!
You select the channel in ADCON0,
Thanks for the response. I wanna make use of pin0 and pin1. So far I've got this:

int value1, value2; //to store value 1 and 2
ADCON1 = 0x0D; // to select AN0(RA0) and AN1(RA1) as analog input
ADCON2 = 0x__; // i dunno the value but set as FOSC/4 and right justified
ADCON0 = 0x01; //select AN0
ADCON0bits.GO = 1; //start conversion
while(ADCON0bits.GO == 1); //wait for conversion to finish
value1 = (ADRESH*256)+ADRESL;
ADCON0 = 0x05; //select AN1(RA1)
ADCON0bits.GO = 1; //start conversion
while(ADCON0bits.GO == 1); //wait for conversion to finish
value2 = (ADRESH*256)+ADRESL;

This way value 1 and 2 contain the ADC values for AN0 and AN1 respectively.
 
Top