cancel
Showing results for 
Search instead for 
Did you mean: 

GPIO in interrupt handler

jordan
Associate
Posted on August 30, 2011 at 02:22

I'm trying to create an interrupt handler that will toggle an LED on and off very quickly  (as a basic test, my end goal is to eventually do much more than that). Right now I have an interrupt handler which is configured to be triggered by TIM1, and while it does seem that the interrupt handler is being called, the LED is just staying off. What am I doing wrong? Below are stm8s_it.h, sm8s_it.c, main.c, and stm8s_interrupt_vector.c .

/********** stm8s_it.h **********/

#ifndef __STM8S_IT_H

#define __STM8S_IT_H

@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void);

#endif

/********** end stm8s_it.h **********/

/********** sm8s_it.c **********/

#include ''stm8s.h''

#include ''stm8s_it.h''

void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void) {

    /* If I set a break point on the next line, the program does break here

       so the interrupt handler is being called but for some reason this next

         line is not toggling the LED on and off. */

    GPIO_WriteReverse(GPIOD, GPIO_PIN_2);

    

    // Clear the interrupt pending bit for TIM1.

    TIM1_ClearITPendingBit(TIM1_IT_UPDATE);

}

/********** end sm8s_it.c **********/

/********** main.c **********/

#include ''stm8s.h''

void main(void)

{

    TIM1_DeInit();

    // Set TIM1 to:

    // - use an exact prescaler of 1000,

    // - to count up,

    // - to have a period of 1, and

    // - to have a repetition counter of 0.

    TIM1_TimeBaseInit(1000, TIM1_COUNTERMODE_UP, 1, 0);

    // Set TIM1 to generate interrupts every time the counter overflows (every ms).

    TIM1_ITConfig(TIM1_IT_UPDATE, ENABLE);

    // Enable TIM1.

    TIM1_Cmd(ENABLE);

    

    enableInterrupts();

        

    GPIO_Init(GPIOC, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST);

        

    for (;;)

        {

            // When the following code is uncommented the LED does blink slowly, so the LED itself works.

            /*

            long d;

            for (d = 0; d < 50000; ++d) {

                nop();

            }

            GPIO_WriteReverse(GPIOC, GPIO_PIN_2);

            */

        }

}

/********** end main.c **********/

/********** stm8s_interrupt_vector.c **********/

/*    BASIC INTERRUPT VECTOR TABLE FOR STM8 devices

 *    Copyright (c) 2007 STMicroelectronics

 */

 

#include ''stm8s_it.h''

typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {

    unsigned char interrupt_instruction;

    interrupt_handler_t interrupt_handler;

};

@far @interrupt void NonHandledInterrupt (void)

{

    /* in order to detect unexpected events during development,

       it is recommended to set a breakpoint on the following instruction

    */

    return;

}

extern void _stext();     /* startup routine */

struct interrupt_vector const _vectab[] = {

    {0x82, (interrupt_handler_t)_stext}, /* reset */

    {0x82, NonHandledInterrupt}, /* trap  */

    {0x82, NonHandledInterrupt}, /* irq0  */

    {0x82, NonHandledInterrupt}, /* irq1  */

    {0x82, NonHandledInterrupt}, /* irq2  */

    {0x82, NonHandledInterrupt}, /* irq3  */

    {0x82, NonHandledInterrupt}, /* irq4  */

    {0x82, NonHandledInterrupt}, /* irq5  */

    {0x82, NonHandledInterrupt}, /* irq6  */

    {0x82, NonHandledInterrupt}, /* irq7  */

    {0x82, NonHandledInterrupt}, /* irq8  */

    {0x82, NonHandledInterrupt}, /* irq9  */

    {0x82, NonHandledInterrupt}, /* irq10 */

  {0x82, (interrupt_handler_t)TIM1_UPD_OVF_TRG_BRK_IRQHandler}, /* irq11 */

    {0x82, NonHandledInterrupt}, /* irq12 */

    {0x82, NonHandledInterrupt}, /* irq13 */

    {0x82, NonHandledInterrupt}, /* irq14 */

    {0x82, NonHandledInterrupt}, /* irq15 */

    {0x82, NonHandledInterrupt}, /* irq16 */

    {0x82, NonHandledInterrupt}, /* irq17 */

    {0x82, NonHandledInterrupt}, /* irq18 */

    {0x82, NonHandledInterrupt}, /* irq19 */

    {0x82, NonHandledInterrupt}, /* irq20 */

    {0x82, NonHandledInterrupt}, /* irq21 */

    {0x82, NonHandledInterrupt}, /* irq22 */

    {0x82, NonHandledInterrupt}, /* irq23 */

    {0x82, NonHandledInterrupt}, /* irq24 */

    {0x82, NonHandledInterrupt}, /* irq25 */

    {0x82, NonHandledInterrupt}, /* irq26 */

    {0x82, NonHandledInterrupt}, /* irq27 */

    {0x82, NonHandledInterrupt}, /* irq28 */

    {0x82, NonHandledInterrupt}, /* irq29 */

};

/********** end stm8s_interrupt_vector.c **********/

loosely based on http://benryves.com/tutorials/stm8s-discovery/ though I am not using a discovery board.
4 REPLIES 4
brazov22
Associate II
Posted on August 30, 2011 at 08:07

do you want to write on PD2 or PC2? In the first case you have to change GPIO configuration and if possible I'd put it at the beginning of the main.

brazov2

jdf25252
Associate II
Posted on August 30, 2011 at 16:59

I don't use the standard I/O library so I can't comment on most of your code though I think the declaration of the interrupt handler needs to include the ''@interrupt'' modifier:

void @interrupt TIM1_UPD_OVF_TRG_BRK_IRQHandler(void) {

The compiler doesn't seem to remember the @interrupt from the function prototype.

jdf

jordan
Associate
Posted on August 30, 2011 at 19:27

I want to write to PC2, and that was my entire problem. Thank you.

brazov22
Associate II
Posted on August 31, 2011 at 13:23

You're welcome!