0
\$\begingroup\$

I am currently using the MSP430FR4133 in order to make an ultrasonic measurement system for the volume of a room and would like to be able to check the temperature of a room to work out the speed of sound before I carry out any calculations. I am trying to use the code in the "Out-the-Box Software Example" that uses the temperature sensor to display the temperature in Celsius and Fahrenheit. This folder is found at: http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP-EXP430FR4133/latest/index_FDS.html.

My code is as follows:

main.c

#include <msp430.h>
#include <driverlib.h>
#include "hal_LCD.h"
#include "InputOutput.h"
#include "Temp.h"
#include "Displays.h"

#define PORT1_VECTOR        (47 * 2u)
#define TIMER1_A0_VECTOR    (54 * 2u) 

char introduction[6] = "HELLO";

int main(void)
{
WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer

tempInit();
InitInputs();
InitOutputs();
Init_LCD();
double speedofsound = tempInit();
displayScrollText(introduction);

// Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
PMM_unlockLPM5();

while(1)
{
      double distance[3];
      double time[3];
      double volume = 0;

      displayLength();
      SW1();
      displayWait();
      time[0] = SW2();
      displayWidth();
      SW1();
      displayWait();
      time[1] = SW2();
      displayHeight();
      SW1();
      displayWait();
      time[2] = SW2();

      for(int i =0;i<3;i++)
      {
            distance[i] = time[i]*speedofsound;
      }

      volume = distance[0]*distance[1]*distance[2];
      displayVolume(volume);
    }
}

Temp.c

#include <msp430.h>
#include <driverlib.h>
#include "hal_LCD.h"
#include "Temp.h"

#define CALADC_15V_30C  *((unsigned int *)0x1A1A)       // Temperature Sensor Calibration-30 C
#define CALADC_15V_85C  *((unsigned int *)0x1A1C)       // Temperature Sensor Calibration-85 C

volatile unsigned char * tempUnit = &BAKMEM4_H;
volatile int *degC = &BAKMEM5;                          // Celcius measurement
volatile unsigned char * tempSensorRunning = &BAKMEM3_H;      // Temp Sensor running flag
int deg;

Timer_A_initUpModeParam initUpParam_A1 =
{
    TIMER_A_CLOCKSOURCE_ACLK,               // ACLK Clock Source
    TIMER_A_CLOCKSOURCE_DIVIDER_1,          // ACLK/1 = 32768Hz
    0x2000,                                 // Timer period
    TIMER_A_TAIE_INTERRUPT_DISABLE,         // Disable Timer interrupt
    TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE ,   // Disable CCR0 interrupt
    TIMER_A_DO_CLEAR                        // Clear value
};

Timer_A_initCompareModeParam initCompParam =
{
    TIMER_A_CAPTURECOMPARE_REGISTER_1,        // Compare register 1
    TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, // Disable Compare interrupt
    TIMER_A_OUTPUTMODE_RESET_SET,             // Timer output mode 7
    0x1000                                    // Compare value
};

double tempInit()
{
  *tempSensorRunning ^= 0x01;
  *tempSensorRunning =1;
  //Initialize the ADC Module
  /*
   * Base Address for the ADC Module
   * Use Timer trigger 1 as sample/hold signal to start conversion
   * USE MODOSC 5MHZ Digital Oscillator as clock source
   * Use default clock divider of 1
   */
  ADC_init(ADC_BASE,ADC_SAMPLEHOLDSOURCE_2,ADC_CLOCKSOURCE_ADCOSC,ADC_CLOCKDIVIDER_1);

ADC_enable(ADC_BASE);

//Configure Memory Buffer
/*
 * Base Address for the ADC Module
 * Use input A12 Temp Sensor
 * Use positive reference of Internally generated Vref
 * Use negative reference of AVss
 */
    ADC_configureMemory(ADC_BASE,ADC_INPUT_TEMPSENSOR,ADC_VREFPOS_INT,ADC_VREFNEG_AVSS);

    ADC_clearInterrupt(ADC_BASE, ADC_COMPLETED_INTERRUPT);

    // Enable the Memory Buffer Interrupt
    ADC_enableInterrupt(ADC_BASE,ADC_COMPLETED_INTERRUPT);

    ADC_startConversion(ADC_BASE, ADC_REPEATED_SINGLECHANNEL);

    // Enable internal reference and temperature sensor
    PMM_enableInternalReference();
    PMM_enableTempSensor();

    // TimerA1.1 (125ms ON-period) - ADC conversion trigger signal
    Timer_A_initUpMode(TIMER_A1_BASE, &initUpParam_A1);

    //Initialize compare mode to generate PWM1
    Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam);

    // Start timer A1 in up mode
    Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);

    // Delay for reference settling
    __delay_cycles(300000);

    while(*tempSensorRunning)
    {
        __bis_SR_register(LPM3_bits | GIE);                       // LPM3 with interrupts enabled
        //__no_operation();                                         // Only for debugger

        // Calculate Temperature in degree C and F
        signed short temp = (ADCMEM0 - CALADC_15V_30C);
        *degC =((long)temp * 10 * (85-30) * 10)/((CALADC_15V_85C-CALADC_15V_30C)*10) + 300;

        *tempSensorRunning = 0;
    }
    double speed = 331+0.6*(*degC);
    return speed;
    };

