Using method for Timer

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Kinrin
Level 2
Level 2
10 replies posted 25 sign-ins 5 replies posted

Hi guys,

 

I'm trying to use Timer to produce interrupt on my program, but comes up with a problem after compiling.

here are the error descriptions:

Build error: too few arguments to function 'Timer_1_ClearInterrupt'

Build error: The command 'arm-none-eabi-gcc.exe' failed with exit code '1'.

 

And here is my interrupt function for the timer:

Kinrin_0-1680245090857.png

Can anybody help to solve the problem?

 Many thanks!

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

So Timer_1_ClearInterrupt() need an argument.
If you read "Timer_1.c" there is a description

006-Timer_1_func.JPG

This suggest that your (or our) choice are

* - Timer_1_INTR_MASK_TC - Terminal count mask
* - Timer_1_INTR_MASK_CC_MATCH - Compare count / capture mask

As I imagined that you are using TC (terminal count), I wrote something like below

Note: I could compile, but as I don't have the board, I could not test it.

#include "project.h"

volatile int Timer1_1s = 0 ;
volatile int Timer1_3sec_flag = 0 ;

CY_ISR(timer1)
{
    Timer1_1s++ ;
    if (Timer1_1s >= 3000) {
        Timer1_3sec_flag = 1 ;
        Timer1_1s = 0 ;
    }
    Timer_1_ClearInterrupt(Timer_1_INTR_MASK_TC) ;
}

int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    timer_tc_int_ClearPending() ;
    timer_tc_int_StartEx(timer1) ;

    UART_Start() ;
    Timer_1_Start() ;

    for(;;)
    {
        if (Timer1_3sec_flag) {
            Timer1_3sec_flag  = 0 ;
            UART_UartPutString("3 sec passed\n\r") ;       
        }
    }
}

As others have already suggested, we should avoid using blocking funtion or function which take very long time inside an interrupt service routine, so I just set Timer1_3sec_flag and let the main loop take care of the rest.

By the way, if all you need is an interrupt of seconds resolutin (or ms resolution), 
we can use SysTick without consuming hardware timer.

So, I wrote a sample program using CY8CKIT-149, which has CY8C4147AZI-S475 the closest board I have with your CY8C4125LQI-S423.

Schematic

002-Schematic.JPG

Pins

003-Pins.JPG

main.c

#include "project.h"
#include "stdio.h"

volatile uint32_t tick_count = 0 ;
volatile int sec_passed_flag = 0 ;

#define STR_LEN 64
char str[STR_LEN+1] ;
void print(char *str)
{
    UART_UartPutString(str) ;
}

void cls(void)
{
    print("\033c") ; /* reset */
    CyDelay(100) ;
    print("\033[2J") ; /* clear screen */
    CyDelay(100) ;
}

void splash(char *title)
{
    cls() ;
    if (title && *title) {
        print(title) ;
        print(" ") ;
    }
    snprintf(str, STR_LEN, "(%s %s)\n\r", __DATE__, __TIME__) ;
    print(str) ;
}


CY_ISR(tick_callback)
{
    tick_count++ ;
    if (tick_count >= 1000) {
        sec_passed_flag = 1 ;
        tick_count = 0 ;
    }
}

int find_empty_slot(void)
{
    int result = -1 ;
    uint32_t i ;
    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {
        if (CySysTickGetCallback(i) == NULL) {
            result = i ;
            break ;
        }
    }
    return(result) ;
}

int main(void)
{   
    int sec = 0 ;
    int sys_tick_slot = 0 ;
    
    CyGlobalIntEnable; /* Enable global interrupts. */
    UART_Start() ;

    sys_tick_slot = find_empty_slot() ;
    if (sys_tick_slot < 0) {
        print("Sorry No empty SysTick Slot available\n\r") ;
        while(1) { } /* halting here */
    } else {
        CySysTickStart() ;
        CySysTickSetCallback(sys_tick_slot, tick_callback) ;
    }
    
    splash("SysTick Timer Test") ;
       
    for(;;)
    {
        if (sec_passed_flag) {
            sec_passed_flag = 0 ;
            sec++ ;
            snprintf(str, STR_LEN, "%d secconds passed\n\r", sec) ;
            print(str) ;
        }
    }
}

When started it will write to com port (Serial Terminal, such as Tera Term)

001-TeraTerm-log.JPG

moto

 

 

View solution in original post

3 Replies
BiBi_1928986
Level 7
Level 7
First comment on blog 500 replies posted 250 replies posted

Hello.

Timer_1_ClearInterrupt() is missing the parameter that tells the PSoC processor which Timer interrupting source signal is to be cleared.  This parameter is defined as a "mask".  You'll find the various mask definitions in the Timer datasheet.

