EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

ADC10 problem , MSP1232

Started by nerdy_om April 5, 2004
Here is a breif statement of my application that I started 
implementing in MSPF1232,using IAR Assembly, a few weeks ago. With a 
huge task ahead, at my first job project,and first on MSP,  now  I  
am still in the beginning itself as the on chip ADC seems unreliable.

Ps: Jump to  end of the mail (No.3)to look about the ADC problem 
specifically.
-------------------- x ----------------------
A)2 Channels of analog data A0,A1 (range 0-5v) coming in from a 
sensor.
B)The base frequncy component of these signals will not be more than 
20-30Hz and I have a low pass filter to do the job.

C)The following operations must be going on on the 
processor "continously" (24/7),
   i)  Firstly the data on both channels has to be buffered over  
       Tsecs (say 10 secs)
   ii) Second the buffered data has to be analysed for "peaks" to 
       get a "count" dependent on those peaks.
   ii) Third the count for each buffer has to be logged on to some  
       kind of memory (flash).

------------------------
Now my work until now :

1. Inital step : What I intended to do was measure an input voltage 
(0-2.5 V), passing in through a potentiometer to channel A0, so when 
ever there is a change in direction of  the twist of the pot, my 
algorithm would detect the peak . 

Similarly , if I input a DAC voltage from some other device, like a 
pure sinusoid it should be able to detect each peak one after the 
other.That way I can extend the concept to my actual application.So 
here is what I did,
    
    a) Fixed the buffer length to N samples.Running off the DCO, I 
setup the DTC to get a sample burst (of N smaples), in 'Repat Single 
Channel' mode.So that,ADC10 interrupt will be generated after N 
conversions have been finished (or my buffer has been filled).
       
    b) There in the ADC10 ISR, I implemented a 'peak detection' 
algorithm that would go through the entire buffer and increment a 
counter when it finds peaks.

--------------------- x ----
     
As you can see, until  here I have no control over the 'sampling 
frequency'.Once I 'start the ADC' , it only stops after N 
conversions and 'repeats' over. So, my idea was to setup external 
trigger (TimerA),that would control the sample freq. (@ abt 32Hz ).

c) I setup a TRIGGER for the ADC10 using TimerA in set/rest 
mode.Thus, at every 0.03125ms (~ assuming 800KHz DCO), SHI is 
triggerd by the TIMERA.1  interrupt.Making SAMPCON high . (see CODE 
SNIPPET 1., below)

;--------------------------------
            ORG     0E000h                  ; Program Start
;--------------------------------
RESET       mov.w   #0300h,SP               ; Initialize stackpointer
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT

SetupADC10  
mov.w   #SHS_1+CONSEQ_2,&ADC10CTL1 ; TA1 trigger sample start    
mov.w
#SREF_1+ADC10SHT_2+REFON+REF2_5V+ADC10ON+ADC10IE,&ADC10CTL0

bis.w   #ENC,&ADC10CTL0    ; ADC10 enable set
bis.b   #001h,&ADC10AE     ; P2.0 ADC10 option select 
            
SetupP1
            bis.b   #00Eh,&P1SEL            ; P1.1 - P1.3 option 
            bis.b   #00Fh,&P1DIR            ; P1.0-3 outputs 
SetupC0
            mov.w   #25000-1,&CCR0          ; PWM Period x
SetupC1     
            mov.w   #OUTMOD1+OUTMOD0,&CCTL1 ; CCR1 set/reset
            mov.w   #2,&CCR1                ; CCR1 PWM Duty Cycle
	  
SetupTA                                     ;
            mov.w   #TASSEL_2+MC0,&TACTL    ; SMCLK, upmode
SetupDTC                                    ;
            mov.b   #nConv,&ADC10DTC1       ; 32 conversions    
            mov.w   #sA0,&ADC10SA           ; Data buffer start
            clr     PeakCount                ;
Mainloop    
            bis.w   #CPUOFF+GIE,SR          ; Enter LPM3 
            nop                             ; Required only for C-spy

;--------------------------------
getPeaks;
; Subroutine returns a COUNT of number of PEAKS in given data 
; Also writes sample # of fallingedge derivatives at the end of the 
;data in another block
;--------------------------------
                                    ; Initialize   
                                    ; Now move to dervative part
            clr     myFlagReg       ; flag register 
            mov     #sA0-0x2,iA0    ; iA0  : (sA0 + iA0)
            mov     #0000h,count1   ; intialize COUNTER

;-------;                
Init  
       incd    iA0                     ; i ++   
       inc.b   count1                  ; count ++  
       cmp.b   #nConv-1,count1         ; EXIT Loop
       jhs     EXIT                    ; if count1 >= nConv -1
       cmp     @iA0,2(iA0)     ; A0(i) >= A0(i+1) ?  N = 1 if TRUE
       jeq     Init            ; keep looping until nonZero SLOPE 
       jn      dSlope          ;
       mov     #0h, myFlagReg  ; reset lslp Flag (N = 0),
                               ; A0(2) > A0(1)
       jmp     try             ;