I have made slight adjustments to the code in order to find the speed of sound for the temperature of the room, however this code does not seem to work. I get a warning a value of type "unsigned short volatile *" cannot be used to initialize an entity of type "int volatile *"(line 10 of Temp.c) which I don't think is effecting my code, however I am unsure on how to correct this.

When I set breakpoints within the code I is seen that at if(*tempSensorRunning)the code runs into an endless loop. Can anyone please give me some advice for this problem?

EDIT:

I have changed the code for Temp.c slightly to illustrate the suggested changes. Having set breakpoints throughout the code I can see that the problem is occuring at signed short temp = (ADCMEM0 - CALADC_15V_30C);. The code is stopping here and not moving past this point. The disassembly is staying at the point:

?reset_vector:
010000

Can anyone explain what is happening here?

\$\endgroup\$
3
  • \$\begingroup\$ no it's not correct \$\endgroup\$ Commented Mar 2, 2016 at 17:03
  • \$\begingroup\$ This question would be better if you pointed out the exact line that triggers the error (or warning) message from the compiler. \$\endgroup\$ Commented Mar 2, 2016 at 19:56
  • \$\begingroup\$ @AdrianMcCarthy sorry I forgot about that, I have made changes to this \$\endgroup\$
    – Aidan Howie
    Commented Mar 2, 2016 at 20:16

2 Answers 2

1
\$\begingroup\$

The variable tempSensorRunning is set to 1 in the line:

*tempSensorRunning = 1;

and never (at least in this code) cleared to 0, so that's where your infinite loop comes from.

This device is a 16-bit MCU, so int in this case is 16-bits long. In any case, this is confusing, so to be sure you're using the correct bit width for accesses (especially as you're accessing data via pointers), include <stdint.h> and be explicit:

  • uint8_t for unsigned 8-bit numbers
  • uint16_t for unsigned 16-bit numbers
\$\endgroup\$
1
  • \$\begingroup\$ Thank you, I have edited the code to solve the endless loop problem. However I don't think that was the problem, I have stated above where the problem seems to be happening. If you can help with this at all it would be very helpful \$\endgroup\$
    – Aidan Howie
    Commented Mar 3, 2016 at 18:26
0
\$\begingroup\$

I assume the warning comes from this line:

volatile int *degC = &BAKMEM5;

Apparently BAKMEM5 is a short, not an int. The way to correct it is to change the type of degC to volatile short *. This fix may have ripple effects. You have to use the right types consistently.

This is likely an actual bug and not just a warning you can ignore.

\$\endgroup\$
4
  • \$\begingroup\$ When changing this to volatile short * it comes up with a different warning. This warning is a value of type "unsigned short volatile *" cannot be used to initialize an entity of type "short volatile *". I am unsure on why this error is coming up. \$\endgroup\$
    – Aidan Howie
    Commented Mar 3, 2016 at 17:23
  • 1
    \$\begingroup\$ Based on your edit, it looks like the problem is that the MCU is being placed into a low power mode with (__bis_SR_register(LPM3_bits | GIE);), which stops the oscillator. To 'wake up', you need an interrupt service routine (presumably for the ADC), which I don't see in your code. If you remove the __bis_SR_register(LPM3_bits | GIE); line, the code should continue running, but you may stop getting conversion results (depending on the how the ADC is configured). \$\endgroup\$
    – Ed King
    Commented Mar 4, 2016 at 9:17
  • \$\begingroup\$ @EdKing this fixed the problem. I knew that it would go into low power at one point just didn't know when. Thank you very much, this problem has bee frustrating me for days! \$\endgroup\$
    – Aidan Howie
    Commented Mar 4, 2016 at 13:50
  • \$\begingroup\$ @EdKing that's not right. LPM3 does not turn off the oscillator or ACLK, which is what OP is using. LPM3_bits = (SCG1+SCG0+CPUOFF), not like LPM4_bits = (SCG1+SCG0+OSCOFF+CPUOFF) \$\endgroup\$
    – Passerby
    Commented Mar 12, 2016 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.