problem with ADC on MC9S08DZ128

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem with ADC on MC9S08DZ128

1,957 Views
hasaur
Contributor II

Hello.

 

I am working on the MC9S08DZ128 ADC.

I am facing something strange : when the program runs itself, there in no problem with the value (in my case, I have for example (on 12bits) 0x587). But when I put a breakpoint before the ADC instruction and after the conversion is complete, the value isn't right (it becomes 0x161).

Is there an explanation ? Is it possible to break before and after, to see the value ?

 

Thank you in advance for your help.

Labels (1)
7 Replies

1,072 Views
bigmac
Specialist III

Hello,

 

Is it possible that the break point occurs after the very first conversion following power up?  Normally the result of the first conversion should be discarded.  Possibly Vdd may not have stabilised prior to this conversion, especially if large bulk capacitors are present at the power supply output.  Make sure you are in single conversion mode.

 

Also what do you mean by "ADC instruction"?  The instruction to read the ADC data register will still need to occur prior to the break, or within the break.

 

Regards,

Mac

 

0 Kudos
Reply

1,072 Views
hasaur
Contributor II

Hello, thank you for your interest.

The result of the conversion is always false when I use breakpoints, not just when power up. I am in single mode.

I put a breakpoint before the function that starts conversion and read the result and another breakpoint after reading the result.

 

I have another problem but I don't know if it could be my code or the schematic of the board. I am using the ADC on 3 channels : PTA4, PTA5 and PTA6. On PTA6, I have a temperature sensor (STLM20), on PTA4 I am converting voltage.

The problem is that, when something change (voltage or temperature), the other channel change too. When temperature increase, the voltage measured increases too.

Is there a reason to that ? could it be my code ? Or is it just the board that has problem ? Is it possible to make that by code ?

 

Thank you very much.

0 Kudos
Reply

1,072 Views
peg
Senior Contributor IV

Hi,

 

Perhaps you could post the relevant section of code and where you are placing the breakpoints.

I wonder whether your problem could be too high impedance of your analogue sources. With high impedance the result can tend towards the previous conversions value.

 

0 Kudos
Reply

1,072 Views
rocco
Senior Contributor II

 


Peg wrote:
I wonder whether your problem could be too high impedance of your analogue sources.

I was wondering the same thing. Are your analog inputs buffered? The inputs to the AtoD are not very high impedance, and I have had problems with cross-channel effects when using 50k pots as inputs. 5k pots worked much better, but the cross-channel problems did not go away completely until I buffered the inputs with op-amps.

 

0 Kudos
Reply

1,072 Views
bigmac
Specialist III

Hello,

 

Rocco, I believe that the cross channel interference that you describe is not due to low input resistance of the ADC module, but due to its capacitance, some of which will be present after the channel multiplexer.  A high source resistance will increase the time constant of the CR circuit, and full settling may not occur during the sample interval.

 

The problem would be exacerbated with a number of channels being read in succession, since the starting voltage across  the capacitance would be the input level of the previous channel, that may be significantly different from the current input voltage.

 

For a worst case 1 LSB settling error, the input time constant should be a fraction of the sample interval by the following factors.  I might assume that the input capacitance would be of the order of 5pF.  The total source resistance would also include the series resistance of the input multiplexer.

Time constant CR <= Tsamp / k

8-bit:    k = 5.5

10-bit:  k = 6.9

12-bit:  k = 8.3

 

With a moderately high source resistance (maybe 5k or greater), the first step would be to choose the long sample interval.  Placing a capacitor, say 100n, at each input pin may also help provided rapid fluctuations of the input levels are not encountered. An additional approach would be to take two readings in succession for each channel, and discard the first reading.  If significant errors persist, the additional hardware buffering would need to be considered.

 

Regards,

Mac

 

1,072 Views
hasaur
Contributor II

Thank you all for your responses.

Here is my code if it could help.

 

 

