This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem with ADC triggering (ADC12SC)

Other Parts Discussed in Thread: MSP430F5328, MSP430F5438A

Hello,

 

I am working with a MSP430F5328 and I need to sample some ADC channels. I am using the adc in sequence-of-channels mode.

But the ADC is not starting, only the first time I trigger the ADC12SC bit with the instruction: "ADC12CTL0 |= ADC12SC ;"

And if I add the instruction twice, it is working.

It seems that the same problem already is posted, but I didn't get any reply! And I need to have it working soon.

 

It is the same problem as described in: Problem with ADC triggering using software(ADC12SC)

http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/123789/807992.aspx#807992

 

Is it also a bug in the MSP430F5328? And where can I find the revision of the chip I have?

Best regards,

Jeroen

  • Such a bug it is not reported in MSP430F5328 errata (SLAZ272 http://www.ti.com/litv/pdf/slaz272b), so maybe you have discovered an unknown bug. Revision is identified by a capital letter written on top of chip package and its location varies from package to package, as documented in Package Markings chapter of the errata document above. Regards, Peppe
  • Jeroen,

    How have you initialized the ADC?  Can you provide your init code?

    Darren

  • Hello,

     

    Thanks, I found my revision, it is F.

     

    I made an example project, it is not exact simmular to my code but it has the same problem.

    I used a timer to start the ADC. In the timer interrupt routine i have to add twice the instruction "ADC12CTL0 |= ADC12SC ;"

    The first time when I start the ADC I only have to trigger the ADC ones. After the first time the ADC need to be triggered twice before the ADC starts.

     

     Please let me know if there is a solution to solve this problem.

     

     

    #include <msp430f5328.h>

    volatile unsigned int results[4];           // Needs to be global in this example

                                                // Otherwise, the compiler removes it

                                                // because it is not used for anything.

     

    void main(void)

    {

      // ADC settings

      WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

      P6SEL = 0x0F;                             // Enable A/D channel inputs

      ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_2; // Turn on ADC12, set sampling time

      ADC12CTL1 = ADC12SHP+ADC12CONSEQ_1;       // Use sampling timer, single sequence

      ADC12MCTL0 = ADC12INCH_0;                 // ref+=AVcc, channel = A0

      ADC12MCTL1 = ADC12INCH_1;                 // ref+=AVcc, channel = A1

      ADC12MCTL2 = ADC12INCH_2;                 // ref+=AVcc, channel = A2

      ADC12MCTL3 = ADC12INCH_3+ADC12EOS;        // ref+=AVcc, channel = A3, end seq.

      ADC12IE = 0x08;                           // Enable ADC12IFG.3

      ADC12CTL0 |= ADC12ENC;                    // Enable conversions

     

      // Timer settings

      TA0CCTL0 = CCIE;                          // CCR0 interrupt enabled

      TA0CCR0 = 32768;

      TA0CTL = TASSEL_1 + MC_1 + TACLR;         // SMCLK, upmode, clear TAR

     

      __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, enable interrupts

      __no_operation();                         // For debugger

     

    }

     

     

    #pragma vector=ADC12_VECTOR

    __interrupt void ADC12ISR (void)

    {

        switch(__even_in_range(ADC12IV,34))

      {

      case  0: break;                           // Vector  0:  No interrupt

      case  2: break;                           // Vector  2:  ADC overflow

      case  4: break;                           // Vector  4:  ADC timing overflow

      case  6: break;                           // Vector  6:  ADC12IFG0

      case  8: break;                           // Vector  8:  ADC12IFG1

      case 10: break;                           // Vector 10:  ADC12IFG2

      case 12:                                  // Vector 12:  ADC12IFG3

        results[0] = ADC12MEM0;                 // Move results, IFG is cleared

        results[1] = ADC12MEM1;                 // Move results, IFG is cleared

        results[2] = ADC12MEM2;                 // Move results, IFG is cleared

        results[3] = ADC12MEM3;                 // Move results, IFG is cleared

        __bic_SR_register_on_exit(LPM4_bits);   // Exit active CPU, SET BREAKPOINT HERE

      case 14: break;                           // Vector 14:  ADC12IFG4

      case 16: break;                           // Vector 16:  ADC12IFG5

      case 18: break;                           // Vector 18:  ADC12IFG6

      case 20: break;                           // Vector 20:  ADC12IFG7

      case 22: break;                           // Vector 22:  ADC12IFG8

      case 24: break;                           // Vector 24:  ADC12IFG9

      case 26: break;                           // Vector 26:  ADC12IFG10

      case 28: break;                           // Vector 28:  ADC12IFG11

      case 30: break;                           // Vector 30:  ADC12IFG12

      case 32: break;                           // Vector 32:  ADC12IFG13

      case 34: break;                           // Vector 34:  ADC12IFG14

      default: break;

      }

    }

     

     

    // Timer0 A0 interrupt service routine

    #pragma vector=TIMER0_A0_VECTOR

    __interrupt void TIMER0_A0_ISR(void)

    {

           ADC12CTL0 |= ADC12SC ;                   // Start ADC

           //ADC12CTL0 |= ADC12SC ;                 // Second instruction is needed to start the ADC

    }

     

  •  Jeroe,

    I am running the MSP430F5438A ADC in pretty much the same fashion as you and I am not having any issues.  This in your timer interrupt service routine instead.

    #pragma vector=TIMER0_A0_VECTOR

    __interrupt void TIMER0_A0_ISR(void)

    {

           ADC12CTL0 |= ADC12ON;

          ADC12CTL0 |= ADC12ENC;

           ADC12CTL0 |= ADC12SC ;                   // Start ADC

    }

    Remove these first two lines from your init code in main and place them in the ISR like above.  This is working for me.  Also, I noticed that you are not explicitly setting the start channel.

    Cheers,

    Darren

  • Darren, 

    Thanks for your reply.

    Like I said earlier in one of my posts: 

    "The first time when I start the ADC I only have to trigger the ADC ones. After the first time the ADC need to be triggered twice before the ADC starts."

    When I add one of the instructions (or both):  

    ADC12CTL0 |= ADC12ON;
    ADC12CTL0 |= ADC12ENC;

    It is working, but am I now re-starting or re-enabling the ADC, so it is every time the first sample, which start with one trigger of the ADC12SC bit?

    And I thought I could start the ADC to trigger the ADC12SC bit. Like the datasheet (SLAU208K p732) says:

    "When ADC12SC triggers a sequence, successive sequences can be triggered by the ADC12SC bit."

    Or do I understand that wrong? 

    Best regards,

    Jeroen


  • Hello, 

    Are there some more options because it is still not working?!

    Best regards,

    Jeroen

  • Hello, 

    I still haven't found a solution for my problem. Is there someone with the same problem and any idea how I can fix this problem? 

    Best regards,

    Jeroen 

  • Hello,

    The problem isn't solved yet. Any idea's?

    Best regards,

    Jeroen

  • Jeroen,

    Make sure that you look at the state diagram on page 703 of SLAU208L.pdf (the User's Guide).

    Your issue is that when the sequence of channels is complete, you need to clear and then set the ENC bit, but only after all channels have been converted. In my application I did this in the ISR for the DMA controller when it had transferred all the channel data.

  • I see now that you're using the ADC12 and not ADC10. Double check the state diagram for the ADC12 in sequence mode.

    Depending on the clock rate of the ADC12 (vs the CPU MCLK rate) the ADC may not have had a chance to transition back to the "Wait for Enable" state, so the SC bit has no effect.

    Also, if you're going to retrigger in the ISR, then why not use the "Repeated Sequence of Channels" mode instead and get rid of setting SC in the ISR?

  • Brian, thanks for your reply.

    I checked the state diagram on page 732 of the user guide but i couldn't found anything.

    Do you have to wait before you can start another sequence? I tried waiting for the ADC12BUSY bit is low and for ADC12SC bit low is. But both are low before I start the sequence and still I need to set ADC12SC twice.

    I also have the problem in SINGLE CHANNEL - SINGLE CONVERSION mode. 

    The CPU is running on 20 MHz.
    The ADC is running on 4 MHz.

    How can I check that I am writing ADC12SC bit to early?

    Best regards,

    Jeroen

     

  • Darren,

    Can you provide your code? So I can check if I can see some differences.

    Best regars,

    Jeroen

  • Hello,

    It is a time ago but the problem was solved by clearing the ADC12SC bit in the ISR.

    According the MSP430x5xx and MSP430x6xx Family manual on page 740: "When ADC12SC triggers a
    sequence, successive sequences can be triggered by the ADC12SC bit. The ADC12SC must be cleared
    by software after each sequence to trigger another sequence. When any other trigger source is used,
    ADC12ENC must be toggled between each sequence."

    The problem was that I didn't cleared the ADC12SC bit.

    Also make sure all adc settings where set else it could go also wrong.

    Jeroen

**Attention** This is a public forum