This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

problems with the EK-LM4F120XL Launchpad and arrays

hi,

i'm a student from germany, but i'm study supply engineering and didn't learned programming. But i wan't to learn it with books, internet etc. and i have read very much and did most of your workshops, and read very much in forums. but now i have a problem which i can't solve on my own.

i wan't to read the values of the adc into an array. this is no problem with 15 values (array[15]). but then i wan't to make an array with 100 values (array[100]) the code stops by an FaultISR(). and i don't know why. 

i wan't to build a fast logger, wich samples at 1000hz and writes the values of the adc first in an array[2000] and after logging (2s logging because 2000 values at 1000Hz==>2s)  the values of the array will be send over the uart to the pc

Here's the code (necessary passage  yellow colored) 

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/adc.h" //for the ADC
#include "driverlib/debug.h"
#ifdef DEBUG
void__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

int main(void)
{
unsigned long ulPeriod;

SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //Set the System Clock to 40 MHZ; 16MHZ_XTAL ==>400MHZ PPL / 2 /SYSDIV_5 =40MHZ

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//enable periphery GPIO port F for rgb led
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);//enable periphery GPIO port E for ADC
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);//enable periphery GPIO port D for ADC
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//enable periphery GPIO port B for ADC
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3); // Set the Pin PB4 to analog input on
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1); // Set the Pin PB4 to analog input on
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3); // Set the Pin PB4 to analog input on
GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4); // Set the Pin PB4 to analog input on
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); //port F as output; pin 1 2 3 = output

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); //enable periphery TIMER 0
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER); // set TIMER 0 To 32 bit counting down periodic

ulPeriod = (SysCtlClockGet())*10;// ==> 10s
TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1); //Set the Count beginning to ulPeriod

IntEnable(INT_TIMER0A); //enable Interrupt on TIMER0A
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); //interrupt then Timer0A = 0
IntMasterEnable(); //enable master interrupt

TimerEnable(TIMER0_BASE, TIMER_A); //enable timer

volatile unsigned long ulTempAvg;
volatile unsigned long ulTempValueC;
volatile unsigned long ulTempValueF;

SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //enable the periphery ADC
SysCtlADCSpeedSet(SYSCTL_ADCSPEED_250KSPS); //set the periphery to 250ksps
ADCHardwareOversampleConfigure(ADC0_BASE, 64); //hardware periphery rate 64 ==> 250/64
ADCSequenceDisable(ADC0_BASE, 1); //disable ADC sequencer 1
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0); // processor triggers the adac sequencer 1, with the highest priority 0()

ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0); //sequencer 1 samples in first step the temperature sensor (ADC_CTL_TS) change adc_CTL_TS with ADC_CTL_CH0 trough ADC_CTL_CH23 for GPIOS use!!!
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH2); //sequencer 1 has 4 steps. page 761 spms294e.pdf and page 40 spmu019o
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH4);
ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH10 | ADC_CTL_IE | ADC_CTL_END); //last step; cause an interrupt (ADC_CTL_IE); set as last step of the sequence (ADC_DTL_END)
ADCSequenceEnable(ADC0_BASE, 1); //enable the ADC
unsigned long ulADC0Value[4]; //array for the 4 sequencer data
//int array[1] = { 0 };
int array[100]={0}; //array for test
while(1)
{
ADCIntClear(ADC0_BASE, 1); //clear the ADC0 Interrupt from sequencer 1
ADCProcessorTrigger(ADC0_BASE, 1); //trigger the ADC conversion
while(!ADCIntStatus(ADC0_BASE, 1, false)) //wait for conversion; better to do this with an interrupt!!
{
}

ADCSequenceDataGet(ADC0_BASE, 1, ulADC0Value); //write the values from the 4 steps into the ulADC0Value Array
ulTempAvg = (ulADC0Value[0] + ulADC0Value[1] + ulADC0Value[2] + ulADC0Value[3] + 2)/4; //
ulTempValueC = 33*((2475 * ulTempAvg) / 4096);
array[0]= ulTempAvg;
array[1]= ulTempAvg;
array[2]= ulTempAvg;
array[99]= ulTempAvg;
}
}