dSlope 
       mov     #001h,  myFlagReg    ; set lslp Flag  (N =1) ,
                                    ; A0(1) > A0(2)     
;-------;
try    incd    iA0                  ; i ++, increments 2 bytes       
       inc.b   count1               ; increments 1 byte 
       mov     #0,sd0 - sA0 - 0(iA0); clear DEST
       cmp     @iA0,2(iA0)          ; A0(i+1) >= A0(i) ? 
       jeq     SKIP                 ; A0(i) == A0(i+1) , then SKIP 
       jn      NEGSLOPE             ; else if A0(i+1) < A0(i) 

POSSLOPE    
          bit     #BIT0, myFlagReg         ; if lslpF == 1, change 
          JZ      SKIP       ; else same direction to previous : SKIP
markMin     
          mov     2(iA0),sd0-sA0-0(iA0)    ; N = 0,A0(i+1) > A0(i),
          sub     0(iA0),sd0-sA0-0(iA0)
          cmp     #noiseT,sd0-sA0-0(iA0)
          jhs     isMinima                 ; dA0 >= #48d
          mov     #0h,sd0 - sA0 - 0(iA0)   ; clear DST
          jmp     SKIP                     ; DONT MARK a change
isMinima    
          mov     #0x1111,sd0 - sA0 - 0(iA0)
          jmp     RECORD                   
                         
NEGSLOPE    
          bit     #BIT0, myFlagReg         ; if lslpF == 0, change 
          JNZ     SKIP                     ; else same direction to 
                                           ;previous : SKIP         
markMax     
          mov     0(iA0),sd0-sA0-0(iA0)    ; N = 0,A0(i+1) < A0(i), 
          sub     2(iA0),sd0-sA0-0(iA0)     
          cmp     #noiseT,sd0-sA0-0(iA0)   ; jerk < noiseThreshold
          jhs     isMaxima                 ; dA0 >= #48d
          mov     #0h,sd0 - sA0 - 0(iA0)   ; clear DST
          jmp     SKIP                     ; DONOT mark a change
isMaxima   
          mov     #0xFFFF,sd0 - sA0 - 0(iA0)
            
RECORD    xor     #0001h, myFlagReg        ; TOGGLE SLOPE BIT
          inc.b   PeakCount
SKIP      cmp.b   #nConv-0x01,count1   ; compare LSByte Count 
          jne     try                      ;
EXIT            
          xor.b    #01h,&P1OUT
          ret                              ; return from CALL
            
   
;--------------------------------
ADC10_ISR;   
;--------------------------------
            xor.b   #01h,&P1OUT    ; TOGGLE after each buffer fill
            call    #getPeaks               ; analyZe for Peaks in 
the Buffer,(nested call)        
            mov.w   #sA0,&ADC10SA            ; Data buffer start
            bis.w   #ENC,&ADC10CTL0         ; start next "sample 
burst"                  

ADC10_Exit  
            reti                      
;--------------------------------
;           Interrupt Vectors Used MSP430x12x2         
;--------------------------------
            ORG     0FFFEh                 ; MSP430 RESET Vector
            DW      RESET                   ; 
            ORG     0FFEAh                ; ADC10 Vector
            DW      ADC10_ISR          ; 
            END

;--------------------------------
 

Now my questions are,

2. If the DTC is set up in repeat single channel mode even in case
(C) above, then am I doing a 32Hz sampling correctly ? 

Because the data sheet says , TimerA will trigger the sample burst & 
succesive samples will be aquired one after the other.... am I 
missing anything here ??

Is there some thing to the ENC bit toggling, which I seem to be 
confused.(i understand DCO need not be exactly at 800kHz, but how 
about the logic itself ?).

3. Now, hopefully if my sampling is correct, I can do the same using 
a 32kHZ crystal.Then I will be able to fill my 'buffer' at required 
rates.Fine until here.

But, my 'get Peaks' routine, peaks up a peak every so often , that 
it has become hard for me to decided what will be the bit error to 
decided a noise Threshold to eliminate false peaks, in a supposedly 
smooth incoming signal.

I have tried the to sample just a single channel, with sample codes 
from TI. But, even though I am just sampling a voltage input from a 
AAA battery with 16K series resistance, on A0, I never seem to get a 
good stable conversion result.There is a HUGE sway in volatge ranges 
of about 0-6 bits, over 32 samples or so.Why is it so large ? 

As I could see from some of the earlier posts is it necessary to 
calibrate the ADC ? If so how do i do it ? 

4. Please let me know, if you see any serious BUGS in this little 
piece of software.

