Part Number: MSP430G2553
Hello!
I have a school project where MSP430G2ET launchpad measures soil moisture and runs a pump when soil is dry. It's also measures light and save some data to flash but I have commented those lines out. Problem occours when I try run launchpad without IAR debugger. Launchpad will freeze and program will not run. I have blinking led control in my timer interrupt (1 s cycle) so I know when the program will run. Led will not blink and stays on when I exit from debugger. When I press reset same thing happens. I think the problem is in times interrupt routine, but I can not figure that out.
#include <msp430.h>
//#include"stdio.h"
//Setup
//Moisture sensor input pin = P1.1
//Light sensor input pin = P1.0+9/
//Moisture sensor operating voltage 5v
//Light sensor operating voltage 3.3-5v
//Pump transistor base pin = P2.1
//Pump drive voltage 3-6v (tested with 3v)
//Flash memory write
unsigned int * const savedDataPtr = (unsigned int *)(0x1000); //Memory pointer
unsigned int savedData = 0; //Variable for moisture cycle counter
unsigned char * hourMemPtr = (unsigned char *)(0x1002);
unsigned char * minuteMemPtr = (unsigned char *)(0x1003);
unsigned char * secondMemPtr = (unsigned char *)(0x1004);
unsigned int * const lightAVGPtr = (unsigned int *)(0x1040);
unsigned int * const lightMemPtr = (unsigned int *)(0x1080);
// Average calculations
unsigned char L = 0; //Count for light array string
unsigned char M = 0; //Count for moisture array string
unsigned int sumL = 0; //Count variable for light function
int sumM = 0; //Count variable for moisture function
int average_UV; //10s average UV-light value
int average_MST; //10s average moisture value
char arrayL[120]; //Light average data array in RAM
int arrayM[10]; //Moisture average data array in RAM
char averageL(); //Function call
int averageM();
unsigned char lightCycles = 0; //Light measurement cycles
//Set moisture levels
int mstMIN = 15; //Moisture minimum level 0-100%
int mstMAX = 70; //Moisture maximum level
//Time set
char seconds = 5; //60 seconds
char minutes = 55; //60 minutes
char hours = 15; //24 hours
char time; //Delay counter
//State machine
int STATE;
#define MEASURE 1 //Moisture measure
#define PUMP 2 //Run pump
#define WAITS 3 //Wait after the pump sequency
#define PUMP2 4 //Pump to maximum moisture
void main(void)
{
//ADC10
WDTCTL = WDTPW + WDTHOLD; //Stop WDT
ADC10CTL0 = ADC10SHT_3 + SREF_0;
//Sensor & time interrupt routine
TA0CCTL0 = CCIE; //CCR0 interrupt enabled
TA0CCR0 = 32767; //K�y liian nopeasti (1s / min) Kalibroitava!
TA0CTL = TASSEL_1 + MC_1 + ID1; //ACLK, upmode
BCSCTL3 |= XCAP_3; //Internal capasitor 12.5uF for timer
BCSCTL3 |= LFXT1S_0;
STATE = 1; //Set state start value
//PWM
TA1CCR0 = 255; //Timer will count to this number
TA1CTL = TASSEL_1 + MC_1 + ID1; //ACLK, upmode, nodivider
TA1CCTL1 |= OUTMOD_7;
P2DIR |= BIT1; //2.1 output pin for pump
P2SEL |= BIT1;
P1DIR |= 0x01;
////Erase flash memory bank 2
//FCTL2 = FWKEY + FSSEL1 + FN0; //FWKEY + clock source + divider
//FCTL1 = FWKEY + ERASE; //ERASE enabled
//FCTL3 = FWKEY; //LOCK disabled
//*lightAVGPtr = 0; //Erase flash memory bank 2
//while((FCTL3 & BUSY)); //Wait until unbusy
//FCTL1 = FWKEY; //Clear WRITE
//FCTL3 = FWKEY + LOCK; //LOCK enabled
//
////Erase flash memory bank 1
//FCTL2 = FWKEY + FSSEL1 + FN0;
//FCTL1 = FWKEY + ERASE;
//FCTL3 = FWKEY;
//*savedDataPtr = 0;
//while((FCTL3 & BUSY));
//FCTL1 = FWKEY;
//FCTL3 = FWKEY + LOCK;
//
////Erase flash memory bank 3
//FCTL2 = FWKEY + FSSEL1 + FN0;
//FCTL1 = FWKEY + ERASE;
//FCTL3 = FWKEY;
//*lightMemPtr = 0;
//while((FCTL3 & BUSY));
//FCTL1 = FWKEY;
//FCTL3 = FWKEY + LOCK;
while(1){
switch (STATE){
case MEASURE:{ //Measure sequency
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupt
break;
}
case PUMP:{ //Pump over minimum moisture
TA1CCR1 = 150; //Pump pulse wildth (150 seems to be good)
if(average_MST >= mstMIN) //If average_MST is greater or equal to mstMIN set STATE to WAIT
{
STATE = WAITS;
}
break;
}
case WAITS:{ //30s wait period that soil moisture is balanced
TA1CCR1 = 0;
time = seconds; //30s time calculations
if(time > 30){
time = 30 - (60 - time);
}
else{
time += 30;
}
__bis_SR_register(LPM0_bits + GIE);
if(average_MST <= mstMIN){ //If average_MST is less or equal to mstMIN start pump sequency again
STATE = PUMP;
}
else if(average_MST >= mstMIN && average_MST <= mstMAX){ //If average_MST is greater than mstMIN and less than mstMAX start pump sequency 2
STATE = PUMP2;
}
else{ //Else return to measure
STATE = MEASURE;
// memData(); //Function call for flah memory data write
}
break;
}
case PUMP2:{ //Pump to final maximum moisture
TA1CCR1 = 100;
if (average_MST >= mstMAX) //If average_MST is greater or equal to mstMAX start 30s waiting period
{
STATE = WAITS;
}
break;
} //end of case
} //end of Switch
} //end of while
} //enf of main
//char averageL(){ //Average light calculator loop 0-100%. If you want LUX multiply average by 10.
//
// unsigned char average;
// unsigned char loop;
// int sensorData; //Data from sensor 0-1023
// float sensDataFloat = 0;
// char lightArrayData;
//
// ADC10CTL1 = INCH_0 + ADC10DIV_7 + CONSEQ_0; //ADC10 channel A0
// ADC10CTL0 = ENC + ADC10SC + ADC10ON; //ADC10 Enable Conversion
// while ((ADC10CTL1 & ADC10BUSY) == 0x01);
//
// sensorData = ADC10MEM; //Save ADC-memory to variable
// ADC10CTL0 &= ~ENC; //Disable ADC
// sensDataFloat = (float)sensorData;
// lightArrayData = (char)(0.09775 * sensDataFloat);
//
// arrayL[L] = lightArrayData; //Add UV-light measurement to char array
// L = L+1;
//
// for(loop = 0; loop < 120; loop++) { //Count array sum
// sumL += arrayL[loop];
// }
//
// average = sumL / 120; //Counting average from array sum
//
// if(hours == 22 && minutes == 59){ //Count and save days average light to flash
//
// L = 0;
// sumL += *lightAVGPtr;
// sumL = sumL / 18;
// FCTL2 = FWKEY + FSSEL1 + FN0; //FWKEY + clock source + divider
// FCTL1 = FWKEY + ERASE; //ERASE enabled
// FCTL3 = FWKEY; //LOCK disabled
// *lightMemPtr = 0; //Erase flash memory bank 3
// FCTL1 = FWKEY + WRT; //WRITE enabled
// *lightMemPtr = sumL; //Memory addres = lightMemPtr
// FCTL1 = FWKEY; //Clear WRITE
// FCTL3 = FWKEY + LOCK; //LOCK enabled
// }
//
// if (L == 120){ //Save 1 hour average light to flash
//
// L = 0;
// sumL += *lightAVGPtr; //Add exist flash light value to array sum
// FCTL2 = FWKEY + FSSEL1 + FN0; //FWKEY + clock source + divider
// FCTL1 = FWKEY + ERASE; //ERASE enabled
// FCTL3 = FWKEY; //LOCK disabled
// *lightAVGPtr = 0; //Erase flash memory bank 2
// FCTL1 = FWKEY + WRT; //WRITE enabled
// *lightAVGPtr = sumL; //Memory addres = lightAVGPtr
// FCTL1 = FWKEY; //Clear WRITE
// FCTL3 = FWKEY + LOCK; //LOCK enabled
// }
//
// sumL = 0; //Initalize sumL
//
// return average;
//
// }
int averageM(){ //Average moisture calculator loop
int average;
float averageFloat;
unsigned char loop;
int sensorData;
ADC10CTL1 = INCH_1 + ADC10DIV_7 + CONSEQ_0; //ADC10 channel A1
ADC10CTL0 = ENC + ADC10SC + ADC10ON; //ADC10 Enable Conversion
while ((ADC10CTL1 & ADC10BUSY) == 0x01);
sensorData = ADC10MEM; //Save ADC-memory to variable
ADC10CTL0 &= ~ENC; //Disable ADC
if (M == 10){ //Initalize array string counter
M = 0;
}
arrayM[M] = sensorData; //Add moisture measurement to array
M = M+1;
for(loop = 0; loop < 10; loop++) { //Count array sum
sumM += arrayM[loop];
}
averageFloat = 100 - (sumM / 10 - 400) * 0.25641; //Calculation average moisture from array sum. Converting 0-1024 range to 0-100. Calibrate average value so that sensor in the air(dry) is 0 and in the water is 100.
average = (int)averageFloat; //From float to int
sumM = 0; //Initalize sum
return average;
}
//int memData(){ //Function writes data to flash memory
//
// //Flash data write
// savedData = *savedDataPtr + 1;
// FCTL2 = FWKEY + FSSEL1 + FN0; //FWKEY + clock source + divider
// FCTL1 = FWKEY + ERASE; //ERASE enabled
// FCTL3 = FWKEY; //LOCK disabled
// *savedDataPtr = 0; //Erase flash memory bank 1
// FCTL1 = FWKEY + WRT; //WRITE enabled
// *savedDataPtr = savedData; //Memory addres = savedData
// *hourMemPtr = hours;
// *minuteMemPtr = minutes;
// *secondMemPtr = seconds;
// FCTL1 = FWKEY; //Clear WRITE
// FCTL3 = FWKEY + LOCK; //LOCK enabled
//
// return 0;
//}
#pragma vector = TIMER0_A0_VECTOR // Timer A0 interrupt. Running every 1 second.
__interrupt void Timer_A0 (void)
{
seconds += 1; //Clock second count
if (seconds == 60)
{
minutes += 1; //Clock minute count
seconds = 0;
}
if (minutes == 60)
{
hours += 1; //Clock hour count
minutes = 0;
}
if (hours == 24)
{
hours = 0;
}
// if (seconds == 0 || seconds == 30 && hours >= 5 && hours <= 22)
// {
// average_UV = averageL(); //Function call
// }
average_MST = averageM();
P1OUT ^= 0x01;
if(average_MST <= mstMIN){ //If average_MST is less than mstMIN exit interrupt
STATE = PUMP;
__bic_SR_register_on_exit(CPUOFF);
}
if(seconds == time){ //Exit interrupt if second = time (30 second wait period)
__bic_SR_register_on_exit(CPUOFF);
}
}
