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.

CCS/TM4C123GE6PM: If else satement is not behaving as expected, might be due to the value for the "now" varaiable.

Part Number: TM4C123GE6PM

Tool/software: Code Composer Studio

Hello, 

I am trying to detect a rising edge from an input signal using the Tiva C, I am trying to do this using loops. 

I am running into a problem with the variables for the loop, I am trying to keep the input pin on read for loop by anding it with a binary value, however, I am not sure if I am doing this correctly. 

These are the variables that I am using:

#define PIND                0x00000010
#define SIGANLIN_PIN        GPIO_PIN_4 

And here is the loop that I am calling to detect the rising and falling edge:

          if (pulsevalue != 0)
                    {
                    UARTprintf("Pulses detected\n");
                    //this will enable the pulses to be read
                    SafteyCountdown(); //Will blink the LED to show the program will start running
                    while(1) {
                        last = 0;
                      now = PIND & (1<<SIGNALIN_PIN);
                      if (now != last) {
                         if (now > 0){
                                         bpm++;//rising edge, do something
                                         GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3 | GPIO_PIN_0, GPIO_PIN_3);  //Need to output to the high pin
                                     }
                         else
                            {
                                //need to output to the low pin
                             GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_3, GPIO_PIN_0);
                            }


                           last = now; //remember state for next pass
                          } //end of now != last
                         } //end of while
                        UARTprintf("Interrupt Conducted\n");
                        //    InterruptEnable();
                    }
                else
                    {
                    //This will allow the program to be run the same way if there are no pulses present
                    UARTprintf("Pulses not detected\n");
                    SafteyCountdown(); //Will blink the LED to show the program will start running
                   // InterruptEnable();
                    while(1) {
                      now = PIND & (1<<SIGNALIN_PIN);
                      if (now != last) {
                         if (now > 0){
                                         bpm++;//rising edge, do something
                                         GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3 | GPIO_PIN_0, GPIO_PIN_3); //Need to output to the high pin
                                     }
                         else
                             {
                               //Need to output to low pin
                               GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_3, GPIO_PIN_0);
                             }

                           }
                           last = now; //remember state for next pass
                       } //end of now != last
                     } //end of while
                    UARTprintf("Interrupt Conducted\n");

  • Hi,

    Not sure what your problem really is as I'm not clear what problem you are facing and what is not working.

    Are you trying to set both the PA3 and PA0 or only PA3? When you write GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3 | GPIO_PIN_0, GPIO_PIN_3) you are only setting PA3, not both PA3 and PA0. This is the first comment I have. If you want to set both PA3 and PA0 then you will need to write GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3 | GPIO_PIN_0, GPIO_PIN_3 | GPIO_PIN_0).

    BTW, you can configure the pin to generate interrupt when a specified edge is detected. This is all done by the hardware. In the Interrupt ISR you can take additional actions, i.e. set or clear other pins. Wouldn't you consider this method for your project?
  • Hi Charles,

    I have considered interrupts and have written a code using them but I do not have a super strong background in coding so I don't understand interrupts very well and therefore I couldn't get my orginal code to work.

    So in hopes of being able to understand my code, I have resorted to loops. I am trying to write to PA3 and PA0 individually. I am trying to write to PA3 when the rising edge is detected and PA0 when there is no rising edge (so technically the falling edge).
  • Hi,

     Interrupt is not difficult to handle. You are creating a superloop structure which will not help down the road when you need to add new features into your project. Below is an example code that demonstrates interrupt generation when a pin (PJ0 in the TM4C129 devcice which is connected to the SW1 on the TM4C129 launchpad) is pressed. Once in the SW1Hnadler interrupt ISR, it just reloads a timer to toggle another pin. Note this is a sample code for TM4C129 device. You will need to port to TM4C123 device if you want to use the interrupt mode.

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/timer.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    
    
    #define USER_LED1  GPIO_PIN_0
    #define USER_LED2  GPIO_PIN_1
    uint32_t ui32SysClock;
    
    
    //*****************************************************************************
    //
    // Counter to count the number of interrupts that have been called.
    //
    //*****************************************************************************
    static volatile uint32_t g_ui32Counter = 0;
    
    
    //*****************************************************************************
    //
    // The interrupt handler for the Timer0 interrupt.
    //
    //*****************************************************************************
    void
    Timer0IntHandler(void)
    {
        //
        // Clear the timer interrupt flag.
        //
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
    
        if ((g_ui32Counter % 2) == 0){
            GPIOPinWrite(GPIO_PORTN_BASE, (USER_LED1|USER_LED2), USER_LED1);
    
        } else {
            GPIOPinWrite(GPIO_PORTN_BASE, (USER_LED1|USER_LED2), USER_LED2);
    
        }
    
        //
        // Update the periodic interrupt counter.
        //
        g_ui32Counter++;
    
    
    }
    
    void SW1Handler (void)
    {
        GPIOIntClear(GPIO_PORTJ_BASE, GPIO_PIN_0);
        ui32SysClock *= 1.2;
        TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock / 2);
    
    }
    
    
    
    //*****************************************************************************
    //
    // Configure Timer0B as a 16-bit periodic counter with an interrupt
    // every 1ms.
    //
    //*****************************************************************************
    int
    main(void)
    {
    
    
    
        //
        // Set the clocking to run directly from the external crystal/oscillator.
        // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
        // crystal on your board.
        //
    
        ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_OSC), 25000000);
    
        //
        // The Timer0 peripheral must be enabled for use.
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    
        //
        // Enable and wait for the port to be ready for access
        //
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPION))
        {
        }
    
        //
        // Configure the GPIO port for the LED operation.
        //
        GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, (USER_LED1|USER_LED2));
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
        while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOJ)));
        GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0);
    //    HWREG(GPIO_PORTJ_BASE + GPIO_O_PUR) = GPIO_PIN_0;
        GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
        GPIOIntTypeSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_FALLING_EDGE);
        GPIOIntRegister(GPIO_PORTJ_BASE, SW1Handler);
        GPIOIntEnable(GPIO_PORTJ_BASE, GPIO_INT_PIN_0);
        IntEnable(INT_GPIOJ);
        //
        // Configure Timer0B as a 16-bit periodic timer.
        //
        TimerConfigure(TIMER0_BASE,  TIMER_CFG_PERIODIC);
    
    
        //
        // Set the Timer0B load value to 1ms.
        //
        TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock / 2);
    
        //
        // Enable processor interrupts.
        //
        IntMasterEnable();
    
        //
        // Configure the Timer0B interrupt for timer timeout.
        //
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
        //
        // Enable the Timer0B interrupt on the processor (NVIC).
        //
        IntEnable(INT_TIMER0A);
    
        //
        // Initialize the interrupt counter.
        //
        g_ui32Counter = 0;
    
        //
        // Enable Timer0B.
        //
        TimerEnable(TIMER0_BASE, TIMER_A);
    
        //
        // Loop forever while the Timer0B runs.
        //
        while(1)
        {
    
        }
    }
    

  • Hi Charles,

    This is a good exmaple, thank you.
    However, I don't believe I will have time to implement it with my current project.
    Hopefully I will be able to come back to it eventually.
    Thank you