IN THE KNOW
Go to bottomPage: 12
TOPIC:
*
#906
ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 1
Hi,

I am wondering if anyone has any sample code that they can share on doing a single shot ADC. I am developing a battery powered Zmotion application and would like to report back the voltage level of the battery when asked.

Currently planning on using Pin 16 - PC0/ANA4 as input to the voltage divider on the battery..
Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#909
Re:ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 1
I been working on sample code and haven't had much luck. Here is what I have so far. Any ideal of what I am doing wrong?

Code:

 

#include <ez8.h>
#include <defines.h>


#define ADCCTL0 (*(unsigned char volatile far*)0xF70)              // Reset = 0x00 ADC Control 0
#define ADCCTL1 (*(unsigned char volatile far*)0xF71)              // Reset = 0x00 ADC Control 1

#define ADCD_H  (*(unsigned char volatile far*)0xF72)              // Reset = 0xXX ADC Data High
#define ADCD_L  (*(unsigned char volatile far*)0xF73)              // Reset = 0xXX ADC Data Low


/**********************************************************************************************************
**  init_PORTC0()
**
**  Initialize Port C0 (ADA0) to be ADC for single shot.
**
**  Step 1:   Enable port for input
**  Step 2:  Write to ADC Contro / Status register.  ADC
**
***********************************************************************************************************/

void init_PORTC0(void) {

  
  PCADDR  = 0x02;                     //Port C Alternate Function
  PCCTL &=  0x02;                      //Select Alternate Function

  PCADDR  = 0x01;                    //Port C Data Direction
  PCCTL |= 0x01;                     //Port C bit 1 is configured as Input

  
  
  PCADDR = 0x00;                    // close off changes to PC
  
  
  
 } /*init_PORTC0*/
 
 

/*******************************************************************************
** void main(void)
**
** Main Routine for the program.   This program runs in conjunction with debug
** to view the data generated from the ADC.
**
********************************************************************************/

void main(void) {


UINT8 ADChigh=0x00;
UINT8 ADClow=0x00;
UINT16 ADCdata;

init_PORTC0();

ADCCTL1 &= 0x78;      // 0XXX X000 (ANA0)  :   
                     //  7>REFSEL_H=0, 6:3>RESERVED,  2:0> BUFMODE=000 (single-ended, unbuffered)
                         

ADCCTL0 = 0xC0;      //  1100 0000 (ANA0)    Internal 1v ref, 
//  7>CEN = 1,  6>REFSEL_L=1, 5>REFOUT=0, 4>CONT=0, 3:0>000 (ANA0)

    
while(ADCCTL0 & 0x80);  // Wait until ADC is finish (when CEN goes to low)

ADChigh =  ADCD_H;
ADClow =  ADCD_L;

if (!(ADClow & 0x01)) {  // If OVF is not 1, then data is good.  

ADCdata = (ADChigh <<8)| (ADClow); //ADC output word
ADCdata = (ADCdata >> 3) & 0xFFF; //12-bits ADC 


} else {   // Bad data.. set to FFFF.
ADCdata = 0xFFFF;    // Max out

}



}  // END OF MAIN
 

Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#910
Re:ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 1
I been working on sample code and haven't had much luck. Here is what I have so far. Any ideal of what I am doing wrong?

Code:

 

#include <ez8.h>
#include <defines.h>


#define ADCCTL0 (*(unsigned char volatile far*)0xF70)              // Reset = 0x00 ADC Control 0
#define ADCCTL1 (*(unsigned char volatile far*)0xF71)              // Reset = 0x00 ADC Control 1

#define ADCD_H  (*(unsigned char volatile far*)0xF72)              // Reset = 0xXX ADC Data High
#define ADCD_L  (*(unsigned char volatile far*)0xF73)              // Reset = 0xXX ADC Data Low


/**********************************************************************************************************
**  init_PORTC0()
**
**  Initialize Port C0 (ADA0) to be ADC for single shot.
**
**  Step 1:   Enable port for input
**  Step 2:  Write to ADC Contro / Status register.  ADC
**
***********************************************************************************************************/

void init_PORTC0(void) {

  
  PCADDR  = 0x02;                     //Port C Alternate Function
  PCCTL &=  0x02;                      //Select Alternate Function

  PCADDR  = 0x01;                    //Port C Data Direction
  PCCTL |= 0x01;                     //Port C bit 1 is configured as Input

  
  
  PCADDR = 0x00;                    // close off changes to PC
  
  
  
 } /*init_PORTC0*/
 
 

/*******************************************************************************
** void main(void)
**
** Main Routine for the program.   This program runs in conjunction with debug
** to view the data generated from the ADC.
**
********************************************************************************/

void main(void) {


UINT8 ADChigh=0x00;
UINT8 ADClow=0x00;
UINT16 ADCdata;

init_PORTC0();

ADCCTL1 &= 0x78;      // 0XXX X000 (ANA0)  :   
                     //  7>REFSEL_H=0, 6:3>RESERVED,  2:0> BUFMODE=000 (single-ended, unbuffered)
                         

ADCCTL0 = 0xC0;      //  1100 0000 (ANA0)    Internal 1v ref, 
//  7>CEN = 1,  6>REFSEL_L=1, 5>REFOUT=0, 4>CONT=0, 3:0>000 (ANA0)

    
while(ADCCTL0 & 0x80);  // Wait until ADC is finish (when CEN goes to low)

ADChigh =  ADCD_H;
ADClow =  ADCD_L;

if (!(ADClow & 0x01)) {  // If OVF is not 1, then data is good.  

ADCdata = (ADChigh <<8)| (ADClow); //ADC output word
ADCdata = (ADCdata >> 3) & 0xFFF; //12-bits ADC 


} else {   // Bad data.. set to FFFF.
ADCdata = 0xFFFF;    // Max out

}



}  // END OF MAIN
 

Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#911
Re:ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 4
Hi Don
Here is a really basic sample:

