Using External Interrupt is one of the key feature of any microcontroller. Just like any other microcontroller, STM8s series also provide the external interrupt functionality out of the box. If you are coming with any other 8-bit microcontroller family like the 8051 series you may notice that those microcontrollers provides limited numbers of pins for the external interrupt functionality. Mostly one or two pins, even the famous Arduino Uno board which comes with ATMega328p microcontroller also have only 2 external interrupt pins. But the ST microcontrollers always take cares of users and provide more rich peripherals usage. The STM8s is capable of having the interrupt on any GPIO pin.

In this STM8s external interrupt example we are going to demonstrate the external interrupt functionality but the resultant output code will be very simple. It will toggle the LED whenever the push button is pressed on the external interrupt pin. We are going to use the Cosmic C compiler for writing the code for the STM8s microcontroller. Just like in our previous STM8S LCD interfacing example, as well as the STM8 UART example post. You may view all the examples of STM8 Cosmic C compiler .

stm8s103f3 pinout
STM8S103F3 pinout

The microcontroller number which we are going to use is, as usual the STM8S103F3 microcontroller. You may also use STM8S003F3 which is almost similar with same pinouts. The reason of using this microcontroller is because of its STM8S Blue pill board.

STM8S Interrupt vector Table

Before we would be able to use any interrupts we need to find out the interrupt vector table. To find the interrupt vector table, we have to goto the STM8S103f3p6 micrcontroller’s Datasheet. In this datasheet, if you navigate to the section 7 of interrupt vector mapping, here you need to find out the IRQ number of your required interrupt. We are going to use the PortA for our external mapping. Here we can see it is EXT0 and the IRQ number for this interrupt source is IRQ3. With this information we will go to the STVD IDE for writing the code.

STM8S103F3 interrupt vector table mapping

Now if you open the project in STVD IDE, you may see two files. The main.c is the file which we are using in all our previous tutorials. But you may notice that there is one more file named stm8_interrupt_vector.c This is the file which is responsible for this interrupt vector mapping. Double click on this file and open it in the editor. By default it will hold following code

/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices
 * Copyright (c) 2007 STMicroelectronics
 */

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 */

extern @far @interrupt void EXTI3_IRQHandler (void);

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, (interrupt_handler_t)EXTI3_IRQHandler}, /* irq6 (FOR PRTD EXTERNAL INTERRUPT) */
 {0x82, NonHandledInterrupt}, /* irq7  */
 {0x82, NonHandledInterrupt}, /* irq8  */
 {0x82, NonHandledInterrupt}, /* irq9  */
 {0x82, NonHandledInterrupt}, /* irq10 */
 {0x82, NonHandledInterrupt}, /* 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 */
};
Code language: JavaScript (javascript)

All you have to do is to replace the NonHandledInterrupt with your own Interrupt Service Routine pointer in the proper IRQ number. In our case this would be IRQ3.

Final Code

Here is complete working code which blinks onboard LED @PB5 continuously and toggle LED on PD2 whenever it detect RISING EDGE on PD3 . Here we enabled the interrupts from EXTI_CR1 Register.

EXTI_CR1 Register for stm8s external interrupt
#include "iostm8s.h"

_Bool LED_BUILTIN @PB_ODR: 5; //TO WRITE OUTPUT
_Bool LED @PD_ODR: 2; //TO WRITE OUTPUT
//---------------------------------
_Bool SW1 @PD_IDR: 3; //TO READ INPUT
//----------------------------------
void delay_ms(unsigned int nCount) {
  /* Decrement nCount value */
  unsigned int i = 0;
  while (nCount != 0) {
    for (i = 0; i < 0x3FF; i++);
    nCount--;
  }
}

main() {
  CLK_CKDIVR = 0x00; //CPUDIV=1,HSDIV=1,Int_clock= 16MHz
  #asm
  sim
  #endasm

  PB_DDR |= (1 << 5);
  PD_DDR |= (1 << 2);
  PD_CR1 |= (1 << 2);
  PD_DDR &= ~(1 << 3);
  PD_CR1 &= ~(1 << 3);
  PD_CR2 |= (1 << 3); //ENABLE EXTERNAL INTERRUPT
  EXTI_CR1 &= ~(1 << 7); //PORTD FALLING & LOW Level
  EXTI_CR1 |= (1 << 6); //PORTD FALLING & LOW Level

  #asm
  rim
  #endasm
  while (1) {
    unsigned int i = 0;

    LED_BUILTIN = ~LED_BUILTIN;
    delay_ms(500);
  }
}

@far @interrupt void EXTI3_IRQHandler(void) {
  if (SW1 == 1) {
    LED = ~LED;

  }
}Code language: PHP (php)

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

One thought on “STM8s External interrupt example”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.