void Timer0AIntHandler(void)
{
// Clear the timer interrupt
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

// Read the current state of the GPIO pin and
// write back the opposite state
if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);
}
}

  • Well - you certainly are ambitious - quite a task - and you're almost there.   Overall - very good job.

    Our group always tries to, "proceed by refinement."   You report success @ array[15] - not so much @ array[100].  Have you considered - incrementally extending your array[15] success - perhaps with array[25] - then array[50]?   Such "indirectness" is frustrating to the young (I want it now) - but is less likely to so quickly - and finally - "crash and burn!"  Stack overflow is a, "usual suspect" - and the incremental approach I offer should enable you to probe that.

    Also suggest you start @ slower update rate - and w/out the "hardware oversample" - which adds needless complexity @ this early stage.  Get the basics to work - only then make one refinement (and only one) at a time - and observe.

    Devil much in the detail w/this stuff - "copy/paste PB4" ran bit amuck on you - may wish to update your comments so that when you return in the future you may avoid, "WTF?"   Served almost 2 years in Germany decades past w/US Army, Signal Corps as Radio/Radar Officer...  (great times)  My MCU then was a K&E slide rule...

  • You are right. The array is declared on the stack. Take the array declaration outside of the function, and it will work.

  • @ sign Bit: Thank's i found  own this my own, but forget it to post it here. the code that worked for me is in  the attachment. (the code is not very nice and was only for testing) 2816.array+timer+adc-version0.1.c

    But now i have another problem. I want to use the TIMER2A as counter from an gpio pin PB0. this works, but the counter doesn't stop and begins at the defined TimerLoadset. But i wan't, that the counter makes an interrupt. what's wrong with my code? 

    And what i have to  do, that an interrupt of timer0a counts down the counter of timer2a  one step?  i didn't found this in the manual. i know i could set a togglebit to another gpio an make a wire bridge to in gpioinput of the counter. but i think there must be an easier way :)

    here are the codes:

    main.c code:

    #define PART_LM4F120H5QR true //befor using pin_map.h !!!!
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/timer.h"
    #include "driverlib/adc.h" //for the ADC
    #include "driverlib/debug.h"
    #include "driverlib/pin_map.h"

    #ifdef DEBUG
    void__error__(char *pcFilename, unsigned long ulLine)
    {
    }
    #endif

    //define values

    #define counter_value 12


    int main (void)
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //Enable GPIOP Port B
    GPIOPinConfigure(GPIO_PB0_T2CCP0); //USE Pin 0 on port B for counter
    GPIOPinTypeTimer(GPIO_PORTB_BASE,GPIO_PIN_0); //USE Pin 0 on port B for counter
    //Set Timer2A as counter
    IntMasterEnable(); //enable master interrupt
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2); //enable periphery TIMER 2
    TimerDisable(TIMER2_BASE,TIMER_A);
    TimerIntDisable(TIMER2_BASE, TIMER_CAPA_MATCH);
    TimerConfigure(TIMER2_BASE, TIMER_CFG_A_CAP_COUNT ); // set TIMER 2 To 24 bit counting down one shot
    TimerLoadSet(TIMER2_BASE, TIMER_A, counter_value); //Set the Count for Timer2A to 0
    TimerControlEvent(TIMER2_BASE, TIMER_A, TIMER_EVENT_BOTH_EDGES); //count then GPIO Pin
    TimerMatchSet(TIMER2_BASE, TIMER_A, 1);//TimerMatchSet(TIMER2_BASE,TIMER_A,5);
    TimerIntEnable(TIMER2_BASE, TIMER_CAPA_MATCH); //interrupt when countervalue=1
    IntEnable(INT_TIMER2A); //enable Interrupt on TIMER2A
    TimerEnable(TIMER2_BASE, TIMER_A);

    int counter=15;
    while(1)
    {

    counter=TimerValueGet(TIMER2_BASE,TIMER_A);


    }
    }

    void Timer2AIntHandler(void)
    {

    TimerIntClear(TIMER2_BASE, TIMER_CAPA_MATCH);
    int check;
    check=1;

    }

    and the startup_ccs.c code:

    //*****************************************************************************
    //
    // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
    // TI Information - Selective Disclosure
    //
    //*****************************************************************************

    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);

    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    extern void Timer2AIntHandler(void);


    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern unsigned long __STACK_TOP;

    //*****************************************************************************
    //
    // The vector table. Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
    (void (*)(void))((unsigned long)&__STACK_TOP),
    // The initial stack pointer
    ResetISR, // The reset handler
    NmiSR, // The NMI handler
    FaultISR, // The hard fault handler
    IntDefaultHandler, // The MPU fault handler
    IntDefaultHandler, // The bus fault handler
    IntDefaultHandler, // The usage fault handler
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    IntDefaultHandler, // SVCall handler
    IntDefaultHandler, // Debug monitor handler
    0, // Reserved
    IntDefaultHandler, // The PendSV handler
    IntDefaultHandler, // The SysTick handler
    IntDefaultHandler, // GPIO Port A
    IntDefaultHandler, // GPIO Port B
    IntDefaultHandler, // GPIO Port C
    IntDefaultHandler, // GPIO Port D
    IntDefaultHandler, // GPIO Port E
    IntDefaultHandler, // UART0 Rx and Tx
    IntDefaultHandler, // UART1 Rx and Tx
    IntDefaultHandler, // SSI0 Rx and Tx
    IntDefaultHandler, // I2C0 Master and Slave
    IntDefaultHandler, // PWM Fault
    IntDefaultHandler, // PWM Generator 0
    IntDefaultHandler, // PWM Generator 1
    IntDefaultHandler, // PWM Generator 2
    IntDefaultHandler, // Quadrature Encoder 0
    IntDefaultHandler, // ADC Sequence 0
    IntDefaultHandler, // ADC Sequence 1
    IntDefaultHandler, // ADC Sequence 2
    IntDefaultHandler, // ADC Sequence 3
    IntDefaultHandler, // Watchdog timer
    IntDefaultHandler, // Timer 0 subtimer A
    IntDefaultHandler, // Timer 0 subtimer B
    IntDefaultHandler, // Timer 1 subtimer A
    IntDefaultHandler, // Timer 1 subtimer B
    Timer2AIntHandler, // Timer 2 subtimer A
    IntDefaultHandler, // Timer 2 subtimer B
    IntDefaultHandler, // Analog Comparator 0
    IntDefaultHandler, // Analog Comparator 1
    IntDefaultHandler, // Analog Comparator 2
    IntDefaultHandler, // System Control (PLL, OSC, BO)
    IntDefaultHandler, // FLASH Control
    IntDefaultHandler, // GPIO Port F
    IntDefaultHandler, // GPIO Port G
    IntDefaultHandler, // GPIO Port H
    IntDefaultHandler, // UART2 Rx and Tx
    IntDefaultHandler, // SSI1 Rx and Tx
    IntDefaultHandler, // Timer 3 subtimer A
    IntDefaultHandler, // Timer 3 subtimer B
    IntDefaultHandler, // I2C1 Master and Slave
    IntDefaultHandler, // Quadrature Encoder 1
    IntDefaultHandler, // CAN0
    IntDefaultHandler, // CAN1
    IntDefaultHandler, // CAN2
    IntDefaultHandler, // Ethernet
    IntDefaultHandler, // Hibernate
    IntDefaultHandler, // USB0
    IntDefaultHandler, // PWM Generator 3
    IntDefaultHandler, // uDMA Software Transfer
    IntDefaultHandler, // uDMA Error
    IntDefaultHandler, // ADC1 Sequence 0
    IntDefaultHandler, // ADC1 Sequence 1
    IntDefaultHandler, // ADC1 Sequence 2
    IntDefaultHandler, // ADC1 Sequence 3
    IntDefaultHandler, // I2S0
    IntDefaultHandler, // External Bus Interface 0
    IntDefaultHandler, // GPIO Port J
    IntDefaultHandler, // GPIO Port K
    IntDefaultHandler, // GPIO Port L
    IntDefaultHandler, // SSI2 Rx and Tx
    IntDefaultHandler, // SSI3 Rx and Tx
    IntDefaultHandler, // UART3 Rx and Tx
    IntDefaultHandler, // UART4 Rx and Tx
    IntDefaultHandler, // UART5 Rx and Tx
    IntDefaultHandler, // UART6 Rx and Tx
    IntDefaultHandler, // UART7 Rx and Tx
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    IntDefaultHandler, // I2C2 Master and Slave
    IntDefaultHandler, // I2C3 Master and Slave
    IntDefaultHandler, // Timer 4 subtimer A
    IntDefaultHandler, // Timer 4 subtimer B
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    IntDefaultHandler, // Timer 5 subtimer A
    IntDefaultHandler, // Timer 5 subtimer B
    IntDefaultHandler, // Wide Timer 0 subtimer A
    IntDefaultHandler, // Wide Timer 0 subtimer B
    IntDefaultHandler, // Wide Timer 1 subtimer A
    IntDefaultHandler, // Wide Timer 1 subtimer B
    IntDefaultHandler, // Wide Timer 2 subtimer A
    IntDefaultHandler, // Wide Timer 2 subtimer B
    IntDefaultHandler, // Wide Timer 3 subtimer A
    IntDefaultHandler, // Wide Timer 3 subtimer B
    IntDefaultHandler, // Wide Timer 4 subtimer A
    IntDefaultHandler, // Wide Timer 4 subtimer B
    IntDefaultHandler, // Wide Timer 5 subtimer A
    IntDefaultHandler, // Wide Timer 5 subtimer B
    IntDefaultHandler, // FPU
    IntDefaultHandler, // PECI 0
    IntDefaultHandler, // LPC 0
    IntDefaultHandler, // I2C4 Master and Slave
    IntDefaultHandler, // I2C5 Master and Slave
    IntDefaultHandler, // GPIO Port M
    IntDefaultHandler, // GPIO Port N
    IntDefaultHandler, // Quadrature Encoder 2
    IntDefaultHandler, // Fan 0
    0, // Reserved
    IntDefaultHandler, // GPIO Port P (Summary or P0)
    IntDefaultHandler, // GPIO Port P1
    IntDefaultHandler, // GPIO Port P2
    IntDefaultHandler, // GPIO Port P3
    IntDefaultHandler, // GPIO Port P4
    IntDefaultHandler, // GPIO Port P5
    IntDefaultHandler, // GPIO Port P6
    IntDefaultHandler, // GPIO Port P7
    IntDefaultHandler, // GPIO Port Q (Summary or Q0)
    IntDefaultHandler, // GPIO Port Q1
    IntDefaultHandler, // GPIO Port Q2
    IntDefaultHandler, // GPIO Port Q3
    IntDefaultHandler, // GPIO Port Q4
    IntDefaultHandler, // GPIO Port Q5
    IntDefaultHandler, // GPIO Port Q6
    IntDefaultHandler, // GPIO Port Q7
    IntDefaultHandler, // GPIO Port R
    IntDefaultHandler, // GPIO Port S
    IntDefaultHandler, // PWM 1 Generator 0
    IntDefaultHandler, // PWM 1 Generator 1
    IntDefaultHandler, // PWM 1 Generator 2
    IntDefaultHandler, // PWM 1 Generator 3
    IntDefaultHandler // PWM 1 Fault
    };

    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event. Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called. Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
    //
    // Jump to the CCS C initialization routine. This will enable the
    // floating-point unit as well, so that does not need to be done here.
    //
    __asm(" .global _c_int00\n"
    " b.w _c_int00");
    }

    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI. This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
    }

    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt. This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
    //
    // Enter an infinite loop.
    //
    while(1)
    {
    }
    }

    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt. This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
    //
    // Go into an infinite loop.
    //
    while(1)
    {
    }
    }

  • Gratitude & response - unbounded...

    Today's request veers far from original Subject: "Arrays" - which confounds both "focused helpers" and future searchers.   New post may be more appropriate...

  • sorry that  i forget to reply to my post that i found the solution for my problem and that i didn't thank for response.  when it would be better to start a new topic about my new problem, then i'm going to do that.