Jump to content
Sign in to follow this  
LadyInRed

Generate a delay using Timer0A - Stellaris LM4F120H5QR

Recommended Posts

 
Hi, guys.
 
I am a beginner in Stellaris microcontroller programming.
 
I try to generate a delay of 1 sec (1 sec - led ON, 1 sec - led OFF).
 
I have selected the timer0A - 16 bits. Delay - 1sec. Frequency = 4 MHz
 
T = 1 / 4Mhz = 250 nsec.
 
So, to generate a delay of 1 sec : 1.000.000.000 nsec / 250 nsec = 4.000.000 
 
4.000.000 = 62.500 * 64;
 
But i think in my code i must set another bit, i dont know if it is correct, his name "main interrupt".
 
Here is my code : 
 

 

#include<stdint.h>

#include"inc/tm4c123gh6pm.h"
#include"inc/hw_timer.h"
 
void Timer0IntHandler()
{
        volatile uint32_t counter=0;
        TIMER0_CTL_R |= TIMER_CTL_TAEN;             // timer module 0 is enabled
        GPIO_PORTF_DATA_R &= ~(0x08);                   // PIN_F3 is clear
        if (TIMER_RIS_TAMRIS == 1)                                // the TAMRIS bit in the GPTMRIS register is set
        {
               counter++;
               if(counter >= 64)
               {
                         counter = 0;
                         GPIO_PORTF_DATA_R |= 0x08;                        // PIN_F3 is set
                         TIMER0_ICR_R |= TIMER_ICR_TAMCINT;      // Writing a 1 to this bit clears the TAMRIS bit in the GPTMRIS register
               }
        }
}
 
int main()
{
        volatile uint32_t temp;
 
        SYSCTL_RCC_R = SYSCTL_RCC_OSCSRC_INT4;        // set the system clock to 4 MHz.
 
        SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;              // enable the GPIO port that is used for the on-board LED
        temp = SYSCTL_RCGC2_R;                                                   // do a dummy read to insert a few cycles after enabling the peripheral
        GPIO_PORTF_DIR_R |= 0x08;                                                // set the direction as output
        GPIO_PORTF_DEN_R |= 0x08;                                              // enable the GPIO pin for digital function
 
        SYSCTL_RCGCTIMER_R |= SYSCTL_RCGCTIMER_R0;          // timer module 0 is enabled and a clock is provided
        TIMER0_CTL_R &= ~TIMER_CTL_TAEN;                                      // timer module 0 is disabled
        TIMER0_CFG_R |= TIMER_CFG_16_BIT;                                      // select the 16-bit timer configuration
        NVIC_SW_TRIG_R |= 0x13;                                                               // enable the interrupt for timer module 0
        TIMER0_TAMR_R |= TIMER_TAMR_TAMR_PERIOD | TIMER_TAMR_TAMIE | TIMER_TAMR_TACDIR;                            // enable the periodic timer mode
                                                                                                                                                                                                                          // an interrupt is generated when the match value in the GPTMTAMATCHR register is reached                                
                                                                                                                                                                                                                         // the timer counts up starting from 0x00
        TIMER0_TAILR_R = 0xF424;                                                                                                                                   // the timer counts up until is equal or greather than the value from TIMER0_TAMATCHR_R; in this moment an interrupt is generated
        TIMER0_TAMATCHR_R = 0xF424;                                                                                                                         // same thing
        TIMER0_IMR_R |= TIMER_IMR_TAMIM;                                                                                                                // Timer A Match Interrupt Mask - interrupt is enabled
        while(1)
        {
 
        }
 
}

 

 

Share this post


Link to post
Share on other sites

Hi and welcome to the world of easy programming and not-caring-about-register-bits! ;-)

 

A big advantage of the Stellaris controllers is the driverlib, which makes it very easy to use peripherals like timers.

 

This is an example of how to configure a periodic 100ms-timer with Timer0A with the driverlib. You can easily switch to 1s timer by changing the divider in the TimerLoadSet function call.

You have to install StellarisWare to use this code http://www.ti.com/tool/sw-lm3s

#include "driverlib/timer.h"
#include"inc/hw_timer.h"

//*****************************************************************
//Setup Timer0
//*****************************************************************

TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler)
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()/10); //Divider 1/10 sec = 100ms
IntEnable(INT_TIMER0A);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

//Enable Timer
TimerEnable(TIMER0_BASE, TIMER_A);

Share this post


Link to post
Share on other sites

Hi.

I try to test a program from "Getting Started with the Stellaris EK-LM4F120XL LaunchPad Workshop", lab 4 "Interrupts and the Timer" (see :

).

