STM8经常使用中断指令

  • 开总中断

    • _asm(“rim”);
  • 禁止中断
    • _asm(“sim”);
  • 进入停机模式
    • _asm(“halt”);
  • 中断返回
    • _asm(“iret”);
  • 等待中断
    • _asm(“wfi”);
  • 软件中断
    • _asm(“trap”);

STM8S经常使用中断映射

如使用中断函数时。能够通过在上图中查找相相应的中断向量号,而中断函数的名字能够自己定义

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

外部中断长按键识别相关配置

  STM8S为外部中断事件专门分配了五个中断向量:

  • PortA 口的5个引脚:PA[6:2]
  • PortB 口的8个引脚:PB[7:0]
  • PortC 口的8个引脚:PC[7:0]
  • PortD 口的7个引脚:PD[6:0]
  • PortE口的8个引脚:PE[7:0]

  PD7是最高优先级的中断源(TLI);

中断IO设置

  这里选用EXTI2(portC外部中断)。

那么须要将中断促发的IO(PC5)设置为上拉输入或中断上拉输入。悬浮输入的话非常easy受干扰。

/*PC5设置为上拉输入*/
void Init_EXTI2_GPIO(void)
{
PC_DDR &= 0XDF;
PC_CR1 &= 0XDF;
PC_CR2 |= 0x20;
}

外部中断寄存器配置

CPU CC寄存器中断位:

  I1 I0不能直接写,仅仅能通过开中断或关中断来写,上电默认是11。当用指令开中断时( _asm(“rim\n”);),为00;当发生中断时,由当前中断(ITC_SPRx)加载I[1:0],主要用于做中断优先级;退出中断自己主动清0;因此在写EXTI_CR1。需将ITC_SPRx配置成11。或增加禁中断指令 。

EXTI_CR1:

  配置促发方式;

測试代码

#include<stm8s003f3p.h>

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; /*电量指示灯*/
#define LED1 PD2
#define LED2 PC7
#define LED3 PC6
#define LED4 PC3
/*按键*/
#define KEY PC5 /*主时钟频率为8Mhz*/
void Init_CLK(void)
{
CLK_ICKR |= 0X01; //使能内部快速时钟 HSI
CLK_CKDIVR = 0x08; //16M内部RC经2分频后系统时钟为8M
while(!(CLK_ICKR&0x02)); //HSI准备就绪
CLK_SWR=0xE1; //HSI为主时钟源
} void Init_LED(void)
{
/*LED 配置为推挽输出*/
PD_DDR |= 0X04; //PD2输出模式,0为输入模式
PD_CR1 |= 0X04; //PD2模拟开漏输出
PD_CR2 &= 0XFB; //PD2输出速度最大为2MHZ,CR1/CR2悬浮输入 PC_DDR |= 0XC8;
PC_CR1 |= 0XC8;
PC_CR2 &= 0X27;
} /*PC5设置为上拉输入*/
void Init_EXTI2_GPIO(void)
{ PC_DDR &= 0XDF;
PC_CR1 &= 0XDF;
PC_CR2 |= 0X20;
} void Init_EXTI2(void)
{
EXTI_CR1 |= 0x30; //上升沿和下降沿促发
} void Init_TIM1(void)
{
TIM1_IER = 0x00;
TIM1_CR1 = 0x00; TIM1_EGR |= 0x01;
TIM1_PSCRH = 199/256; // 8M系统时钟经预分频f=fck/(PSCR+1) TIM1 为16位分频器
TIM1_PSCRL = 199%256; // PSCR=0x1F3F,f=8M/(200)=40000Hz,每一个计数周期1/40000ms TIM1_CNTRH = 0x00;
TIM1_CNTRL = 0x00; TIM1_ARRH = 400/256; // 自己主动重载寄存器ARR=400
TIM1_ARRL = 400%256; // 每记数400次产生一次中断。即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; //长按
else if(count >= 4)keyMode = 1; //短按
else keyMode = 0; //抖动 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;
}
}
注意:
中断向量需声明。在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 */

  另參见不用外部中断长按键识别:不用外部中断识别长按键

