I am using the MSP4305529's 12 bit ADC to acquire voltage readings. 8 samples are taken then averaged by a SCALE_FACTOR of 3. The result is then stored in sum_adc_data.
sum_adc_data >>= SCALE_FACTOR;
I wanted to output the value as a voltage, so we stored the value in vout. In order to get the correct voltage we multiplied by the appropriate ADC12_RATIO (2500/4095).
vout = sum_adc_data * ADC12_RATIO;
the problem is that when I check the registers in CCS vout does not give me the appropriate value. I decided to just copy the value from the sum_adc_data to vout.
vout = sum_adc_data ;
I still obtained the same result for vout. Below I have provided the code and a screenshot of the registers:
#include <msp430.h>
#include <stdint.h>
#include "TI_LMP91000.h"
#include "TI_LMP91000_register_settings.h"
#include "TI_MSP430.h"
#include "TI_MSP430_hardware_board.h"
#include "TI_MSP430_i2c.h"
/*----------------------------------------------------------------------------*/
void ADC12_Init(void); // To init MSP430F5528 ADC12 & Start Conversion
/*----------------------------------------------------------------------------*/
#define NUM_OF_RESULTS 8 // Number of temp sensor samples to take
#define SCALE_FACTOR 3 // For averaging converted samples
#define ADC12_RATIO 0.61035 // 2500/4096 (2.5V reference & 12bit converter)
//******************************************************************************
void main(void)
{
uint8_t status = TI_LMP91000_NOT_READY;
uint8_t read_val[2]; // buffer to store register values
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
TI_LMP91000_LED_PxOUT |= TI_LMP91000_LED_PIN; // Set LED ON
TI_LMP91000_LED_PxDIR |= TI_LMP91000_LED_PIN; // Set pin direction is output
I2CSetup(LMP91000_I2C_Address); // Initialize I2C module
TI_LMP91000_MENB_PxOUT &= ~TI_LMP91000_MENB_PIN; // Enable \MENB Pin
TI_LMP91000_MENB_PxDIR |= TI_LMP91000_MENB_PIN; // Set pin direction is output
while (status == TI_LMP91000_NOT_READY)
status = LMP91000_I2CReadReg(TI_LMP91000_STATUS_REG); // Read device ready status
LMP91000_I2CWriteReg(TI_LMP91000_LOCK_REG, TI_LMP91000_WRITE_UNLOCK); // unlock the registers for write
LMP91000_I2CWriteReg(TI_LMP91000_TIACN_REG, TI_LMP91000_TIACN_REG_VALUE); // Modify TIA control register
LMP91000_I2CWriteReg(TI_LMP91000_REFCN_REG, TI_LMP91000_REFCN_REG_VALUE); // Modify REF control register
read_val[0] = LMP91000_I2CReadReg(TI_LMP91000_TIACN_REG); // Read to confirm register is modified
read_val[1] = LMP91000_I2CReadReg(TI_LMP91000_REFCN_REG); // Read to confirm register is modified
if ((read_val[0] != TI_LMP91000_TIACN_REG_VALUE) ||
(read_val[1] != TI_LMP91000_REFCN_REG_VALUE)) // test values took effect
while (1); // otherwise error
LMP91000_I2CWriteReg(TI_LMP91000_LOCK_REG, TI_LMP91000_WRITE_LOCK); // lock the registers
LMP91000_I2CWriteReg(TI_LMP91000_MODECN_REG, TI_LMP91000_MODECN_REG_VALUE); // 3-lead amperometric cell
ADC12_Init(); // Initialize MSP430F5528 ADC12 & Start Conversion
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0, Enable interrupts
__no_operation(); // For debugger
}
// Description: Initialization of the ADC12 Module & Start Conversion
/*----------------------------------------------------------------------------*/
void ADC12_Init(void)
{
TI_LMP91000_VOUT_ADC12_PxSEL |= TI_LMP91000_VOUT_ADC12_PIN; // Enable A/D channel A0
REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to
// ADC12_A ref control registers
ADC12CTL0 = ADC12ON+ADC12SHT0_8+ADC12MSC; // Turn on ADC12, set sampling time
// set multiple sample conversion
ADC12CTL0 |= ADC12REFON+ADC12REF2_5V; // Turn on Ref Gen & set to 2.5V
ADC12MCTL0 = ADC12SREF_1; // Vr+ = Vref+ and Vr- = AVSS
ADC12CTL1 = ADC12SHP+ADC12CONSEQ_2; // Use sampling timer, set mode
ADC12IE = ADC12IE0; // Enable ADC12IFG.0
__delay_cycles(500); // delay to allow Ref to settle
ADC12CTL0 |= ADC12ENC; // Enable conversions
ADC12CTL0 |= ADC12SC; // Start conversion
}
/*----------------------------------------------------------------------------*/
// Description:
// ADC12 Interrupt Service Routine
/*----------------------------------------------------------------------------*/
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
static uint8_t index = 0;
static volatile uint16_t results[NUM_OF_RESULTS]; // To store ADC output
static uint32_t sum_adc_data = 0; // accumulate and avg adc results
static volatile float vout; // lmp91000 vout
switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflow
case 4: break; // Vector 4: ADC timing overflow
case 6: // Vector 6: ADC12IFG0
results[index] = ADC12MEM0; // Move results
sum_adc_data += ADC12MEM0;
index++; // Increment results index, modulo;
if (index == NUM_OF_RESULTS)
{
sum_adc_data >>= SCALE_FACTOR; // Divide by NUM_OF_RESULTS
vout = sum_adc_data * ADC12_RATIO; // LMP91000 vout
sum_adc_data = 0; // Set Breakpoint here & see measured vout
index = 0;
}
break;
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
here are the results when we multiply with the ADC12_RATIO:
here are the results when the ratio is removed
shouldn't my vout have the same value as sum_adc_data since all i did was assign the value to vout? Is there a problem with float types in the msp430? How can I fix this issue?