Here's an example of using the Timer Interrupt in Section 4 of AN90799:
AN90799 - PSoC 4 Interrupts (infineon.com)

And examples with code and schematic in CE224593:
PSoC 4 PWM (infineon.com) for pdf.
Infineon Technologies for the zip file of source code.

Good luck with your project.

odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

You can't put any delay code inside the interrupt code!

CyDelay(DELAY_1S); - hangs the processor 

 

try something like

CY_ISR(timer1)  {

    if (UI_LOBAT_Read()==LED_ON) // if LED still on?

            UI_LOBAT_Write(LED_OFF); // turn off 

 

     Timer1_1s++;

     if (Timer1_1s > 30000) {

          Timer1_1s =0; // reset

          UI_LOBAT_Write(LED_ON); // enable LED

     }

}

 

lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

So Timer_1_ClearInterrupt() need an argument.
If you read "Timer_1.c" there is a description

006-Timer_1_func.JPG

This suggest that your (or our) choice are

* - Timer_1_INTR_MASK_TC - Terminal count mask
* - Timer_1_INTR_MASK_CC_MATCH - Compare count / capture mask

As I imagined that you are using TC (terminal count), I wrote something like below

Note: I could compile, but as I don't have the board, I could not test it.

#include "project.h"

volatile int Timer1_1s = 0 ;
volatile int Timer1_3sec_flag = 0 ;

CY_ISR(timer1)
{
    Timer1_1s++ ;
    if (Timer1_1s >= 3000) {
        Timer1_3sec_flag = 1 ;
        Timer1_1s = 0 ;
    }
    Timer_1_ClearInterrupt(Timer_1_INTR_MASK_TC) ;
}

int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    timer_tc_int_ClearPending() ;
    timer_tc_int_StartEx(timer1) ;

    UART_Start() ;
    Timer_1_Start() ;

    for(;;)
    {
        if (Timer1_3sec_flag) {
            Timer1_3sec_flag  = 0 ;
            UART_UartPutString("3 sec passed\n\r") ;       
        }
    }
}

As others have already suggested, we should avoid using blocking funtion or function which take very long time inside an interrupt service routine, so I just set Timer1_3sec_flag and let the main loop take care of the rest.

By the way, if all you need is an interrupt of seconds resolutin (or ms resolution), 
we can use SysTick without consuming hardware timer.

So, I wrote a sample program using CY8CKIT-149, which has CY8C4147AZI-S475 the closest board I have with your CY8C4125LQI-S423.

Schematic

002-Schematic.JPG

Pins

003-Pins.JPG

main.c

#include "project.h"
#include "stdio.h"

volatile uint32_t tick_count = 0 ;
volatile int sec_passed_flag = 0 ;

#define STR_LEN 64
char str[STR_LEN+1] ;
void print(char *str)
{
    UART_UartPutString(str) ;
}

void cls(void)
{
    print("\033c") ; /* reset */
    CyDelay(100) ;
    print("\033[2J") ; /* clear screen */
    CyDelay(100) ;
}

void splash(char *title)
{
    cls() ;
    if (title && *title) {
        print(title) ;
        print(" ") ;
    }
    snprintf(str, STR_LEN, "(%s %s)\n\r", __DATE__, __TIME__) ;
    print(str) ;
}


CY_ISR(tick_callback)
{
    tick_count++ ;
    if (tick_count >= 1000) {
        sec_passed_flag = 1 ;
        tick_count = 0 ;
    }
}

int find_empty_slot(void)
{
    int result = -1 ;
    uint32_t i ;
    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {
        if (CySysTickGetCallback(i) == NULL) {
            result = i ;
            break ;
        }
    }
    return(result) ;
}

int main(void)
{   
    int sec = 0 ;
    int sys_tick_slot = 0 ;
    
    CyGlobalIntEnable; /* Enable global interrupts. */
    UART_Start() ;

    sys_tick_slot = find_empty_slot() ;
    if (sys_tick_slot < 0) {
        print("Sorry No empty SysTick Slot available\n\r") ;
        while(1) { } /* halting here */
    } else {
        CySysTickStart() ;
        CySysTickSetCallback(sys_tick_slot, tick_callback) ;
    }
    
    splash("SysTick Timer Test") ;
       
    for(;;)
    {
        if (sec_passed_flag) {
            sec_passed_flag = 0 ;
            sec++ ;
            snprintf(str, STR_LEN, "%d secconds passed\n\r", sec) ;
            print(str) ;
        }
    }
}

When started it will write to com port (Serial Terminal, such as Tera Term)

001-TeraTerm-log.JPG

moto