Part Number: MSP430F6776A
Tool/software:
New to embedded and am trying to read the raw data from the sd24 channels that have a pressure sensor connected to it (not calibrated yet but that's not important).
I've based my code off of a library demo code that initially outputted the top 16 bits of channels 0, 1 and 2.
I modified the code to use SD24_B_getResults function to get 2 16 bit chunks. The problem with this is the first 8 0's seem to be put at the beginning of the number not the end, putting the number outside of it's 24 bit range.
I even tried bit shifting it and manually taking away the first 8 bits and the numbers still did not seem correct.
From my understanding the conversion from raw data to MV is (results/2^23) * .6 and it should give me a mv of .115 which would make the raw data be ~ 1,607,816.53. Because of the incorrect setup the outputs are around 2708761088 on channel 0 alone.
I tried checking if it might be something setup with the SD24_B_initConverterAdvancedParam settings, but changing that didn't seem to do anything either. Please let me know what I can do to get the correct reading from the sd24 channels.
//*****************************************************************************
// MSP430F67791A Demo - SD24_B, Continuous Conversion on a Group of 3 Channels
//
// Description: This program uses the SD24_B module to perform continuous
// conversions on a group of channels (0, 1 and 2). An SD24_B interrupt occurs
// whenever the conversions have completed. Test by applying voltages to the
// 3 input channels and setting a breakpoint at the line indicated
// below. Run program until it reaches the breakpoint, then use
// the debugger's watch window to view the conversion results. Results
// (upper 16 bits only) are stored in three arrays, one for each channel.
// ACLK = n/a, MCLK = SMCLK = DCO = ~ 1.1MHz
// //* For minimum Vcc required for SD24_B module - see datasheet *//
// //* 100nF cap between Vref and AVss is recommended when using 1.5V REF *//
//
// MSP430F67791A
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// Vin1+ -->|SD0P0 |
// Vin1- -->|SD0N0 |
// Vin2+ -->|SD1P0 |
// Vin2- -->|SD1N0 |
// Vin3+ -->|SD2P0 |
// Vin3- -->|SD2N0 |
// | VREF |---+
// | | |
// | | -+- 100nF
// | | -+-
// | | |
// | AVss |---+
// | |
//
// E. Chen
// Texas Instruments Inc.
// January 2014
// Built with CCS Version: 5.5.0 and IAR Embedded Workbench Version: 5.52
//*****************************************************************************
#include <msp430.h>
#include "sd24_b.h"
#include <stdio.h>
/* Number of conversion results to store */
#define Num_of_Results 8
/* Arrays to store SD24_B conversion results */
unsigned int Ch0results[Num_of_Results];
unsigned int Ch1resultsLow[Num_of_Results];
unsigned int Ch1results[Num_of_Results];
unsigned int Ch2results[Num_of_Results];
uint32_t raw24;
volatile uint32_t lastRaw = 0;
volatile uint32_t Ch0Full[Num_of_Results];
volatile uint32_t Ch1FullBeforeConvert[Num_of_Results];
volatile uint32_t Ch1Full[Num_of_Results];
volatile uint32_t Ch2Full[Num_of_Results];
uint8_t Globalconverter = SD24_B_CONVERTER_1;
//#pragma vector=SD24B_VECTOR
__interrupt void SD24B_ISR(void)
{
lastRaw = SD24_B_getResults(SD24_BASE, Globalconverter);
SD24_B_clearInterrupt(
SD24_BASE,
Globalconverter,
SD24_B_CONVERTER_INTERRUPT
);
__bic_SR_register_on_exit(LPM0_bits); // wake main loop
}
void AlignmentSetup(void){
SD24_B_initParam modParam = {
.clockSourceSelect = SD24_B_CLOCKSOURCE_SMCLK,
.clockPreDivider = SD24_B_PRECLOCKDIVIDER_1,
.clockDivider = SD24_B_CLOCKDIVIDER_1,
.referenceSelect = SD24_B_REF_INTERNAL
};
SD24_B_init(SD24_BASE, &modParam);
// —————————————————————————————
// 2) Advanced per-converter init
// (right-aligned, two’s-complement,
// 1× PGA, OSR=256, continuous)
// —————————————————————————————
SD24_B_initConverterAdvancedParam advParam = {
.converter = SD24_B_CONVERTER_0, // channel 0 (SD0P0/SD0N0)
.alignment = SD24_B_ALIGN_RIGHT, // right-aligned
.startSelect = SD24_B_CONVERSION_SELECT_SD24SC,
.conversionMode = SD24_B_CONTINUOUS_MODE,
.dataFormat = SD24_B_DATA_FORMAT_2COMPLEMENT,
.sampleDelay = SD24_B_FOURTH_SAMPLE_INTERRUPT, // no interrupt delay
.oversampleRatio = SD24_B_OVERSAMPLE_256, // 256× OSR
.gain = SD24_B_GAIN_1 // unity PGA
};
SD24_B_initConverterAdvanced(SD24_BASE, &advParam);
advParam.converter = SD24_B_CONVERTER_1; // channel 1
SD24_B_initConverterAdvanced(SD24_BASE, &advParam);
advParam.converter = SD24_B_CONVERTER_2; // channel 2
SD24_B_initConverterAdvanced(SD24_BASE, &advParam);
// —————————————————————————————
// 3) Enable interrupts on channel 2 only
// (as in the demo)
// —————————————————————————————
SD24_B_enableInterrupt(SD24_BASE,
SD24_B_CONVERTER_2,
SD24_B_CONVERTER_INTERRUPT);
// —————————————————————————————
// 4) Start bucket-brigade / group conversion:
// group0 = converters 0–2
// —————————————————————————————
// TRGCTL1 holds the group-start bits (grp0 = bit0)
HWREG16(SD24_BASE + OFS_SD24BCTL1) |= SD24GRP0SC;
// —————————————————————————————
// 5) Enter LPM0 w/ interrupts
// —————————————————————————————
//__bis_SR_register(LPM0_bits | GIE);
/* */
}
uint32_t raw;
int32_t signedResult;
int32_t Convert2(int32_t bounds) {
int32_t raw = (int32_t)(lastRaw >> 8);
return (raw << 8) >> 8; // Sign-extend 24-bit into 32-bit by shifting
}
int32_t Convert(uint32_t x)
{
int32_t t = x & 0xffffff;
return t - (t >> 23 << 24);
}
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
SD24BCTL0 = SD24REFS | SD24SSEL_1; // Select internal REF
// Select SMCLK as SD24_B clock source
AlignmentSetup(); // does this update alignments? Moving it stop register interrupts.
SD24BCCTL0 = SD24ALGN | SD24SCS_4; // Left-aligned, group 0
SD24BCCTL1 = SD24ALGN | SD24SCS_4; // Left-aligned, group 0
SD24BCCTL2 = SD24ALGN | SD24SCS_4; // Left-aligned, group 0
SD24BIE = SD24IE2; // Enable channel 2 interrupt
__delay_cycles(0x3600); // Delay for 1.5V REF startup
SD24BCTL1 |= SD24GRP0SC; // Set bit to start conversion
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=SD24B_VECTOR //ties interrupt to below function
__interrupt void SD24BISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(SD24B_VECTOR))) SD24BISR (void)
#else
#error Compiler not supported!
#endif
{
static unsigned int index = 0;
switch (SD24BIV)
{
case SD24BIV_SD24OVIFG: // SD24MEM Overflow
break;
case SD24BIV_SD24TRGIFG: // SD24 Trigger IFG
break;
case SD24BIV_SD24IFG0: // SD24MEM0 IFG
break;
case SD24BIV_SD24IFG1: // SD24MEM1 IFG
break;
case SD24BIV_SD24IFG2: // SD24MEM2 IFG
{
raw = SD24_B_getResults(SD24_BASE, Globalconverter) & 0x00FFFFFF; // Mask to 24 bits
if (raw & 0x00800000) {
raw |= 0xFF000000; // Sign-extend if negative
}
signedResult = (int32_t)raw;
lastRaw = SD24_B_getResults(SD24_BASE, Globalconverter);
Ch0Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_0); //gives me ~2708761088
Ch1Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_1); //gives me ~2360862464
//Ch1FullBeforeConvert[index] = Ch1Full[index] ;
//Ch1Full[index] = Convert2(Ch1Full[index]);
Ch2Full[index] = SD24_B_getResults(SD24_BASE, SD24_B_CONVERTER_2); //gives me ~2148898816
Ch0results[index] = SD24BMEMH0; // Save CH0 results (clears IFG)
Ch1resultsLow[index] = SD24BMEML1; // Low CH1 results (clears IFG)
Ch1results[index] = SD24BMEMH1; // Save CH1 results (clears IFG)
Ch2results[index] = SD24BMEMH2; // Save CH2 results (clears IFG)
if (++index == Num_of_Results)
{
index = 0; // SET BREAKPOINT HERE
}
break;
}
}
}