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.

MSP430F2132: ADC

Part Number: MSP430F2132

Hi,

It's OK?
I'm simulating a level monitoring of a depleted reservoir. According to the fact that the reservoir is filling the LEDs will light up increasingly, but I am having difficulty performing this LED control to interleave them cyclically using the function "IF". To simulate the level, I use a potentiometer
Would you help me? See attachment firmware and diagram.

Thank you!

Caio de Morais


//#include "msp430g2553.h"
#include "msp430f2132.h"

//Variavel que recebe o valor do conversor a/d ao ser ligado
unsigned int tempCalibrated = 0;

//Rotina de configuração do conversor a/d
void ConfigureAdc(void) {
ADC10CTL1 = INCH_1 + ADC10DIV_3;
ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
__delay_cycles(1000);
ADC10CTL0 |= ENC + ADC10SC;
__bis_SR_register(CPUOFF + GIE);
tempCalibrated = ADC10MEM;
}

unsigned int value = 0;

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF);
}

int main( void ) {
WDTCTL = WDTPW + WDTHOLD; // Desliga Watchdog timer
//P1DIR = 0x01 + 0x02 + 0x04 + 0x08 + 0x10 + 0x20 + 0x40 +0x80 ; // Define pinos 1.0 e 1.6 como saída (0100 0001)
P1DIR = 0xFF;


BCSCTL1 = CALBC1_1MHZ; // Seleciona fonte de clock
DCOCTL = CALDCO_1MHZ; // Configura fonte de clock
BCSCTL2 &= ~(DIVS_3); // Demais configurações de clock
ConfigureAdc();
__enable_interrupt(); // Habilita interrupções
while(1) {
__delay_cycles(1000); // Atraso de 1000 ciclos
ADC10CTL0 |= ENC + ADC10SC; // Valor do AD = sensor interno de temp.
__bis_SR_register(CPUOFF + GIE); // Desliga CPU e habilita interrupções
value= ADC10MEM; // Obtem o valor do AD
//value = 0;

if (value == tempCalibrated) {
P1OUT = 0x01 ;
}
if (0.2 <= tempCalibrated < 15) {
P1OUT = 0x01;
P1OUT = 0x02; }

if (15 <= tempCalibrated < 30) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04; }

if (30 <= tempCalibrated < 45) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04;
P1OUT = 0x08; }

if (45 <= tempCalibrated < 60) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04;
P1OUT = 0x08;
P1OUT = 0x10; }

if (60 <= tempCalibrated < 75) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04;
P1OUT = 0x08;
P1OUT = 0x10;
P1OUT = 0x20; }

if (75 <= tempCalibrated < 90) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04;
P1OUT = 0x08;
P1OUT = 0x10;
P1OUT = 0x20;
P1OUT = 0x40; }