/* affectation des broches */# define channelT 7 /**< broche pour la mesure de température : PTA6 */# define channelV 5 /**< broche pour la mesure de tension : PTA4 */# define channelI 6 /**< broche pour la mesure de courant : PTA5 *//*** ===================================================================**     Method      :  AD_Init (component ADC)****     Description :**         Initializes the associated peripheral(s) and the bean's **         internal variables. The method is called automatically as a **         part of the application initialization code.**         This method is internal. It is used by Processor Expert only.** ===================================================================*//*! \fn void AD_Init(void)    \brief fonction d'initialisation du convertisseur analogique numérique*/void AD_Init(void){  /* ADCSC1: COCO=0,AIEN=0,ADCO=0,ADCH4=1,ADCH3=1,ADCH2=1,ADCH1=1,ADCH0=1 */  setReg8(ADCSC1, 0x1F);               /* Disable the module */   /* ADCSC2: ADACT=0,ADTRG=0,ACFE=0,ACFGT=0,??=0,??=0,??=0,??=0 */  setReg8(ADCSC2, 0x00);               /* Disable HW trigger and autocompare */   OutFlg = 0;                          /* No measured value */  SumChan = 0;  ModeFlg = STOP;                      /* Device isn't running */  /* ADCCFG: ADLPC=1,ADIV1=0,ADIV0=1,ADLSMP=0,MODE1=0,MODE0=1,ADICLK1=0,ADICLK0=0 */  setReg8(ADCCFG, 0xA4);               /* Set prescaler bits */ }void AD_MeasureChan(byte Channel, byte *Result){  ModeFlg = SINGLE;                    /* Set state of device to the measure mode */  SumChan = Channel;                   /* Set required channel */  if (ModeFlg) {                       /* Start or stop measurement? */    OutFlg &= ~Table[SumChan];         /* Output value isn't available */    ADCSC1 = Channels[SumChan];          /* Start measurement of next channel */    while (!ADCSC1_COCO) {}              /* Wait for AD conversion complete */    ((TWREG*)(&AD_OutV[SumChan]))->b.high = ADCRH; /* Save measured value */    ((TWREG*)(&AD_OutV[SumChan]))->b.low = ADCRL; /* Save measured value */    OutFlg |= Table[SumChan];            /* Value of measured channel is available */    ADCSC1 = 0x1F;                   /* Stop the device */    ModeFlg = STOP;                      /* Set the device to the stop mode */    Result[0] = (AD_OutV[Channel]) & (0xFF);    /* Save measured values to the output buffer */    Result[1] = ((AD_OutV[Channel]) & (0xF00)) >> 8;    /* Save measured values to the output buffer */  }}/*! \fn void mesT (byte *dataT)    \brief fonction de mesure de température    \param dataT pointeur vers le résultat de la mesure*/void mesT (byte *dataT){  AD_MeasureChan (channelT, dataT);  }/*! \fn void mesV (byte *dataV)    \brief fonction de mesure de tension    \param dataV pointeur vers le résultat de la mesure*/void mesV (byte *dataV){  AD_MeasureChan (channelV, dataV);} interrupt void RTC_Interrupt (void) {  byte dataV[2], dataT[2], dataI[2];  byte mesure[3]; // tableau contenant les mesures  RTCSC_RTIF = 1; // efface le flag  mesV(&dataV); // mesure de tension  mesure[0] = (branche<<5) + module ;  mesure[1] = dataV[0];   mesure[2] = dataV[1];  send (&mesure, 3, mesures);  mesT(&dataT); // mesure de température  mesure[0] = (branche<<5) + module ;  mesure[1] = dataT[0];   mesure[2] = dataT[1];  send (&mesure, 3, temperature);  /* dans le cas d'un module qui mesure le courant */  //# ifdef COURANT   if (module_courant == num_module) {  mesI(&dataI);  mesure[0] = (branche<<5) + module ;  mesure[1] = dataI[0];   mesure[2] = dataI[1];  send (&mesure, 3, courant);}  }

 

The problem is with dataT and dataV. The measure of dataI is always 0xFFF.

I tried some changes and somes tests (I put an input voltage on the channel mesured by mesV). Here are my observations.

the same code with short sample time :

                                0V                          1V                          2V                               3V                           4V                           5V

mesV                    0x000                   3A3                       718                             A83                       DED                        FFF

mesT                    0x1AB                   31F                       4BC                           67B                        827                         991

 

the same code with long sample time :

                                0V                          1V                          2V                               3V                           4V                           5V

mesV                    0x000                   3A5                       6DF                             A47                       DCA                        FFF

mesT                    0x1A7                   31C                       4A2                             65F                        823                         99B

 

with short sample time but I do mesV, then mesI and then mesT:

                                0V                          1V                          2V                               3V                           4V                           5V

mesV                    0x000                   35F                       6DD                             A59                       DB7                        FFF

mesT                    0x9C7                   9BF                      9B5                             9AF                        9B4                         9B7

(here the value measured for temperature is -90°C with 9B5)

 

with short sample time and two readings in succession for each channel :

                                0V                          1V                          2V                               3V                           4V                           5V

mesV                    0x000                   3AF                       6DD                             A9F                       DCD                        FFF

mesT                    0x3F2                   409                       5C7                             75A                        8F7                         A97

 

with short sample time and two readings in succession for each channel but I do mesV, then mesI and then mesT:

                                0V                          1V                          2V                               3V                           4V                           5V

mesV                    0x000                   360                       715                              A43                        DBF                        FFF

mesT                    0x9E5                   AAF                       AE5                             A29                        A2F                         A72

 

 

mesV gives the voltage, so it seems to be right.

Please, is there something that I'm doing wrong ??

I don't understand why I have those values.

Sorry for my english, I am french...

 

Thank you very much for your help.

0 Kudos
Reply

1,072 Views
bigmac
Specialist III

Hello,

 

If you have not already done so, I think that you need to confirm, using an oscilloscope, that the voltages applied to the ADC inputs are free of hum and noise.  In particular, I notice that the temperature sensor might be prone to instability (oscillation) if operating into a capacitive load of more than 300pF.  For example, if you had a 100nF capacitor at the ADC input pin, you would require an isolating series resistance of 470 ohms between the temperature sensor output and the input to ensure stability.

 

Additionally the input capacitor will need to be returned to the low noise analog ground to prevent injection of noise to the input.  There should be a separate bypass capacitor between the VddA/VrefH pins and the VssA/VrefL pins.  These pins should be connected to Vdd and Vss pins respectively, right at the MCU package only.

 

I think that you need to verify your circuit board layout before assuming that there is a coding deficiency.  Proper layout is extremely important for 12-bit  conversions, much more so than for lower ADC resolutions.  Noise fluctuations of more than about 1 millivolt are significant.  Sometimes it is necessary to enter wait mode during the conversion process, to eliminate the internal CPU clock noise.

 

Regards,

Mac