Code:


//Selected internal reference 2.0Volts default 
void init_adc(void)
{
ADCCTL0 = 0x00;  // ADC conversion disable,
//Select ANA0
//Internal reference voltage 2.0V
//Disable reference voltage out, single shot conversion

ADCCTL1 = 0x81; // Single-ended, buffered with unity gain
// Configure ANA0 - PB0 Alternate function 1
PBADDR = 0x02; //access to AF registers
PBCTL  |= 0x01; //Turn on AF Subset 1 for PB0
PBADDR = 0x00; // release access

}

int get_adcval()
{
int val;
ADCCTL0 |= 0x80; //Start the conversion

while (ADCCTL0 & 0x80) ; //Wait until it is clear
val = (ADCD_H << 8) | ADCD_L;
    
return val;
}


void main()
{
int val;
init_adc();

while (1)
{
val = get_adcval() & 0x0FFF;


}

}

Tom Ormiston (Admin)
Admin
Posts: 168
graph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#912
Re:ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 4
Don,
I believe your problem is in your pin initialization.

PCADDR = 0x02;
PCCTL |= 0x01; //Set PC0 to alternate function (ANA4)

You are also initializing your ADC control registers differently that you comments in main().

ADCCTL1 = 0x00; //matches your comments

ADCCTL0 = 0xC4; //matches your comments only selecting ANA4


Let me know if this doesn’t help.
Tom Ormiston (Admin)
Admin
Posts: 168
graph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#915
Re:ADC Sample Code Z8FS021A - Single Shot.. 1 Year, 5 Months ago Karma: 1
Thanks for the feedback on my code. I have incorporate the suggestions and attached is the code. I think I got the ADC working, but the results are not what I am expecting.

When I wire the ADC to GND, I would expect to get 0x0000, however, I am getting 0x1FF8. When I connect the ADC to a AA battery, voltage 1.59v, I get 0x0AE1. I would expect with 2v reference, I would receive 0x0CB8.

My calculations are simple: INT( 1.59v / 2.0v (max) * 4096) ==> HEX = 0x0CB8.

Do I have something wrong with my code or my calculations for ADC value?

Using PC0 (ANA4):

/**********************************************************************************************************
** Initialize Port PC0 (ADA4) to be ADC for single shot.
**
** Step 1: Enable port for input
** Step 2: Write to ADC Control / Status register 1. ADCCTL1
**
** 1 X X X X 0 0 0 where X is unknown.
**
** Bit 7 - REFSEL_H = 1 (10 for 2v internal reference model)
** Bit 6:3 - RESERVED
** Bit 2:0 - BUFMODE - 000 - Single ended, unbuffered
**
**
** Step 3: Write to ADCCTL0 1010 0100
** 7>CEN = 1, 6>REFSEL_L=1, 5>REFOUT=0, 4>CONT=0, 3:0>100 (ANA4)
** Bit 7 - CEN = 1 to start the ADC conversion. When 0, it stops.
** Bit 6 - REFSEL_L = 1 - (01 lower part 01 for 1v internal ref)
** Bit 5 - REFOUT = 1 Internal Reference
** Bit 4 - CONT - Conversion 0 for single shot
** Bit 3:0 - Analog Input
**
** Step 4: CEN remains 1 until completion of conversion
**
** Step 5: CEN turns to 0 when completion of conversion, ADCD_H (7:0) & ADCD_L (7:3) = value of ADC
**********************************************************************************************************/

#include <ez8.h>
#include <defines.h>




#define ADCCTL0 (*(unsigned char volatile far*)0xF70) // Reset = 0x00 ADC Control 0
#define ADCCTL1 (*(unsigned char volatile far*)0xF71) // Reset = 0x00 ADC Control 1

#define ADCD_H (*(unsigned char volatile far*)0xF72) // Reset = 0xXX ADC Data High
#define ADCD_L (*(unsigned char volatile far*)0xF73) // Reset = 0xXX ADC Data Low


/**********************************************************************************************************
** init_adc()
**
** Initialize PORTC0 for input using alternate function and configure the ADC
**
***********************************************************************************************************/

void init_adc(void) {

ADCCTL0 = 0x00; // ADC conversion disable,

ADCCTL1 = 0x80; //


PCADDR = 0x02; //Port C Alternate Function
PCCTL |= 0x01; //Select Alternate Function for PC0

PCADDR = 0x00; // close off changes to PC



} /*init_PORTC0*/


/*******************************************************************************
** void get_adcval()
**
** Return the ADC value in an integer. Test using GND and 1.5v battery.
**
********************************************************************************/

int get_adcval(void)
{
UINT16 val;

ADCCTL0 = 0xA4; // Define ADC Control Register 1010 0100 = A4
// 7 - 1 CEN - Set to 1 to start ADC conversion
// 6 - 1 REFSELL - Value = 0 (lower of 10 for 2v conversion)
// 5 - 1 REFOUT - Value = 1 - Internal ADC reference
// 4 - 1 CONT - Value = 0 for single shot
// 3:0: Using ANA4 - Value = 0100;




while (ADCCTL0 & 0x80) ; //Wait until it is clear
val = (ADCD_H << 8) | ADCD_L;

val = val >> 3; // Mask off lower 3 bits and shift over 3 bits.

return val;
}



/*******************************************************************************
** void main(void)
**
** Main Routine for the program. This program runs in conjunction with debug
** to view the data generated from the ADC.
**
********************************************************************************/

void main(void) {


UINT16 val;
init_adc();

while (1)
{
val = get_adcval();

}


} // END OF MAIN
Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
Go to topPage: 12