Passing two variables back from a Hi-Tech C function

Discussion in 'Embedded Systems and Microcontrollers' started by Guinness1759, Jun 7, 2011.

  1. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    64
    0
    Here's my code:

    Code ( (Unknown Language)):
    1.  
    2. unsigned char, unsigned char
    3. get_temp() {
    4.  
    5.         ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
    6.         while(ADGO)
    7.             continue;   // wait for conversion complete
    8.         temph = ADRESH;
    9.         templ = ADRESL;
    10.         return ADRESH, ADRESL;
    11. }
    12.  
    This code gives me numerous errors. Works fine if I want to return only one variable. Looked through a lot of example code and can't find anywhere, where they return 2 variables.
     
  2. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    You have to provide an identifier for your variable.
    Here is how we declare and define a variable.
    Code ( (Unknown Language)):
    1.  
    2. unsigned char var1 ;
    3. unsigned char var2 ;
    4.  
    .
    And always end your statement with a semicolon in C.

    This is how your code should be
    Code ( (Unknown Language)):
    1.  
    2.  
    3. unsigned char temph;
    4. unsigned char templ;
    5.  
    6. void get_temp()
    7. {
    8. ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
    9. while(ADGO)
    10. continue; // wait for conversion complete
    11. temph = ADRESH;
    12. templ = ADRESL;
    13.  
    14. }
    15.  
     
    Guinness1759 likes this.
  3. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    Or your could be like this

    Code ( (Unknown Language)):
    1.  
    2. #define Value() ((((unsigned int)ADRESH)<<8)|(ADRESL))
    3.  
    4. unsigned char temph;
    5. unsigned char templ;
    6.  
    7. unsigned int get_temp()
    8. {
    9. ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
    10. while(ADGO)
    11. continue; // wait for conversion complete
    12. temph = ADRESH;
    13. templ = ADRESL;
    14. return Value();
    15. }
    16.  
    I have not removed the variables temph and templ because they may be used for some purpose.Here I have used a macro "Value()" to get the full 16 bits value of ADC in an unsigned int var.

    Good Luck
     
    Guinness1759 likes this.
  4. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    64
    0
    Is there a way to get it to return two 8 bit values? I would like to stick with 8 bits because my serial function accepts 8 bit values. Thanks.
     
  5. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    You have not specified your mcu, but as it’s hi tech C and you mentioned 8 bits so I assume you are using any Microchip's 8 bits mcu like PIC16Fxxx, PIC18Fxxx or etc.

    Normally in 8bit PIC you will get a 10bit ADC module i.e.. when you get the ADC value the 10bit value is stored in 2 registers ADRESL and ADRESH, the low 8 bits will be in register ADRESL and the remaining higher 2 bits will be in ADRESH.



    You can follow the first code...

    Code ( (Unknown Language)):
    1.  
    2. [COLOR=black][FONT=Verdana]unsigned char temph;[/FONT][/COLOR]
    3. [FONT=Verdana][COLOR=black]unsigned char templ;[/COLOR][/FONT]
    4.  
    5. [FONT=Verdana][COLOR=black]void get_temp() [/COLOR][/FONT]
    6. [FONT=Verdana][COLOR=black]{[/COLOR][/FONT]
    7. [FONT=Verdana][COLOR=black]ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)[/COLOR][/FONT]
    8. [FONT=Verdana][COLOR=black]while(ADGO)[/COLOR][/FONT]
    9. [FONT=Verdana][COLOR=black]continue; // wait for conversion complete[/COLOR][/FONT]
    10. [FONT=Verdana][COLOR=black]temph = ADRESH;[/COLOR][/FONT]
    11. [FONT=Verdana][COLOR=black]templ = ADRESL;[/COLOR][/FONT]
    12. [FONT=Verdana][COLOR=black]}[/COLOR][/FONT]
    13.  
    After you call the get_temp() function, the low 8 bits value of ADRESL is stored in the 8 bits(i.e.. unsigned char) variable named templ and ADC's higher 2 bits value from ADRESH is stored in the 8 bits variable temph.Now you can use these to 8 bits variable templ and temph where you want, may be your serial function.

    Good Luck
     
    Guinness1759 likes this.
  6. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    64
    0
    Ok, so lets say I need to run the function 4 times before I send the serial data, because I'm collecting 4 temperature values.

    get_temp()
    temp1h = temph;
    temp1l = templ;
    get_temp()
    temp2h = temph;
    temp2l = templ;
    get_temp()
    temp3h = temph;
    temp3l = templ;
    get_temp()
    temp4h = temph;
    temp4l = templ;

    It would be nice to be able to condense it to 4 lines of code such as

    temp1h, temp1l = get_temp();
    temp2h, temp2l = get_temp();
    temp3h, temp3l = get_temp();
    temp4h, temp4l = get_temp();

    Or something like that. Not a big deal, just semantics. If I need to use a 16 bit variable, then I'll just stick with the longer code I guess.
     
  7. John P

    AAC Fanatic!

    Oct 14, 2008
    1,671
    241
    This seems easiest if you declare a 2-element array and pass it to the function, then let the function load it.

    Code ( (Unknown Language)):
    1.  
    2. unsigned char temp[2];
    3.  
    4. get_temp(temp);
    5.  
    If you want to call it 4 times, then it could be:
    Code ( (Unknown Language)):
    1.  
    2. unsigned char temp[4][2];
    3.  
    4. get_temp(temp[0]);
    5. get_temp(temp[1]);
    6. get_temp(temp[2]);
    7. get_temp(temp[3]);
    8.  
    And the function would be:
    Code ( (Unknown Language)):
    1.  
    2. void get_temp(unsigned char *tmp)
    3. {
    4. ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
    5. while(ADGO)
    6. continue; // wait for conversion complete
    7. *tmp = ADRESH;
    8. *(tmp+1) = ADRESL;
    9. }
    10.  
    I think that's right.
     
    Guinness1759 likes this.
  8. someonesdad

    Senior Member

    Jul 7, 2009
    1,585
    141
    C is a relatively primitive language and you can't pass more than one object back from a function. Thus, you have to use some kind of container; arrays, structs, and unions (and objects in C++) are the usual tools. Or, declare a structure with static scope and pass back a pointer to it.
     
    Guinness1759 likes this.
  9. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    John P have showed a solution which could be used i.e.. array stuff.
    someonesdad also showed some ways to achieve the goal,but I will point out the last way he showed.

    Or why not pass pointers of the variable to the function like this.

    First create your four variables,I dont think you will need four variables as two is enough but as your logic I am creating the four variables.
    Code ( (Unknown Language)):
    1.  
    2. unsigned char temp1l,temp1h,temp2l,temp2h,temp3l,temp3h,temp4l,temp4h;
    3.  
    Then create your function like this.
    Code ( (Unknown Language)):
    1.  
    2. void get_temp(unsigned char * templ,unsigned char * temph)
    3. {
    4. ADCON0 = 0b00000111; //  Start ADC and Set Channel to AN1 (RA1)
    5. while(ADGO)
    6. continue; // wait for conversion complete
    7. *temph = ADRESH;
    8. *templ = ADRESL;
    9. }
    Now you can use this function by providing the address of the two variables as the parameters and after the call ends the two variables will contain the value of the ADC.

    For example you want the ADC value to be stored in temp1l and temp1h....
    Code ( (Unknown Language)):
    1. get_temp(&temp1l,&temp1h);
    Or in your words
    Code ( (Unknown Language)):
    1.  
    2. get_temp(&temp1l,&temp1h);
    3. get_temp(&temp2l,&temp2h);
    4. get_temp(&temp3l,&temp3h);
    5. get_temp(&temp4l,&temp4h);
    6.  
    Good Luck
     
    Guinness1759 likes this.
  10. John P

    AAC Fanatic!

    Oct 14, 2008
    1,671
    241
    Where I suggested passing the address of a 2-element array, you're saying use 2 individual bytes. Either should work.

    But the quick-and-dirty way to do it is to use global variables and pass nothing at all. Just load the variables and the job is done.
     
    Guinness1759 likes this.
  11. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    64
    0
    edit: Thanks everyone for the help, I had to move the functions part of my code to the beginning of my file, to avoid declaration errors. Now everything should be working fine.
     
    Last edited: Jun 8, 2011
Loading...