if (90 < tempCalibrated <= 100) {
P1OUT = 0x01;
P1OUT = 0x02;
P1OUT = 0x04;
P1OUT = 0x08;
P1OUT = 0x10;
P1OUT = 0x20;
P1OUT = 0x40;
P1OUT = 0x80;}

}

}

  • Hello CdM,

    When posting code to the forum, please use the </> button as it will format the code to make it easier to read. This will lead to better rand faster responses to your issue. When replying to a post and posting code, the </> button can be found in the advanced editor found by clicking the "Insert Code, Attach Files and more..." link to the bottom write of the comment box. I've already edited your orignal post to reflect this change.

    In regards to your post, you are assigning the P1OUT register absolutely to each value, which is causing the previous values to be overwritten. You need to use an " |= " to do what you want in this form.

    Alternatively, you can do the following for each situation.

    // To set P1.0, P1.1, P1.2
    P1OUT = (BIT0 + BIT1 + BIT2);
    //Continue this for each pin
    P1OUT = (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7);

  • I made the change, but did not get a concrete answer because the LEDs do not vary according to the variation of the potentiometer. Or have I made any mistaken changes?
    I've performed the procedure of sending the code the way you requested it, I hope you have it properly adjusted. Thank you!


    //#include "msp430g2553.h" #include "msp430f2132.h" //Variavel que recebe o valor do conversor a/d ao ser ligado unsigned int tempCalibrated = 0; //float tempCalibrated = 0; //Rotina de configuração do conversor a/d void ConfigureAdc(void) { ADC10CTL1 = INCH_1 + ADC10DIV_3; ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; __delay_cycles(1000); ADC10CTL0 |= ENC + ADC10SC; __bis_SR_register(CPUOFF + GIE); tempCalibrated = ADC10MEM; } unsigned int value = 0; //float value = ; #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); } int main( void ) { WDTCTL = WDTPW + WDTHOLD; // Desliga Watchdog timer //P1DIR = 0x01 + 0x02 + 0x04 + 0x08 + 0x10 + 0x20 + 0x40 +0x80 ; // Define pinos 1.0 e 1.6 como saída (0100 0001) P1DIR = 0xFF; //P1OUT = 0x00; P1OUT = BIT0 + BIT1 + BIT2; BCSCTL1 = CALBC1_1MHZ; // Seleciona fonte de clock DCOCTL = CALDCO_1MHZ; // Configura fonte de clock BCSCTL2 &= ~(DIVS_3); // Demais configurações de clock ConfigureAdc(); __enable_interrupt(); // HabiPlita interrupções while(1) { __delay_cycles(1000); // Atraso de 1000 ciclos ADC10CTL0 |= ENC + ADC10SC; // Valor do AD = sensor interno de temp. __bis_SR_register(CPUOFF + GIE); // Desliga CPU e habilita interrupções value= ADC10MEM; // Obtem o valor do AD //value = 0; if ((value > 0) & (value < 10)) P1OUT = BIT0; if (value >= 127) P1OUT = BIT1; if (value >= 254) P1OUT = BIT2; if (value >= 381) P1OUT = 0x07; if (value >= 506) P1OUT = 0x0F; if (value >= 635) P1OUT = 0x1F; if (value >= 762) P1OUT = 0x3F; if (value >= 889) P1OUT = 0x6F; if (value >= 1016) P1OUT = 0xFF; }}

  • CdM,

    You also need to switch from straight ifs to if/else if . Currently you are evaluating every if statement for every measurement. By using If/else if you only evaluate the one condition. You would also need to put in your lower limits again like you had in your first code you posted.
  • > ADC10CTL1 = INCH_1 + ADC10DIV_3;


    I recommend you add the following to ConfigureAdc. "BIT1" corresponds to "INCH_1" above. (See also SLAU144J sections 22.2.2.1 and 22.3.3)


    > ADC10AE0 |= BIT1; // Enable analog on A1

  • Bruce,

    Can not understand what he meant.

  • Jace H,
    I made this configuration, but I did not get results. Or, because he was still a lay person who did not understand and performed correctly, could he make an example so that I could continue?
    Thank you!
  • Bruce
    I made this configuration, but I did not get results. Or, because he was still a lay person who did not understand and performed correctly, could he make an example so that I could continue?
    Thank you!
  • Add the line indicated by the ">" below:

    void ConfigureAdc(void) {
    ADC10CTL1 = INCH_1 + ADC10DIV_3;
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
    > ADC10AE0 |= BIT1; // Enable analog on A1
  • Eu alterei o código, porém nenhum LED acende quando altero o potênciometro
    
    #include "msp430f2132.h"
    #include <intrinsics.h>
    
    //Variavel que recebe o valor do conversor a/d ao ser ligado
    unsigned int tempCalibrated = 0;
    
    //Rotina de configuração do conversor a/d
    void ConfigureAdc(void) {
      //ADC10AE0 |= INCH_1; // Ativar analógico na A1
      ADC10CTL1 = INCH_1 + ADC10DIV_3;        
      ADC10CTL0 = SREF_0 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
      ADC10AE0 |= BIT1;
      __delay_cycles(1000);                   
      ADC10CTL0 |= ENC + ADC10SC;            
      __bis_SR_register(CPUOFF + GIE);  
            
      tempCalibrated = ADC10MEM;
    }
    
    unsigned int value = 0;
    
    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR (void)
    {
      __bic_SR_register_on_exit(CPUOFF);       
    }
    
    int main( void ) {
      WDTCTL = WDTPW + WDTHOLD;          // Desliga Watchdog timer
      P1DIR |= 0xFF;
      P1OUT |= 0x00;
      //P1OUT = (BIT0 + BIT1 + BIT2);
        
      BCSCTL1 = CALBC1_1MHZ;             // Seleciona fonte de clock           
      DCOCTL = CALDCO_1MHZ;              // Configura fonte de clock
      BCSCTL2 &= ~(DIVS_3);              // Demais configurações de clock         
      ConfigureAdc();    
      __enable_interrupt();              // HabiPlita interrupções
      while(1) {    
        __delay_cycles(1000);            // Atraso de 1000 ciclos
        ADC10CTL0 |= ENC + ADC10SC;      // Valor do AD = sensor interno de temp.
        __bis_SR_register(CPUOFF + GIE); // Desliga CPU e habilita interrupções
       value= ADC10MEM;                 // Obtem o valor do AD
      
      
      if ((value > 0) & (value < 1023)) 
    	P1OUT |= 0x00;
        else 
          if (value >= 127) 
    	P1OUT |= 0x01;
        else 
          if (value >= 354) 
    	P1OUT |= 0x02;
        else 
          if (value >= 500)
    	P1OUT |= 0X07;
        else 
          if (value >= 506) 
    	P1OUT |= 0x0F;
        else
          if (value >= 635) 
    	P1OUT |= 0x1F;
        else
          if (value >= 762) 
    	P1OUT |= 0x3F;
        else
          if (value >= 889) 
    	P1OUT |= 0x6F;
        else 
          if(value >= 1016) 
    	P1OUT |= 0xFF;    
       
       }}

  • I have a suggestion. You are trying to debug two things at once: (a) reading the correct values from the ADC (b) displaying them on the LEDs.

    I suggest you debug (a) first: Replace (for the moment) all those if()s down at the bottom with this:
    > P1OUT = (value >> 2);
    This will give you a value proportional to the ADC reading directly on the LEDs. It won't match your (non-linear) scale exactly, but you will be able to watch where the "highest" lit LED is as you adjust the potentiometer. (And the code is very simple.)

    Once you're happy with that, then you can work through (b).
  • I made some changes to the IF of the code and managed to make it work as I needed it. The mistake was at my limits in the IF, as you said earlier in your first few tips. Many thanks to all for the help!

**Attention** This is a public forum