I dont understand what is the mistake.

Look at this code : 


#include<stdio.h>
#include<stdbool.h>
#include<stdint.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"

int main()
{
	unsigned long ulPeriod;

	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
	TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

	ulPeriod = (SysCtlClockGet() / 10) / 2;
	TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);

	IntEnable(TIMER_A);
	TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
	IntMasterEnable();

	TimerEnable(TIMER0_BASE, TIMER_A);
	while(1)
	{
	}
}
void Timer0IntHandler()
{
	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);                  // Clear the timer interrupt
	if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))                     // Read the current state of the GPIO pin and write back the opposite state
	{
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
	}
	else
	{
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
	}
}

And this is the startup_ccs file.

//*****************************************************************************
//
// Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2011-2013 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************

#include <stdint.h>

//*****************************************************************************
//
// 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 Timer0IntHandler(void);

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

//*****************************************************************************
//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
// To be added by user

//*****************************************************************************
//
// 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))((uint32_t)&__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
    Timer0IntHandler,                       // Timer 0 subtimer A
    IntDefaultHandler,                      // Timer 0 subtimer B
    IntDefaultHandler,                      // Timer 1 subtimer A
    IntDefaultHandler,                      // Timer 1 subtimer B
    IntDefaultHandler,                      // 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
    0,                                      // Reserved
    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
    0,                                      // Reserved
    0,                                      // Reserved
    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)
    {
    }
}

Share this post


Link to post
Share on other sites

Hi,

Mircea, when defining interrupts number, that one for timer A is Timer 0 sub timer A, so your call to enable interrupts for timer 0 A should be:

IntEnable(INT_TIMER0A);

@ example was good, - compare with yours.

L

Share this post


Link to post
Share on other sites

Hi,

Yes, there is not a constant TIMER_A (or if it is) it has not the value 35 needed to specify the vector interrupt location 35 in vector interrupt table. Simply the interrupt is not taken because it is not found. The correct interrupt number is to be found in file hw_ints.h. 

L

EDIT: found it - TIMER_A is specified and has the value 255, not 35, so the interrupt vector is not taken (more likely to generate a hard fault..)

Share this post


Link to post
Share on other sites

Hi,

 

Yes in file hw_ints.h : #define  INT_TIMER0A_TM4C123     35          // 16/32-Bit Timer 0A

So i made this modification : IntEnable(INT_TIMER0A_TM4C123); - and regardles at this i am not receive any kind of error.

 

But in this moment i receive many errors and i think is not because of that modification, but in the same time i have included all header files where are defined predefined functions.

 

  #10010 errors encountered during linking; "LM4F - LaunchPad - 04.out" not built LM4F - LaunchPad - 04 C/C++ Problem

  unresolved symbols remain LM4F - LaunchPad - 04 C/C++ Problem

  unresolved symbol GPIOPinRead, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol GPIOPinTypeGPIOOutput, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol GPIOPinWrite, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol IntEnable, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol IntMasterEnable, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol SysCtlClockGet, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol SysCtlClockSet, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol SysCtlPeripheralEnable, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol TimerConfigure, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol TimerEnable, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol TimerIntClear, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol TimerIntEnable, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
  unresolved symbol TimerLoadSet, first referenced in ./main.obj LM4F - LaunchPad - 04 C/C++ Problem
 

Share this post


Link to post
Share on other sites

sounds like the driverlib stuff isn't being linked in, however, you don't really need it-

 

add

#define TARGET_IS_BLIZZARD_RB1

#include "driverlib/rom.h"

 

to the top of your source file (well, not the very top, but under the rest of the #include "driverlib/...." stuff) and change all your driverlib calls so they're prefixed with ROM_

e.g. ROM_SysCtlClockSet, ROM_TimerIntClear, ROM_TimerLoadSet, ROM_IntEnable, etc.

Share this post


Link to post
Share on other sites

Finally works.

 

Thank you for your support. Thank you very much.

 

One more question.

In my opinion i think when i created the project i made a mistake.

Like you said the driverlib isn't linked. 

If this file is linked i think is not necessary to made the modifications that you told me.

 

Can you tell me how to do it ?

Thank you.

Share this post


Link to post
Share on other sites

just curious why are all the other interrupts in the other heading while the Timer interrupt goes in the other heading.

 

 

in Startup_ccs why should

extern void Timer0IntHandler(void);

be under the heading 

//*****************************************************************************

//
// External declarations for the interrupt handlers used by the application.
//
//*****************************************************************************
// To be added by user   <<<<<<<<*          

 

instead of 

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×