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.

Launch pad

Other Parts Discussed in Thread: EK-TM4C123GXL, TM4C123GH6PM

Hi, 

I am beginner of TIVA C and software.

Now I have EK-TM4C123GXL launch pad.

I would like to make one software. The function is the following.

* Blink LED on board.

* I can change the Blink period through the UAR communication.  On Hyper Terminal, I can enter a number.

The following is my source code.

----------

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
//#include "inc/tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "driverlib/timer.h"


int kazu=1;  
uint32_t ui32Period;
uint32_t ui32Hozon;
//*****************************************************************************
//
// The Timer0 interrupt handler.
//
//*****************************************************************************
void Timer0IntHandler(void)
{
 // All interrupt disable
 IntMasterDisable();

 // Clear the timer interrupt
 TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
 TimerDisable(TIMER0_BASE, TIMER_A);

 // 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_2, 0);  //Turn off LED

 }
 else
 {
  GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); //Blink LED
 }

 TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);

 TimerEnable(TIMER0_BASE, TIMER_A);

 IntMasterEnable();
}
//*****************************************************************************
//
// The UART interrupt handler.
//
//*****************************************************************************
void
UARTIntHandler(void)
{
 // All interrupt disable
 IntMasterDisable();

    uint32_t ui32Status;

    //
    // Get the interrupt status.
    //
    ui32Status = UARTIntStatus(UART0_BASE, true);

    //
    // Clear the asserted interrupts.
    //
    UARTIntClear(UART0_BASE, ui32Status);

    //
    // Loop while there are characters in the receive FIFO.
    //
    while(UARTCharsAvail(UART0_BASE))
    {
     //
        // Read the next character from the UART and write it back to the UART.
        //

     kazu = UARTCharGetNonBlocking(UART0_BASE);

//     UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
     UARTCharPutNonBlocking(UART0_BASE, kazu);
    }
 //Timer Re-setting
//    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// TimerIntDisable(TIMER0_BASE, TIMER_A);
//    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
//    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
// ui32Period = (SysCtlClockGet() / UARTCharGetNonBlocking(UART0_BASE))/2;
// ui32Period = (SysCtlClockGet() / kazu)/2;
 ui32Period = ui32Hozon;
 ui32Period = ui32Period/kazu;

// TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);

// IntEnable(INT_TIMER0A);
// TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// TimerEnable(TIMER0_BASE, TIMER_A);

 IntMasterEnable();

}

//*****************************************************************************
//
// Send a string to the UART.
//
//*****************************************************************************
void
UARTSend(const uint8_t *pui8Buffer, uint32_t ui32Count)
{
    //
    // Loop while there are more characters to send.
    //
    while(ui32Count--)
    {
        //
        // Write the next character to the UART.
        //
        UARTCharPutNonBlocking(UART0_BASE, *pui8Buffer++);
    }
}

//*****************************************************************************
//
// This example demonstrates how to send a string of data to the UART.
//
//*****************************************************************************
int main(void)
{
 //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
//    ROM_FPUEnable();
//    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the crystal.
    //
 SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
 //SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable the GPIO pins for the LED (PF2).
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

    //
    // Enable the Timer0
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

    ui32Period = (SysCtlClockGet() / 2)/2;
    ui32Hozon = ui32Period;

    TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);

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

     TimerEnable(TIMER0_BASE, TIMER_A);

 //
    // Turn on the LED --- added 20131014 by Michi
    //
    //GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);


    //
    // Enable the peripherals used by this example.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable processor interrupts.
    //
    //IntMasterEnable();

    //
    // Set GPIO A0 and A1 as UART pins.
    //
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Configure the UART for 115,200, 8-N-1 operation.
    //
    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE));

    //
    // Enable the UART interrupt.
    //
    IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

    //
    // Prompt for text to be entered.
    //
    UARTSend((uint8_t *)"\033[2JEnter number---  ", 16);


    //
    // Loop forever echoing data through the UART.
    //
    while(1)
    {
    }

-----------

At first, LED on the board is bliking. But , when I put some number on Hyperterminal, LED blink is stopped.

The number I put on Hyperterminal is echo back correctly even though LED blinking stopped.

What is the wrong? I am beginner. So I don't know well how to handle interrupt.

Please give me advice.

Best regards,

Michi

  • Hi,

    I did not checked all your code, but I have some comments about it:

    a) You disable/enable global interrupts in each interrupt routine - this is not needed - while in timer interrupt a character arrives in UART, the UART cannot react and can miss that character - to give you a possible scenario - so remove these functions. This practice is usual in some RTOSes, but not needed for Cortex M3/M4 microcontrollers. Take into account the Cortex M3/M4 are designed to work with interrupts enabled even in RTOS (and there are such good examples).

    b) You type some "number" at the terminal to represent the period - so for example 2467 but these are just four characters you send from the terminal to the micro, while the timer need the unsigned integer 2467 to be passed to  - so you must collect all these characters individually and transform them into unsigned integer. And of coarse, keep an eye to the correlation with the micro' s clock.

    Petrei


  • Dear Petrei-san,

    Thank you for your advice.

    I removed the global interrupts disable/enable in each interrupt routine. But the symptom is the same.

    After UART interrupt occurs, LED blink is stopped.

    What part should I check?  As your advice b), I don't modify it yet. Is it needed to fix my issue?

    Best regards,

    Michi

  • Hi Michi,

         After you have made changes recommended by Petrei, debug your code and see where the led turns off.

    Michi Yama said:

    if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
     {
      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);  //Turn off LED

     }

    Put a breakpoint at GPIOPinWrite code line.

    Michi Yama said:
    else
     {
      GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); //Blink LED
     }

    I don't think that this code line above will blink the led.

    -kel

  • Hi,

    Part b) is mandatory - be sure the UART interrupt is very short - collect each sent character and convert the received string to an unsigned integer (take care about CR character...).

    You can verify (any) interrupt duration by setting hi a GPIO pin at the entry into interrupt and setting lo before exit from the interrupt. 

    Use also the debugger - place a breakpoint in UART interrupt and verify the received characters to figure out how the variables are updated.

    Regards.

    Petrei