------------- x ----------------------

Thanks in advance,
Regards,
- OM -




Beginning Microcontrollers with the MSP430

At 08:48 6/04/2004, you wrote:
>I have tried the to sample just a single channel,
with sample codes
>from TI. But, even though I am just sampling a voltage input from a
>AAA battery with 16K series resistance, on A0, I never seem to get a
>good stable conversion result.There is a HUGE sway in volatge ranges
>of about 0-6 bits, over 32 samples or so.Why is it so large ?

Have you got a bypass cap on the Vref+ pin? We had similar problems with a 
F149 and a cap on that pin fixed things for us. It is documented somewhere 
(sort of) but I'm at home and don't have all the info

peter 


> Have you got a bypass cap on the Vref+ pin? We had similar 
> problems with a F149 and a cap on that pin fixed
things for us. It 
> is documented somewhere sort of) but I'm at home and don't have 
> all the info

As you may notice from my 'code' that I attached, I donot use any 
external reference source.I use the internal refrence 2.5V to do the 
conversion.So, my Vref+ (pin 20)and Vref- (pin 20)pins are not being 
used.

I am not sure where to use the bypass. However, I did try to bypass 
my input signal voltage on A0 though, wondering if my input signal 
was really fluctuating, but that didn'y help either.

Do you still think there is a need for bypass ? Can you please be 
more specific abt the pin (just if my terminology were wrong).

Thanks,
<OM>


--- In msp430@msp4..., Peter McConaghy <pmcconaghy@c...> 
wrote:
> At 08:48 6/04/2004, you wrote:
> >I have tried the to sample just a single channel, with sample 
codes
> >from TI. But, even though I am just sampling a
voltage input from 
a
> >AAA battery with 16K series resistance, on A0,
I never seem to 
get a
> >good stable conversion result.There is a HUGE
sway in volatge 
ranges
> >of about 0-6 bits, over 32 samples or so.Why
is it so large ?
> 
> Have you got a bypass cap on the Vref+ pin? We had similar 
problems with a 
> F149 and a cap on that pin fixed things for us. It
is documented 
somewhere 
> (sort of) but I'm at home and don't have
all the info
> 
> peter


At 10:04 6/04/2004, nerdy_om wrote:
> > Have you got a bypass cap on the Vref+ pin?
We had similar
> > problems with a F149 and a cap on that pin fixed things for us. It
> > is documented somewhere sort of) but I'm at home and don't
have
> > all the info
>
>As you may notice from my 'code' that I attached, I donot use any
>external reference source.I use the internal refrence 2.5V to do the
>conversion.So, my Vref+ (pin 20)and Vref- (pin 20)pins are not being
>used.
>
>I am not sure where to use the bypass. However, I did try to bypass
>my input signal voltage on A0 though, wondering if my input signal
>was really fluctuating, but that didn'y help either.
>
>Do you still think there is a need for bypass ? Can you please be
>more specific abt the pin (just if my terminology were wrong).

You still need the external cap if you are using the internal reference for 
the F149. I'd try it on your device as it is fairly easy to test - just add

the caps! Put 10uF + 100nF in parallel between Vref+ and AVss (and perhaps 
between Vref- and AVss if you are using it that way)

In  http://focus.ti.com/lit/ds/symlink/msp430f149.pdf
See page 33, note 1 & page 34

regards
peter  


Peter,

--- In msp430@msp4..., Peter McConaghy <pmcconaghy@c...> 
wrote:
> You still need the external cap if you are using the internal 
reference for 
> the F149. I'd try it on your device as it is
fairly easy to test - 
just add 
> the caps! Put 10uF + 100nF in parallel between
Vref+ and AVss (and 
perhaps 
> between Vref- and AVss if you are using it that
way)

He's actually using an MSP1232, which doesn't have an AVss pin.  Of 
course, I still think your suggestion is a good one (adding a cap 
between VRef and Vss), I'm posting this mainly because I also found 
that it's a lot more difficult to get 'clean' readings from the 
MSP1232 than, e.g., the F149 where you can easily separate all your 
analog and digital traces.

---Joel Kolstad



Hi OM,

<snipsnipsnip>

> I have tried the to sample just a single channel,
with sample codes 
> from TI. But, even though I am just sampling a voltage input from a 
> AAA battery with 16K series resistance, on A0, I never seem to get 
a 
> good stable conversion result.There is a HUGE sway
in volatge 
ranges 
> of about 0-6 bits, over 32 samples or so.Why is it
so large ? 

I didn't look at your code, but what I can tell is that with 16k 
source resistance you might have a sampling time problem. Is there a 
cap to GND between the resistor and the input to buffer the signal 
while the ADC's S&H cap is charged?
Is your sampling time long enough? This is covered on p. 27 of 
slas261c.

