Other Parts Discussed in Thread: TLC5951
Tool/software: Code Composer Studio
See my code below. I catch two analog values into two separate 16-Bit-Integer with the SD16 from the MSP430F2013. Now I do this only with the peripherals ADC and SPI in LMP0 (because of a hint of Mr. Kaustubh Kulkarni). However, the values still jumps. On P1.1 the value is constant 170 mV and on P1.2 the value is zero (GND).
For P1.1 I get values between 19561 and 18399.
For P1.2 the value jumps from 0 to 437.
Is this normal, or is still something not good in my code?
Best regards
Franz Peter Zantis
//using the MSP430F2013 as ADU
//23. Mai 2017, F.P.Zantis
//data transfer works with blocks of 2 16-Bit-Words (INT16)
//new values are delivered from the ADU in the rhythm of 1954Hz / 20
#include "msp430x20x3.h"
unsigned int flag=4; //4=INCH_4,P1.1; 1=INCH_1,P1.2
unsigned int counter;
unsigned int valP11; //value at P1.1, value to transfer
unsigned int valP12; //value at P1.2, value to transfer
unsigned int val; //current value from the ADC
unsigned int valP1x; //result from 10 ADC-values
unsigned int trash; //if wrong data appear
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_1; //divider through 2; 1MHz --> 500kHz both divider results for 500kHz for the ADU
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; //continous 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 500kHz/256=1954Hz Samplerate
SD16CCTL0 |= SD16SC; //start conversion
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 = 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(LPM0_bits + GIE); // Enter LPM0 with interrupt
}
#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
if (P1IFG & BIT0) //check if Bit 0 from P1 is relevant
{
SD16CCTL0 &= ~SD16IE; //interrupt disable for ADU; to make sure, that no ADU-interrupt stops this current interrupt
//USISR=valP11; //write value at P1.1 into the SPI-Register; already done in SD16_ISR
USICNT |= 16; //load counter and start transmission with 16 Bit-Word
while(!(USIIFG & USICTL1)); //wait until data are tranfered
USISR=valP12; //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 for P1
SD16CCTL0 |= SD16IE; //interrupt enabled for ADU
}
#pragma vector = SD16_VECTOR
__interrupt void SD16ISR(void)
{
switch (SD16IV)
{
case 2: //SD16MEM Overflow
trash = SD16MEM0;
break;
case 4: //SD16MEM0 IFG
val = SD16MEM0;
if (val > valP1x)
{
valP1x=val;
}
// SD16CCTL0 &= ~SD16IFG; //clear interrupt flag; automatically done by catching SD16MEM0-value
counter++;
if (counter>9) //the highest value of 9 is taken
{
SD16CCTL0 &= ~SD16SC; //stop conversion, because of switching the channels
if (flag == 4) //value through A4+
{
valP11=valP1x;
USISR=valP1x;
flag = 1; //switch for next value is from P1.2
SD16INCTL0 = SD16INCH_1; //switch for next value is from P1.2
}
else //value through A1+
{
valP12=valP1x;
flag = 4; //switch for next value is from P1.1
SD16INCTL0 = SD16INCH_4; //switch for next value is from P1.1
}
counter=0;
valP1x=0;
SD16CCTL0 |= SD16SC; //start conversion
}
}
}