STM8 common interrupt instructions
Open the total interrupt
_asm("rim");
Disable interrupts
_asm("sim");
Entering shutdown mode
_asm("halt");
Interrupt return
_asm("iret");
Waiting for interrupt
_asm("wfi");
Software interrupts
_asm("trap");
STM8S common interrupt mapping
When using an interrupt function, you can find the corresponding interrupt vector number in the figure above, and the name of the interrupt function can be customized.
/* 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 EXTI2_Hand_Fun(void);
extern @far @interrupt void TIM1_UPD_OVF_TRG_BRK_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, EXTI2_Hand_Fun}, /* irq5 */
{0x82, NonHandledInterrupt}, /* irq6 */
{0x82, NonHandledInterrupt}, /* irq7 */
{0x82, NonHandledInterrupt}, /* irq8 */
{0x82, NonHandledInterrupt}, /* irq9 */
{0x82, NonHandledInterrupt}, /* irq10 */
{0x82, 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 */
};
External interrupt long key recognition related configuration
STM8S has five interrupt vectors specifically allocated for external interrupt events:
PortA's 5 pins: PA[6:2]
PortB port 8 pins: PB[7:0]
Port C port 8 pins: PC[7:0]
7 pins of PortD: PD[6:0]
8 pins of PortE port: PE[7:0]
PD7 is the highest priority interrupt source (TLI);
Interrupt IO settings
Here we select EXTI2 (Port C external interrupt). Then we need to set the interrupt-triggered IO (PC5) to pull-up input or interrupt pull-up input. If the input is suspended, it is easy to be disturbed.
/*PC5 is set as pull-up input*/
void Init_EXTI2_GPIO(void)
{
PC_DDR &= 0XDF;
PC_CR1 &= 0XDF;
PC_CR2 |= 0x20;
}
External interrupt register configuration
CPU CC register interrupt bit:
I1 and I0 cannot be written directly, but can only be written by turning on or off interrupts. The default value is 11 when powered on. When the interrupt is turned on by instruction (_asm("rim\n");), it is 00. When an interrupt occurs, the current interrupt (ITC_SPRx) is loaded into I[1:0], which is mainly used for interrupt priority. Exiting the interrupt automatically clears it to 0. Therefore, when writing EXTI_CR1, ITC_SPRx needs to be configured to 11, or an interrupt disable instruction needs to be added.
EXTI_CR1:
Configure triggering methods;
Test code
#include
char keyFlag;
char keyPressStatus = 1;
unsigned int keyCount;
/*Output Pin*/
_Bool PD2 @PD_ODR:2;
_Bool PC7 @PC_ODR:7;
_Bool PC6 @PC_ODR:6;
_Bool PC3 @PC_ODR:3;
/*Input Pin*/
_Bool PC5 @PC_IDR:5;
/*battery indicator*/
#define LED1 PD2
#define LED2 PC7
#define LED3 PC6
#define LED4 PC3
/*button*/
#define KEY PC5
/*The main clock frequency is 8Mhz*/
void Init_CLK(void)
{
CLK_ICKR |= 0X01; //Enable internal high-speed clock HSI
CLK_CKDIVR = 0x08; //16M internal RC is divided by 2 and the system clock is 8M
while(!(CLK_ICKR&0x02)); //HSI is ready
CLK_SWR=0xE1; //HSI is the main clock source
}
void Init_LED(void)
{
/*LED configured as push-pull output*/
PD_DDR |= 0X04; //PD2 output mode, 0 is input mode
PD_CR1 |= 0X04; //PD2 analog open drain output
PD_CR2 &= 0XFB; //PD2 output speed is up to 2MHZ, CR1/CR2 floating input
PC_DDR |= 0XC8;
PC_CR1 |= 0XC8;
PC_CR2 &= 0X27;
}
/*PC5 is set as pull-up input*/
void Init_EXTI2_GPIO(void)
{
PC_DDR &= 0XDF;
PC_CR1 &= 0XDF;
PC_CR2 |= 0X20;
}
void Init_EXTI2(void)
{
EXTI_CR1 |= 0x30; // rising edge and falling edge trigger
}
void Init_TIM1(void)
{
TIM1_IER = 0x00;
TIM1_CR1 = 0x00;
TIM1_EGR |= 0x01;
TIM1_PSCRH = 199/256; // 8M system clock is pre-divided by f=fck/(PSCR+1) TIM1 is a 16-bit divider
TIM1_PSCRL = 199%256; // PSCR=0x1F3F, f=8M/(200)=40000Hz, each counting cycle is 1/40000ms
TIM1_CNTRH = 0x00;
TIM1_CNTRL = 0x00;
TIM1_ARRH = 400/256; // Automatic reload register ARR=400
TIM1_ARRL = 400%256; // Generate an interrupt every 400 counts, i.e. 10ms
TIM1_CR1 |= 0x81;
TIM1_IER |= 0x01;
}
unsigned int Key_Scan_Test(void)
{
unsigned int count = 0;
unsigned char keyMode;
if(0 == keyPressStatus)
{
keyFlag = 1;
while(!keyPressStatus);
keyFlag = 0;
count = keyCount;
keyCount = 0;
}
else
{
count = 0;
}
/*10ms * 150 = 1.5s*/
if(count >= 150)keyMode = 2; //Long press
else if(count >= 4)keyMode = 1; //short press
else keyMode = 0; //shake
return keyMode;
}
main()
{
char keynum = 0;
_asm("sim");
Init_CLK();
Init_LED();
Init_EXTI2_GPIO();
Init_EXTI2();
Init_TIM1();
_asm("rim");
while (1)
{
keynum = Key_Scan_Test();
if(1 == keynum)LED3 = ~LED3;
if(2 == keynum)LED4 = ~LED4;
}
}
@far @interrupt void EXTI2_Hand_Fun(void)
{
keyPressStatus = !keyPressStatus;
LED1 = ~LED1;
}
@far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
{
static unsigned int i = 0;
TIM1_SR1 &= ~(0X01);
++i;
if(50 == i)
{
LED2 = ~LED2;
i = 0;
}
/*Within Key Press Hand*/
if(1 == keyFlag)
{
++keyCount;
}
}
Notice:
The interrupt vector needs to be declared. Add the following to stm8_interrupt_vector.c:
extern @far @interrupt void EXTI2_Hand_Fun(void);
extern @far @interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void);
{0x82, EXTI2_Hand_Fun}, /* irq5 */
{0x82, TIM1_UPD_OVF_TRG_BRK_IRQHandler}, /* irq11 */
See also Long key recognition without external interrupt: Recognize long key without external interrupt
Previous article:STM8S's pitfalls in setting the highest TIM frequency
Next article:STM8S timer basic interrupt timing
Recommended ReadingLatest update time:2024-11-16 13:00
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Flathead RVB2601 creative application development] @fxyc87 RVB2601-Qiqiao technology
- Looking for a DC/DC step-down chip
- Ask for advice from the experts! Design of soft start circuit based on single chip microcomputer
- U disk IAP jump APP abnormal
- Control power-on circuit problem
- [RISC-V MCU CH32V103 Review] - 0: Three unexpected things when meeting for the first time
- ONENET platform DTLS encryption mentioned the boot machine and access machine. What are the boot machine and access machine? What is the difference between them?
- 【phyBOARD-i.MX 8M Plus Development Board】Part 2: Powering on the Development Board and Evaluating the Development Environment
- 22 Ways to Prevent EMI When Designing Power Supplies
- 【NXP Rapid IoT Review】Hello Touch