Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 21946

MSP430F2013: Code bug Help

$
0
0

Part Number:MSP430F2013

A professor is using the MSP430F2013 as ADU. He has  problems with the code below.

The sd16 is used to digitize two channels: The value at P1.1 and P1.2. From time to time the results will be taken via SPI. In principle it works. However: from time to time (estimated 10% of the samples) wrong values or 0 occurs. Is there something wrong with the code?

//using the MSP430F2013 as ADU
//data transfer works with blocks of 2 16-Bit-Words (INT16)
//new values are delivered from the ADU in the rhythm of 977Hz

#include "msp430x20x3.h"
unsigned int flag=4;  //4=INCH_4,P1.1; 1=INCH_1,P1.2
unsigned int values[4];
//values[0]=0;
//values[1]=0;               //value at P1.1, value to transfer
//values[2]=0;            //value at P1.2, value to transfer
//values[3]=0;

int main( void )
{
WDTCTL = WDTPW + WDTHOLD;                 //Stop watchdog timer to prevent time out reset
BCSCTL1 = CALBC1_16MHZ;                        //clock SMCLK=16MHz
DCOCTL = CALDCO_16MHZ;                        //use internal DCO as clock

P1DIR &= ~BIT2;                                               //P1.2 to input; voltage sample
P1DIR &= ~BIT1;                                               //P1.1 to input; current sample

P1DIR |= BIT4;                                                   //P1.4 to output direction
P1SEL |= BIT4;                                                   //SMCLK to P1.4

P1DIR |= BIT3;                                                   //P1.3 to output direction
P1SEL |= BIT3;                                                   //Uref to P1.3

P1DIR |= BIT7;                                                   //P1.7 to output direction (LED)
P1OUT &= ~BIT7;                                             //LED off

P2SEL &= ~BIT7;                                                //select P2.7 for input/output - use
P2DIR |=  BIT7;                                                  //P2.7 to output direction

 //init ADC SD16
 SD16CTL = SD16REFON;                                                //activate reference 1,2V
 SD16CTL |= SD16SSEL_1;                                              //clock for ADU is SMCLK
 SD16CTL |= SD16XDIV_2;                                              //divider through 16   16MHz --> 1MHz
 SD16CTL |= SD16DIV_2;                 //divider through 4; 1MHz --> 250kHz both divider results for 250kHz for the ADU
 SD16INCTL0 = SD16INTDLY_0;                                    //Interrupt on 4th sample
 SD16INCTL0 |= SD16INCH_4;                                      //default input via A4+, P1.1, Pin3
 SD16AE &= ~SD16AE1;                                                   //unipolar input via A4+, P1.1, Pin3, A4- to GND
 SD16AE &= ~SD16AE2;                                                   //unipolar input via A1+, P1.2, Pin4; A1- to GND
 SD16CCTL0 |= SD16SNGL;                                            //single conversion
 SD16CCTL0 |= SD16UNI;                                                //16-Bit unsigned
 SD16CCTL0 |= SD16IE;                                   //interrupt enabled for ADU
 SD16CCTL0 &= ~SD16XOSR;                                          //set oversampling ratio selector
 SD16CCTL0 |= SD16OSR_256;                      //oversampling ratio for the low-pass-filter 250kHz/256=977Hz Samplerate

 USICTL0 &= ~USISWRST;                                      //USI released for operation
 USICTL1 &= ~USII2C;                                        //clear the I²C-Bit to switch USI to SPI-Mode
 USICTL0 &= ~USIMST;                                         //reset Masterbit to be SPI-Slave
 USICTL0 |= USIPE5;                                           //SPI-clock via Pin7 (from Warrior56)
 USICTL0 |= USIPE6;                                           //SDO-Port enabled; Pin8
 USICTL0 &= ~USIPE7;                                          //SDI-Port disabled; Pin9 can be used for normal in/out
 USICTL0 &= ~USILSB;                                          //MSB first
 USICKCTL &= ~USICKPL;                                     //clock is low when idle
 USICTL1 &= ~USICKPH;                                      //get data on the first edge
 USICTL0 |= USIOE;                                              //activate output (data goes from MSP to Warrior56
 USICNT |= USI16B;                                              //init load counter for 16-bit-data

//---------- init for data exchange -------------
//init interrupt for P1.0 as CS
 P1DIR &= ~BIT0;                                                               //P1.0 for input
 P1REN |= BIT0;                                                                  //P1.0 pullup
 P1IE |= BIT0;                                                                     //P1.0 enabled for interrupt via P1.0
 P1IES |= BIT0;                      //select P1.0 for interrupt with falling edge --> in the ISR is that CS for SPI
 P1IFG = P1IFG & (~BIT0);                                             //clear Interrupt Flag

 _BIS_SR(GIE);                                                                   //enable all interrupts

 while(1)
 {
    USISR=values[1];          //write value at P1.1 into the SPI-Register; the second value (from P1.2) will loaded if the SPI-Request comes up
    P1IE = P1IE | BIT0;                                        //enable interrupt P1.0
    SD16CCTL0 |= SD16SC;                                //start conversion
 }
}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
//ISR if the level at P1.0 jumps from high to low
// if ((P1IFG & BIT0) && !(P2IN & BIT7) ) check if Bit 0 from P1 is relevant and additional P2.7 is not high
 P1IE = P1IE & (~BIT0);                                     //disable interrupt
 SD16CCTL0 &= ~SD16SC;         //stop conversion ADU; to make sure, that no ADU-interrupt stops this current interrupt
 if (P1IFG & BIT0) //check if Bit 0 from P1 is relevant
 {
     SD16CCTL0 &= ~SD16SC;                           //stop ADU-conversion - to be on the save side
     //USISR=values[1];                     //write value at P1.1 into the SPI-Register; is already done in main()
     USICNT |= 16;                                                //load counter and start transmission with 16 Bit-Word
     while(!(USIIFG & USICTL1));                    //wait until data are tranfered

     USISR=values[2];                                          //write value at P1.2 into the SPI-Register
     USICNT |= 16;                                                 //load counter and start transmission with 16 Bit-Word
     while(!(USIIFG & USICTL1));                      //wait until data are tranfered

     P1OUT ^= BIT7;                                            //toggle P1.7 if a new value has been transfered
 }
P1IFG = P1IFG & (~BIT0);                                  //clear Interrupt Flag
//P1IE = P1IE | BIT0;                                           //enable interrupt; is made in main()
}

#pragma vector = SD16_VECTOR
 __interrupt void SD16ISR(void)
{
   //SD16CCTL0 &= ~SD16SC;         //stop conversion; because of single conversion mode: conversion stops automatically
   if (flag == 4)
   {
     values[1]=SD16MEM0;                                //save value to transfer value from P1.1 via SPI
     flag = 1;                                                             //switch for next value is from P1.2
     SD16INCTL0=SD16INCH_1;                         //switch for next value is from P1.2
   }
   else
   {
     values[2]=SD16MEM0;                               //save value to transfer value from P1.2 via SPI
     flag = 4;                                                            //switch for next value is from P1.1
     SD16INCTL0=SD16INCH_4;                         //switch for next value is from P1.1
   }
  // SD16CCTL0 &= ~SD16IFG;       //clear interrupt flag; automatically done by catching SD16MEM0-value
}

Could anyone help me this please?

Thank you in advance.

Kaustubh


Viewing all articles
Browse latest Browse all 21946

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>