Wolfgang



Hi all,

Peter : 

I am using a MSP-FET 120 module, and Jtag from TI, along with 
KickStart.I checked that the 100uf and 10nf were very much installed 
between Vcc & Vss.However, I couldn't get one to install b/n Vref 
and Vss (just in case).

Whong: 

The MSP 1232 datasheet recommends a sampling time "tsample"
 > (Rs +Ri) x ln(2^11) x Ci + 2.5us  : (ADSR =1)
              (or)
 > (Rs +Ri) x ln(2^11) x Ci + 800ns  : (ADSR =0)

Internally, it also says  Ri: max2Kohm and Ci:max 20pF.

Now from the above even if I have a Rs Kohm the maximum tsample 
required would be, 5.245 uSec for ADSR =1. Isn't it ? 
I think my code TRIES to do sampling only at 32Hz.

----------x ---------------
Having said that, I REALLY wonder if I am using the DTC correctly ?
Once again, "CAN I SET THE DTC to GET ONLY ONE SAMPLE ON SHI 
TRIGGER ? ". 

Can some body please comment on the CODE i posted earlier ?
------- x -----------------

Looks like I made the problem lengthier to read but not clear.Here 
are my qn's again breifly.

1. With this setup below (adding a .1uF cap).And logging readings 
using the DTC to RAM, what is the maximum change in readings that I 
can expect ?
                    ___________
      Rs(16K)      |
 AAA -/\/\/\--->A0 | MSP 1232
 BATT      |       |  on 
     Cap(.1uf)     | FET Module
          \-/      |
                   |___________

From what I see, the Cap. didnot change my results.And as one would 
expect I get a value around 0x266 for 1.5v, however it goes as low 
as 0x263 and as high as 0x269 some times.

Are these fluctuations inevitable ? 

Seeing that is as large as 15mV error, is it a BAD SOURCE I am using 
or is it about the ADC itself ?

The datasheet reports all errors put together can be as large as  5 
bits. So is an external ADC necessary in most cases ? Would it limit 
these errors ?

My application is aiming to sample a 0-5V signal sensor output and 
detect , log each "peak" in the incoming signal.Currently , as you 
see the problem is that my algorithm would detect "peaks" even if 
there are NONE :o(

Can any one suggest how do I proceed , what am I missing ? 

--------- x -----------------

With KNIVES coming down my neck,
--OM
                      
--- In msp430@msp4..., "Wolfgang Reich" 
<reich_wolfgang@y...> wrote:
> Hi OM,
> 
> <snipsnipsnip>
> 
> > I have tried the to sample just a single channel, with sample 
codes 
> > from TI. But, even though I am just sampling
a voltage input 
from a 
> > AAA battery with 16K series resistance, on
A0, I never seem to 
get 
> a 
> > good stable conversion result.There is a HUGE sway in volatge 
> ranges 
> > of about 0-6 bits, over 32 samples or so.Why is it so large ? 
> 
> I didn't look at your code, but what I can tell is that with 16k 
> source resistance you might have a sampling time problem. Is there 
a 
> cap to GND between the resistor and the input to
buffer the signal 
> while the ADC's S&H cap is charged?
> Is your sampling time long enough? This is covered on p. 27 of 
> slas261c.
> 
> Wolfgang


>
>Now from the above even if I have a Rs Kohm the maximum tsample
>required would be, 5.245 uSec for ADSR =1. Isn't it ?
>I think my code TRIES to do sampling only at 32Hz.

This has nothing to do with your SAMPLING time.
This is the sampling frequency, if you want to call it so.

The sampling time is determined by the numbers  you write in the control 
register ADC12CTL0 for SHT0 and SHT1
see the ADC description, of course it also has to do with the ADC clock 
frequency

  I get a value around 0x266 for 1.5v, however it goes as low
>as 0x263 and as high as 0x269 some times.
>
>Are these fluctuations inevitable ?
>
>Seeing that is as large as 15mV error, is it a BAD SOURCE I am using
>or is it about the ADC itself ?
>
>The datasheet reports all errors put together can be as large as  5
>bits. So is an external ADC necessary in most cases ? Would it limit
>these errors ?

You possibly mean that you get from a minimum of 263 DECIMAL to a maximum 
of 269.
This is +/- 3 points out of 266 or slightly worse than 1%
If you measure this up to your Full Scale of 1024 points the error is less 
than +/- 0.3% .

You can improve on it, ... .... somewhat.
1) The source is not a reliable one
2) You need to understand what the T/H sampling time is used for ...
3) You may want to stop all microprocessor activity and thus all noise 
during conversion
4) Best of all you may average up a significative number of conversion 
results, e.g. 32 or 64 samples

But do not expect to have the result stable to the least bit ...

Regards
Antonio 



The 2024 Embedded Online Conference