STM8S---外部中断应用之长按键识别的更多相关文章

  1. STM32学习笔记(九) 外部中断,待机模式和事件唤醒

    学会知识只需要不段的积累和提高,但是如何将知识系统的讲解出来就需要深入的认知和系统的了解.外部中断和事件学习难度并不高,不过涉及到STM32的电源控制部分,还是值得认真了解的,在本文中我将以实际代码为 ...

  2. STM32之外部中断

    图1.0 图1.1 中断控制器支持23条中断线,其中16条是IO管脚中断线,分别是EXTI0~EXTI15:  图 1.2 另外七根中断线如下图: 中断线和管脚的对应关系:EXTI0~EXTI15 和 ...

  3. STM32基本GPIO操作:按键输入(扫描+外部中断)

    (涉及专有名词较多,难免解释不到位,若有错误还请指出,谢谢!) 硬件连接图如下: 一.扫描 思路是在main函数中通过死循环来扫描端口电平状态检测,以此判断按键是否按下.实现较为简单. 1.初始化(注 ...

  4. STM32之EXTI——外部中断

    互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...

  5. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...

  6. 十天学会单片机Day1点亮数码管(数码管、外部中断、定时器中断)

    1.引脚定义 P3口各引脚第二功能定义 标号 引脚 第二功能 说明 P3.0 10 RXD 串行输入口 P3.1 11 TXD 串行输出口 P3.2 12 INT0(上划线) 外部中断0 P3.3 1 ...

  7. STM8的中断系统以及外部中断详解

    STM8具有最多32的中断系统,在中断的处理上类似于cortexm系列的芯片,首先是每个中断的向量都是固化在系统内部的,用户需要向相应的中断向量flash位置写入中断处理函数,其二,每个中断向量都具有 ...

  8. STM32学习笔记(三)——外部中断的使用

    开发板芯片:STM32F407ZGT6 硬件连接:PE3-KEY1 一.STM32F4的中断介绍 STM32F4的每个IO都可以作为外部中断输入,很强大的功能吧!以前学习的51只有两个外部中断. ST ...

  9. 【audio】耳机插拔 线控按键识别流程【转】

    耳机插拔/线控按键识别流程 耳机插拔/线控按键识别流程 1.文档概述 本文以msm8909平台,android N为例,介绍了通用情况下,耳机插拔的流程步骤,以及对耳机类型的识别逻辑.以方便在项目工作 ...

随机推荐

  1. 迅为电子4.3寸CAN总线工业平板电脑简介

    型号:iTOP-HMI043-C 4.3寸CAN总线工业平板电脑支持CAN通讯显示器,显示:显示尺寸:4.3英寸:分辨率:480×272 TFT液晶 65536色 :接口:支持CAN 2.0B:USB ...

  2. c++ 模板template

    1.函数模板的声明 声明形式 template<typename 数据类型参数标识符> <返回类型><函数名>(参数表) {     函数体 } 注: templa ...

  3. TYPE=MyISAM 与 ENGINE=MyISAM 的区别(摘要版)

    TYPE=MyISAM 和 ENGINE=MyISAM 都是设置数据库存储引擎的语句 (老版本的MySQL使用TYPE而不是ENGINE(例如,TYPE = MYISAM). MySQL 5.1为向下 ...

  4. Windows命名规则

    函数名: ·参照 Windows API 的命名规范. ·推荐使用动宾结构.函数名应清晰反映函数的功能.用途. ·函数名最长不得超过30个字符. ·函数名第一个字母必须大写. ·全局函数必须以小写前缀 ...

  5. js 异步提交文件

    <form method="POST" action="${ctx}/statement/manage/upload" name="form&q ...

  6. java.util.MissingResourceException: Can't find bundle for base name db, locale zh_CN

    在使用Bundle来加载配置文件的时候, 爆出了这个错误: 原因? 没有找到需要加载的配置文件,因为配置文件必须放在src目录下面, 如果放进了com.bj186.crm的包下面,就必须添加包的名称到 ...

  7. Android-ViewPagerIndicator框架使用——CirclePageIndicator

    前言:Circle适用于应用新功能的展示页和商品的多张图片的展示功能. 1.定义布局文件:SampleCirclesDefault中添加了一个布局:simple_circles. 布局中定义一个Lin ...

  8. Linux从入门到适应(四):Ubuntu 16.04环境下,安装Nvidia驱动,cuda9.2和 cudnn

    在安装深度学习框架之前,cuda和cudnn是必须要提前安装的,现在按照流程而nvidia驱动的版本和cuda版本有这一些对应关系,所以需要按照版本进行安装,现在说一下如何安装: 1 安装nvidia ...

  9. 珂朵莉树(Chtholly Tree)学习笔记

    珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......) ...

  10. kafka 服务端消费者和生产者的配置

    在kafka的安装目录下,config目录下有个名字叫做producer.properties的配置文件 #指定kafka节点列表,用于获取metadata,不必全部指定 #需要kafka的服务器地址 ...