Hello all,
I am currently coding the MSP430G2231 for my senior design project and I am getting an error that I can't seem find a solution for. This program reads a voltage from pins 1.2 and 1.3, does an ADC conversion, converts the values to an ASCII characters then outputs it via UART. If only using 2 pins, it works perfectly. When I add in the 3rd pin, I get the error:
Error[e16]: Segment CSTACK (size: 0x32 align: 0x1) is too long for segment definition. At least 0x1 more bytes needed. The problem occurred while processing the segment placement command
"-Z(DATA)CSTACK+_STACK_SIZE#", where at the moment of placement the available memory ranges were "CODE:24f-27f"
Reserved ranges relevant to this placement:
200-24e DATA16_Z
24f-27f CSTACK
This is beyond my knowledge and I would appreciate if anyone had any suggestions for this can be changed or corrected. I am still new to using the MSP430 so if you could please provide specific details or someone where I could find, that would be greatly appreciated and helpful.
Here is the code:
/******************************************************************************
* MSP-EXP430G2-LaunchPad Application
*
*
* -Measures voltage at pin 1.1 and voltage at pin 1.2
* -Transmits data as two bytes in format: temp_byte,a7_byte\n\r
* -Blinks the red LED during UART transmission at 2400bps
*
******************************************************************************/
#include "msp430g2231.h"
#define LED_RED BIT0
#define LED_GRN BIT6
#define LED_DIR P1DIR
#define LED_OUT P1OUT
#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2
#define APP_STANDBY_MODE 0
#define APP_APPLICATION_MODE 1
#define TIMER_PWM_MODE 0
#define TIMER_UART_MODE 1
#define TIMER_PWM_PERIOD 2000
#define TIMER_PWM_OFFSET 20
//Conditions for 2400 Baud SW UART, SMCLK = 1MHz
#define Bitime_5 0x05*4 //~0.5 bit length + small adjustment
#define Bitime 13*4
#define UART_UPDATE_INTERVAL 200 //Controls the frequency of data transmission
//Variables for UART transmission
unsigned char BitCnt;
unsigned char TXByte;
/* Variables for a 4-value moving average filter on sampled ADC values */
unsigned char measuredPosition=0;
long pinONE[4]; // Pin 1.2
long pinTWO[4]; // Pin 1.1
long pinTHREE[4];
long pinONEaverage;
long pinTWOaverage;
long pinTHREEaverage;
// Functions to Convert an 8-bit binary value to two ASCII chars
char hexChars[16];
//Function prototypes
void InitializeLeds(void);
void ConfigureADC(void);
void ConfigureTimerUart(void);
void Transmit(void);
void InitializeClocks(void);
void InitHexChars(void);
char convertNumToHex_Low(int num); // could pass in int if ADC makes 10 bit or 12 bit num
char convertNumToHex_Med(int num);
char convertNumToHex_High(int num); // could pass in int if ADC makes 10 bit or 12 bit num
void main(void)
{
unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL;
unsigned char i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
InitializeClocks(); // Configure system clocks
InitializeLeds(); // Configure both LEDs for output
ConfigureADC(); // Setup the ADC
ConfigureTimerUart(); // Configure timers for use in software UART
__enable_interrupt(); // Enable interrupts.
InitHexChars(); // initialize an array of the ASCII hex 0, 1 ... F
/* Main Application Loop */
while(1)
{
ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_2 + ADC10DIV_3; // Temp Sensor, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
//Add ADC measurement to the averaging array
pinONE[measuredPosition] = ADC10MEM;
ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_3 + ADC10DIV_3; // Input A7, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
//Add ADC measurement to the averaging array
pinTWO[measuredPosition] = ADC10MEM;
ADC10CTL0 &= ~ENC; // Disable conversion
ADC10CTL1 = INCH_4 + ADC10DIV_3; // Input A7, Clock = ADC10CLK/4
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
//Add ADC measurement to the averaging array
pinTHREE[measuredPosition] = ADC10MEM;
//Increment our position in the averaging array and reset if at end
measuredPosition++;
if (measuredPosition == 4) measuredPosition = 0;
//Reset final average value variables
pinONEaverage = 0;
pinTWOaverage = 0;
pinTHREEaverage = 0;
//Sum previous four measurements for average
for (i = 0; i < 4; i++){
pinONEaverage += pinONE[i];
pinTWOaverage += pinTWO[i];
pinTHREEaverage += pinTHREE[i];
}
pinONEaverage >>= 2; // Divide by 4 (via bitwise shift) to get average
pinTWOaverage >>= 2; // Divide by 4 (via bitwise shift) to get average
pinTHREEaverage >>= 2; // Divide by 4 (via bitwise shift) to get average
if (--uartUpdateTimer == 0)
{
//Turn on the green LED
LED_OUT |= (LED_RED);
//TXByte = (unsigned char)(pinONEaverage);
TXByte = convertNumToHex_High( (int) (pinONEaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinONEaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinONEaverage) );
Transmit();
//TXByte = (unsigned char)(pinONEaverage);
//Transmit a comma separator
TXByte = ',';
Transmit();
//TXByte = (unsigned char)(pinTWOaverage);
TXByte = convertNumToHex_High( (int) (pinTWOaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinTWOaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinTWOaverage) );
Transmit();
//Transmit a comma separator
TXByte = ',';
Transmit();
//TXByte = (unsigned char)(pinTHREEaverage);
TXByte = convertNumToHex_High( (int) (pinTHREEaverage) );
Transmit();
TXByte = convertNumToHex_Med( (int) (pinTHREEaverage) );
Transmit();
TXByte = convertNumToHex_Low( (int) (pinTHREEaverage) );
Transmit();
//Transmit a comma separator
TXByte = ',';
Transmit();
Transmit();
//Transmit the end-of-line characters
TXByte = '\n';
Transmit();
TXByte = '\r';
Transmit();
//Reset the UART interval timer
uartUpdateTimer = UART_UPDATE_INTERVAL;
//Turn off the green LED
LED_OUT &= ~(LED_RED);
}
}
}
//Configure the ADC registers
void ConfigureADC(void)
{
unsigned char i;
//Reference = Vref+
//Sample Lenght = 16 CLKs
//Internal 1.5V Reference Generator = On
//ACD10 = On
//ADC Interrupt = Enabled
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
// Wait for ADC Ref to settle
__delay_cycles(1000);
//Initialize averaging arrays
for (i=0; i < 4; i++){
pinONE[i] = 0;
pinTWO[i] = 0;
pinTHREE[i] = 0;
}
pinONEaverage = 0;
pinTWOaverage = 0;
pinTHREEaverage = 0;
}
void ConfigureTimerUart(void)
{
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; // SMCLK/8, continuous mode
P1SEL |= TXD + RXD; // Peripheral module selected (?)
P1DIR |= TXD; // Set TXD pin as output (P1.1)
}
// Function Transmits Character from TXByte
void Transmit()
{
BitCnt = 0xA; // Load Bit counter, 8data + ST/SP
while (CCR0 != TAR) // Prevent async capture
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
TXByte |= 0x100; // Add mark stop bit to TXByte
TXByte = TXByte << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}
// Timer A0 interrupt service routine, used by UART
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0
if (CCTL0 & CCIS0) // TX on CCI0B?
{
if ( BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt
else
{
CCTL0 |= OUTMOD2; // TX Space
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
TXByte = TXByte >> 1;
BitCnt --;
}
}
}
void InitializeClocks(void)
{
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 1 = 1MHz
}
void InitializeLeds(void)
{
LED_DIR |= LED_RED + LED_GRN;
LED_OUT &= ~(LED_RED + LED_GRN);
}
// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Return to active mode
}
//*****************************************
// Handle Hex to Ascii Conversion
void InitHexChars(void)
{
// Init the hex ASCII char array
hexChars[0] = '0';
hexChars[1] = '1';
hexChars[2] = '2';
hexChars[3] = '3';
hexChars[4] = '4';
hexChars[5] = '5';
hexChars[6] = '6';
hexChars[7] = '7';
hexChars[8] = '8';
hexChars[9] = '9';
hexChars[10] = 'A';
hexChars[11] = 'B';
hexChars[12] = 'C';
hexChars[13] = 'D';
hexChars[14] = 'E';
hexChars[15] = 'F';
}
char convertNumToHex_Low(int num) // LSB 1st ASCII char of number
{
unsigned char i;
i = (unsigned char) num & 0x00F; // Only keep lower 4 bits (3..0)
return( hexChars[i] ); // return the selected hex char
}
char convertNumToHex_Med(int num) // 2nd ASCII char of number
{
unsigned char i;
i = (unsigned char) ( (num & 0x00F0) >> 4); // Only keep lower next 4 bits (7..4)
return( hexChars[i] ); // return the selected hex char
}
char convertNumToHex_High(int num) // MSB 3rd ASCII char of number
{
unsigned char i;
i = (unsigned char) ( (num & 0x0F00) >> 8); // Only keep lower next 4 bits (7..4)
return( hexChars[i] ); // return the selected hex char
}
Thanks for any help you can provide.