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.

MSP430I2040: ADC programming

Part Number: MSP430I2040

Hi,

I am working on EVM430I2040S which has msp430i2040 on it. I am using three channels of ADC. One for voltage sampling, one for current sampling and third for temperature. The voltage and current samples are sent to PC through UART terminal. The sampling rate required is 2 KHz. Baud rate used is 115200. I applied sinusoidal input at the input channels but I am not getting sinusoidal output. I think there is case of under sampling but I am unable to spot the problem in code. What should I do to achieve a sampling rate of 2KHz and transmission using UART. Please find the attached code.

#include <msp430.h> 
unsigned int i;
unsigned int value1,value2;
unsigned char val_low,val_high;
unsigned int value;
/*
 * main.c
 */
void main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    P2DIR |= BIT3;					// Set P1.0 to output direction
	SD24CTL=SD24REFS;           // Internal Reference
	SD24CCTL0|=SD24GRP;    //Group with channel 1
	SD24CCTL1|=SD24GRP|SD24IE;   // Group with channel 2 and enbling interrupt
	SD24INCTL1=0x20;          // Gain=16 for channel 1
	SD24CCTL2=0x00;
	SD24INCTL2=0x06;          // Internal temp sensor to channel 2
	

	P1SEL0|= BIT2|BIT3;          //P1.2,3 eUSCI_A function
	P1SEL1&= ~(BIT2|BIT3);
	UCA0CTLW0|=UCSWRST;          // Hold eUSCI in reset
	UCA0CTLW0|= UCSSEL_2;        //SMCLK
	UCA0BR0=0x8E;                // 115200 baud
	UCA0BR1=0x00;
	UCA0MCTLW=0x0022;
	UCA0CTLW0&=~(UCSWRST);       //Release from reset


	for (i=0; i<20; i++)
	{
		__delay_cycles(16000);    //1ms delay
	}

	SD24CCTL2|=SD24SC;            // Set bit to start conversion
	__bis_SR_register(LPM0_bits|GIE);

}

