[原创] R7F0C802x Easy Start --超级简单好用的中断

youki12345   2014-8-9 23:47 楼主
中断大家一定不陌生,在51,STM32等CPU中都有很多,而且大家都用过。不过瑞萨单片机的中断和别家的还是有些不同的,而这些不同在我看来用起来还是很方便的。 在R7F0C8021的datasheet中对中断的描述分为两个章节。中断和按键中断。那么这两个有什么不同呢?个人理解。对于瑞萨单片机来说中断指的是那种通常我们使用的中断,例如:看门狗中断、定时器中断、AD中断等等。这些中断有个共同特点:当事件发生时,中断就被触发,程序跳转到中断处理函数中执行。在R7F0C8021中共有两种中断:内部中断和外部中断。下表就是对这个CPU中所有中断向量的一个总结。注意这个表中的第10项:INTKR 检测按键返回信号。这个中断表示的就是使用的是按键中断。具体我们后面再说。 1.jpg 和其它MCU一样,对于中断的控制无非就是几个寄存器标志位的操作而已:允不允许中断?优先级如何确定?哪个中断发生了?在R7F0C8021中(MK0L, MK0H)寄存器被称为中断屏蔽标志寄存器,它们用来设置哪些中断被屏蔽哪些被允许。(PR00L, PR00H, PR10L, PR10H)这四个被称为优先级选择寄存器,他们用来确定各中断源的响应顺序。(IF0L, IF0H)这两个寄存器是状态寄存器,用来表明当前哪个中断被触发了。除此之外,程序状态字(PSW)寄存器中还可以设置当前响应哪个优先级别的中断。 而对于中断嵌套,其要发生需要两个条件: 1.即将发生的中断优先级比现在正在执行的要高 2.当前已经打开了IE,即允许了中断。(瑞萨的单片机每次进入中断都会自动禁止IE,所以如果要嵌套的话,比如进入中断后手动打开才行。) 下面我们看看按键中断。个人理解,由于R7F0C8021的目标领域是小家电,所以对按键的需求一般会多一点。所以瑞萨就单独把按键中断提出来。实际上,按键中断是整体中断的一部分。也就是上表中的第10项:INTKR 检测按键返回信号。瑞萨把按键中断命名为KRx系列,也就是说只要引脚为KRx就表明其可以响应按键中断。相对于其它中断来说,按键中断有更多的设置,如:上升或下降沿检测、如何区分哪些按键被按下等等。(KRCTL)被称为按键返回控制寄存器,其中只有两个位,用来设置是否记录哪个按键按下和按键是上升Or下降沿触发。而(KRF)寄存器就是其中的位来指明当前哪个按键被按下的。 一句话可以对按键中断进行总结:当按键按下的时候会发生INTKR中断,同时会设置好KRF寄存器。所以要确定当前哪个按键按下的话,只需要在INTKR中断处理函数中读取KRF寄存器,看看和按键对应的位是否被置为1了。 下面通过实例来看看如何用R7F0C8021的中断和按键中断。 void KR0_Init(void) //按键中断寄存器初始化,板子上有KR0-KR5,所以对于每个按键要分别设置。 { volatile uint8_t w_count; /* Set KR0 pin */ PM4 |= 0x01U; //设置KR0为输入模式,为什么这个引脚是KR0?看芯片引脚定义。 /* Set KR2 pin */ PMC0 &= 0xFDU; //在IO端口模式控制寄存器中设置为数字端口 PM0 |= 0x02U;//设置KR2为输入模式,为什么这个引脚是KR0?看芯片引脚定义。 /* Set KR3 pin */ PMC0 &= 0xFBU;//在IO端口模式控制寄存器中设置为数字端口 PM0 |= 0x04U;//设置KR3为输入模式,为什么这个引脚是KR0?看芯片引脚定义。 /* Set KR4 pin */ PMC0 &= 0xF7U;//在IO端口模式控制寄存器中设置为数字端口 PM0 |= 0x08U;//设置KR4为输入模式,为什么这个引脚是KR0?看芯片引脚定义。 /* Set KR5 pin */ PMC0 &= 0xEFU;//在IO端口模式控制寄存器中设置为数字端口 PM0 |= 0x10U;//设置KR5为输入模式,为什么这个引脚是KR0?看芯片引脚定义。 KRMK = 1U; /* disable INTKR operation *///关中断,因为后面要更改中断设置 KRIF = 0U; /* clear INTKR interrupt flag */ KRCTL = _00_KR_EDGE_FALLING; //下降沿触发 /* Set INTKR level 1 priority */ KRPR1 = 0U; KRPR0 = 1U; //设置优先级为1级别 KRCTL |= _80_KR_FLAG_USED;//需要返回状态 KRM0 = _01_KR0_SIGNAL_DETECT_ON | _02_KR1_SIGNAL_DETECT_ON | _04_KR2_SIGNAL_DETECT_ON | _08_KR3_SIGNAL_DETECT_ON | _10_KR4_SIGNAL_DETECT_ON | _20_KR5_SIGNAL_DETECT_ON;//开启各个中断 /* Change the waiting time according to the system */ for (w_count = 0U; w_count <= KEY_WAITTIME; w_count++) { NOP(); } /* Key Interrupt Start */ KRF = 0U; KRIF = 0U; /* clear INTKR interrupt flag */ KRMK = 0U; /* enable INTKR operation */ //打开中断 } 当中断发生时,程序跳入中按键中断处理函数中执行: __interrupt void interrupt_intkr(){ key_cnt++; key_code = KRF; /* save key code for main loop */ KRF = 0; /* clear flag for next key in */ } 该程序用key_code = KRF; 来记录KRF寄存器的内容,而在随后的主程序中,根据key_code不同位 的值来做不同的事情。 #define KEY_RIGHT 0x20 #define KEY_LEFT 0x10 #define KEY_UP 0x04 #define KEY_DOWN 0x08 #define KEY_STAR 0x01 #define KEY_HASH 0x02 #define LED_GREEN 0 #define LED_RED 1 while(1) { if (key_code != 0) { /* Key Process */ if (key_code == KEY_LEFT)//判断key_code的第4位是否为1 { P0.0 = LED_RED; } else if (key_code == KEY_RIGHT)//判断key_code的第5位是否为1 { P0.0 = LED_GREEN; } key_code = 0;//清除key_code } } 完整程序代码如下:
keyinput.rar (58.04 KB)
(下载次数: 93, 2014-8-9 23:47 上传)
本帖最后由 youki12345 于 2014-8-9 23:49 编辑
https://bbs.eeworld.com.cn/thread-471646-1-1.html 欢迎加入我的团队

回复评论 (7)

感觉人气不足啊。。。。
https://bbs.eeworld.com.cn/thread-471646-1-1.html 欢迎加入我的团队
点赞  2014-8-12 09:59
楼主理解的很透
点赞  2014-8-26 22:21
什么时候才能达到这种境界啊
点赞  2014-8-30 23:04
点赞  2015-8-6 10:30
这个型号的中断优先级寄存器也能用在RL78/G13吗
点赞  2015-8-8 14:08
感谢楼主,学习了,解释的很详细。
点赞  2016-5-17 17:14

若要实现同一个按键,长按与短按,执行不同的操作,这种办法应该区别不了吧?

点赞  2020-7-17 12:02
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复