#pragma vector= SD24_VECTOR
__interrupt void SD24_ISR(void)
{
	value1=SD24MEM0;             // Voltage
	value2=SD24MEM1;             // Current
	value= SD24MEM2;             // temperature
	SD24PRE0= 0xFF;              // delay in next conversion of channel 0
	SD24PRE1= 0xFF;              // delay in next conversion of channel 1

	val_high=(value1>>8)&(0xFF);
	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
	UCA0TXBUF = val_high;      // TX -> RXed character
	val_low=value1&(0xFF);
	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
	UCA0TXBUF = val_low;      // TX -> RXed character


	val_high=(value2>>8)&(0xFF);
	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
	UCA0TXBUF = val_high;      // TX -> RXed character
	val_low=value2&(0xFF);
	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
	UCA0TXBUF = val_low;      // TX -> RXed character
	P2OUT ^= BIT3;				// Toggle P1.0 using exclusive-OR


	}

  • What is the frequency of the sine wave you are applying?
  • Hello,

    Comparing your code to the msp430i20xx_sd24_01.c code example (which I would recommend doing yourself), I see that you're using three Sigma Delta ADC channels and you're grouping them together with the SD24GRP bit. However, you'll notice in the code example that the interrupt enable should be on the master channel, Channel 2. Here, you're enabling the interrupt on Channel 1.

    Also, you can remove the following lines of code from your ISR, since they aren't actually changing the preload. Regardless, this approach is unnecessary because the ISR gets triggered automatically (when configured as continuous sampling) for each sample. The sampling rate can be calculated by dividing the modulation frequency (Fmod) by the Oversampling Rate (OSR). There are several E2E threads that discuss how to do this, so I would recommend searching for those.

    SD24PRE0= 0xFF;              // delay in next conversion of channel 0
    SD24PRE1= 0xFF;              // delay in next conversion of channel 1
    

    Regards,

    James

    MSP Customer Applications

  • Hi,
    Sine wave frequency is 50 Hz. Channel 1 interrupt is enabled because I want to enter ISR only when channel 1 results are available. Master channel is producing results with a sampling frequency 0f 4 KHz. I cannot transfer data at this frequency through UART so I delay conversion results of channel 1 and 2 by 255 cycles of SD24 clock, thus sampling frequency of channel 1 and 2 is 2 KHz and this can be sent through UART at 115200.

    Best Regards,
    Abhishek.
  • Hello,

    I would try lowering your baud rate to 9600 for now until you get everything working. Next, in your existing code, you're not actually delaying the conversion by the preload, since you're configuring the mask and not the register. Changing the preload does not change the sampling frequency. Also, I would recommend sending the UART data in main() and outside of the SD ISR.

    Regards,

    James

    MSP Customer Applications
  • Hello,

    Have you resolved your issue?

    Regards,

    James

    MSP Customer Applications
  • Hi,

    No, the issue still remains. I tried data logging with a different strategy. This time I am first storing samples in an array and then sending them through UART at 9600 baud rate. I am still not able to receive correct characters on receiver. I tried to debug this issue with a logic analyser. On the TXD pin logic analysers is not able to correctly receive characters. It is showing a framing error with character that it decoding. Please suggest how can this error be removed. Please find the attached code:

    #include <msp430.h> 
    
    /*
     * main.c
     */
    unsigned int value1[401];
    unsigned int value2[401];
    //unsigned int value3[200];
    unsigned int i,j,k;
    unsigned char val_low,val_high;
    //unsigned int g;
    
    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
        P2DIR |= BIT3;					// Set P1.0 to output direction
            	SD24CTL=SD24REFS;           // Internal Reference
            	SD24CCTL0|=SD24GRP;    //Group with channel 1
            	SD24CCTL1|=SD24IE;   // Group with channel 2 and enabling interrupt
            	SD24INCTL1=0x20;          // Gain=16 for channel 1
            	value1[0]=0xFFFF;
            	value2[0]=0xFFFF;
    
            	for (i=0; i<8000; i++)
            	                   			{
            	                   				__delay_cycles(16000);    //1ms delay
            	                   			}
    
            	    P1SEL0|= BIT2|BIT3;          //P1.2,3 eUSCI_A function
            		P1SEL1&= ~(BIT2|BIT3);
            		UCA0CTLW0|=UCSWRST;          // Hold eUSCI in reset
            		UCA0CTLW0|= UCSSEL_2;        //SMCLK
            		//UCA0CTLW0|=UCPEN|UCPAR;
            		//UCA0BR0=0x8E;                // 115200 baud
            		//UCA0BR1=0x00;
            		//UCA0MCTLW=0x0022;
            		   UCA0BR0   = 0xAA;                       // 9600 baud
            		   UCA0BR1   = 0x06;
            		   UCA0MCTLW = 0xD600;                     // 16.384MHz/9600 = 1706.6667 (See UG)
            		UCA0CTLW0&=~(UCSWRST);       //Release from reset
                   //g=0;
                   j=0;
    
    
    
                                   i=1;
                       			SD24CCTL1|=SD24SC;            // Set bit to start conversion
    
                       			__bis_SR_register(GIE);
                     while(1)
                     {
                       if(j==1)
                       {
                       SD24CCTL1&=~(SD24IE);
                       i=1;
                       for (k=0;k<=400;k++)
                       {
                        val_high=(value1[k]>>8)&(0xFF);
                       	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
                       	UCA0TXBUF = val_high;      // TX -> RXed character
                       	//__delay_cycles(32000);
                       	val_low=value1[k]&(0xFF);
                        while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
                       	UCA0TXBUF = val_low;      // TX -> RXed character
                       	//__delay_cycles(32000);
    
    
                       	val_high=(value2[k]>>8)&(0xFF);
                        while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
                       	UCA0TXBUF = val_high;      // TX -> RXed character
                       //	__delay_cycles(32000);
                       	val_low=value2[k]&(0xFF);
                       	while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
                       	UCA0TXBUF = val_low;      // TX -> RXed character
                       	//__delay_cycles(32000);
                       }
                       j=0;
                       SD24CCTL1|=SD24IE;
                   }
    
            }
    	
    }
    #pragma vector=SD24_VECTOR
    __interrupt void SD24_ISR(void)
    {
    
    	value1[i]=SD24MEM0;            // Voltage
    	value2[i++]=SD24MEM1;             // Current
    	//value3[i++]=g++;
    	if(i==401)
    	{
    		j=1;
    		//g=0;
    	}
    
    	P2OUT ^= BIT3;				// Toggle P1.0 using exclusive-OR
    
        }
    

    Best Regards,

    Abhishek.

  • Hello Abhishek,

    I would recommend removing your UART code and download/debug the rest of the code on your device. Then, after capturing 400 samples, view the array in the Watch window inside CCS. There should be a feature to export or plot the array in CCS to see if the results are sinusoidal or not. On the other hand, I would recommend starting a new project to get the UART communication working with dummy values before merging the code.

    Also, I’m happy to inform you that the official software release for the new Energy Measurement Design Center and Software Library is available on TI.com. It supports CCS and includes documentation and Design Center examples for the supported EVMs. Please download and install the release from the following link:

    www.ti.com/.../MSP430-ENERGY-MEASUREMENT

    Let me know if you have any questions.

    Regards,

    James

    MSP Customer Applications

**Attention** This is a public forum