准备工作

一.按键介绍与硬件连接

按键介绍

按键是常见的外部中断设备,类似于我们电路中的开关。一般的按键都有4个引脚,这4个引脚成2对:其中一对是常开触点(不按则断开,按下则闭合);一对是常闭触点(平时不按时是闭合的,按下后是断开的),硬件设计时可根据实际情况进行选择。

按键消抖

(1)按键这种物理器件本身会有抖动信号,抖动信号指的是在电平由高到低(也就是按键按下时)或者电平由低到高(也就是按键弹起时)过程中,电平的变化不是立刻变化,而是经过了一段时间的不稳定期才完成变化,在这个不稳定期间电平可能会时高时低反复变化,这个不稳定期就叫抖动(抖动期内获取按键信息是不可靠的,要想办法消抖)。
(2)什么叫消抖?消抖就是用硬件或者软件方法来尽量减小抖动期对按键获取的影响。
消抖常用2种思路:
第一是硬件消抖,消抖思路就是尽量减小抖动时间,方法是通过硬件添加电容等元件来减小抖动;
第二是软件消抖,消抖思路是发现一次按键按下/弹起事件后,不立即处理按键,而是延时一段时间(一般10~20ms,这就是消抖时间)后再次获取按键键值,如果此次获取和上次一样是按下/弹起,那就认为真的按下/弹起了。
(3)一般比较精密需要的时候,需要硬件消抖和软件消抖一起配合。

按键的2种响应方法

SoC处理按键有2种思路:轮询方式和中断方式。
轮询方式,就是SoC主动的每隔一段时间去读取(按键所对应的)GPIO的电平高低,以此获得按键信息;缺点在于CPU要一直注意按键事件,会影响CPU做其他事情。
中断方式,就是SoC事先设定好GPIO触发的中断所对应的中断处理程序ISR,当外部按键按下或弹开时会自动触发GPIO对应的外部中断,导致ISR执行,从而自动处理按键信息。

硬件连接

查询原理图可知,相应的对应关系如下:

Switch name SW1 SW2 SW3 SW4 SW5 SW6
NET name EINT2 EINT3 KP_COL0 KP_COL1 KP_COL2 KP_COL3
GPIO GPH0_2 GPH0_3 GPH2_0 GPH2_1 GPH2_2 GPH2_3
External Interrupt XEINT2 XEINT3 XEINT16 XEINT17 XEINT18 XEINT19


相关的寄存器

根据硬件连接查询数据手册可知GPH0 和GPH2相关的寄存器有GPH0CON, GPH0DAT, GPH0PUD and GPH0DRV,我们重点只使用GPH0CON和GPH0DAT;GPH2也是类似
GPH0CON:用来配置GPIO的状态
GPH0DAT:当配置为input/output时,引脚状态与配置的一致

二.轮询方式处理按键准备工作

轮询方式处理按键的程序流程

(1)第一步,先初始化GPIO模式为input;
所以GPH0CON对应的bit配置为0x0;
(2)第二步,循环读取GPIO的电平值,然后判断有无按键按下

三.中断方式处理按键准备工作

3.1 S5PV210的中断体系介绍

3.1.1 什么是中断

(1)中断的发明是用来解决宏观上的并行需要的。宏观就是从整体上来看,并行就是多件事情都完成了,从微观角度,实际上是串行。
(2)为什么需要中断?因为单核CPU实际无法并行的,但是通过中断机制,可以实现假并行(宏观上的并行,微观上实际还是串行的)。

3.1.2、SoC对中断的实现机制:异常向量表

(1)异常向量表是CPU中某些特定地址的特定定义。当中断发生的时候,中断要想办法通知CPU去处理中断,怎么做到?这就要靠异常向量表。
(2)在CPU设计时,就事先定义了CPU中一些特定地址作为特定异常的入口地址(譬如定义0x00000000地址为复位异常向量地址,则发生复位异常时CPU会自动跳转到0x00000000地址去执行指令。又譬如外部中断对应的异常向量地址为0x30000008,则发生外部中断后,CPU会硬件自动跳转到0x30000008地址去执行指令。)
(3)以上讲的是CPU硬件设计时对异常向量表的支持,下来就需要软件支持了。硬件已经决定了发生什么异常CPU自动跳转PC到哪个地址去执行,软件需要做的就是把处理这个异常的代码的首地址填入这个异常向量地址。
异常向量表
异常向量表中各个向量的相对位置是固定的,但是他们的起始地址是不固定的,各种SoC可以不一样,而且复杂ARM中还可以让用户来软件设置这个异常向量表的基地址。
扩展到所有架构的CPU中:所有架构(譬如51单片机、PIC单片机)的CPU实现中断都是通过异常向量表实现的,这个机制是不变的;但是不同CPU异常向量表的构造和位置是不同的。

3.1.3 异常和中断的区别和联系

(1)针对SoC来说,发生复位、软中断、中断、快速中断、取指令异常、数据异常等,我们都统一叫异常。所以说:中断其实是异常的一种。
(2)异常的定义就是突发事件,打断了CPU的正常常规业务,CPU不得不跳转到异常向量表中去执行异常处理程序;中断是异常的一种,一般特指SoC内的内部外设产生的打断SoC常规业务,或者外部中断(SoC的GPIO引脚传回来的中断)。

3.1.4 异常向量表的编程处理

像内存一样去访问异常向量表
(1)S5PV210的异常向量表可以改变(在CP15协处理器中),以适应操作系统的需求。但是目前系统刚启动时,此时DRAM尚未初始化,程序都在SRAM中运行。210在iRAM中设置了异常向量表,供暂时性使用。
(2)查210的iROM application note文档中iRAM的地址分配,可知,iRAM中的异常向量表起始地址为0xD0037400。知道了异常向量表的起始地址后,各个异常对应的入口就很好知道了。

函数名的实质就是函数的首地址,拿C语言中的语法来讲,函数名就是这个函数的函数指针,当我们将异常处理程序的首地址和异常向量表绑定起来后,异常处理初步阶段就完成了。到目前可以保证相应异常发生后,硬件自动跳转到对应异常向量表入口去执行时,可以执行到我们事先绑定的函数。。

3.1.5 为什么中断处理要先在汇编中进行

(1)中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场
(2)保存现场包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12
(3)为什么要保存LR寄存器?要考虑中断返回的问题。中断ISR执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回时关键的2个寄存器就是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR。
(4)中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR中

3.1.6 汇编保存现场和恢复现场

(1)保护现场关键是保存:中断处理程序的返回地址,r0-r12(cpsr是自动保存的)
(2)恢复现场主要是恢复:r0-r12,pc,cpsr

3.2 S5PV210和S3C2440 的异常处理阶段对比

3.2.1 异常处理的2个阶段

可以将异常处理分为2个阶段来理解。第一个阶段是异常向量表跳转;第二个阶段就是进入了真正的异常处理程序irq_handler之后的部分。

(1)第一个阶段之所以能够进行,主要依赖于CPU设计时提供的异常向量表机制。第一个阶段的主要任务是从异常发生到响应异常并且保存/恢复现场、跳转到真正的异常处理程序处。
(2)第二个阶段的目的是识别多个中断源中究竟哪一个发生了中断,然后调用相应的中断处理程序来处理这个中断。

3.2.2 S3C2440的第二阶段处理过程

(1)第一个问题,怎么找到具体是哪个中断:S3C2440的中断控制器中有一个寄存器(32位的),寄存器的每一个位对应一个中断源(为了解决支持更多中断源,2440又设计了一个子中断机制。在一级中断寄存器中有一些中断是共用的一个bit位,譬如AC97和WDT。对于共用中断,用子中断来区分究竟是哪一个发生了中断)
(2)第二个问题,怎么找到对应的isr的问题:首先给每个中断做了个编号,进入isr_handler之后先通过查阅中断源寄存器和子中断寄存器(中哪一位为1)确定中断的编号,然后用这个编号去isr数组(isr数组是中断初始化时事先设定好的,就是把各个中断的isr的函数名组成一个数组,用中断对应的编号作为索引来查询这个数组)中查阅得到isr地址。

评价:2440的中断处理设计不是特别优秀:第一个过程中使用子中断搞成2级的很麻烦;第二个过程中计算中断编号是个麻烦事,很耗费时间。而中断处理的时间是很宝贵的(系统有一个性能指标,叫实时性。实时性就是中断发生到响应的时间,这个时间越短越好。)

3.2.2 S5PV210的第二阶段处理过程

(1)第一个问题,怎么找到具体是哪个中断:S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号。
(2)第二个问题,怎么找到对应的isr的问题:210中支持的中断源多了很多,如果还使用2440的那一套来寻找isr地址就太慢了,太影响实时性了。于是210开拓了一种全新的寻找isr的机制。210提供了很多寄存器来解决每个中断源对应isr的寻找问题,实现的效果是当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,我们软件只要去这个寄存器中执行函数就行了。

3.2.3 总结

第一阶段都相同,第二阶段各不同
(1)第一阶段(异常向量表阶段)2440和210几乎是完全相同的。实际上几乎所有的CPU在第一阶段都是相同的。
(2)第二阶段就彼此不同了。各个SoC根据自己对实时性的要求,和支持的中断源的多少,各自发明了各自处理中断,找到中断编号,进一步找到对应isr地址的方式。

3.3 S5PV210中断处理的主要寄存器

3.3.1 VICnINTENABLE和VICnINTENCLEAR

(1)VICnINTENABLE 对应interrupt enable,INTENCLEAR对应interrupt enable clear
(2)INTENABLE寄存器负责相应的中断的使能,INTENCLEAR寄存器负责相应的中断的禁止。
(3)当我们想使能(意思就是启用这个中断,意思就是当硬件产生中断时CPU能接收的到)某个中断时,只要在这个中断编号对应的VICnINTENABLE的相应bit位写1即可(注意这个位写1其他位写0对其他位没有影响);如果我们想禁止某个中断源时,只要向VICnINTENCLEAR中相应的位写1即可。

注意:这里的设计一共有2种:有些CPU是中断使能和禁止是一个寄存器位,写1就使能写0就进制(或者反过来写1就进制写0就使能),这样的中断使能设计就要非常小心,要使用我们之前说过的读改写三部曲来操作;另一种就是使能和禁止分开为2个寄存器,要使能就写使能寄存器,要禁止就写禁止寄存器。这样的好处是我们使能/禁止操作时不需要读改写,直接写即可。

3.3.2 VICnINTSELECT

(1)设置各个中断的模式为irq还是fiq。一般都设置成irq
(2)IRQ和FIQ究竟有何区别。210中支持2种中断,irq和fiq。irq是普通中断,fiq是快速中断。快速中断提供一种更快响应处理的中断通道,用于对实时性要求很高的中断源。fiq在CPU设计时预先提供了一些机制保证fiq可以被快速处理,从而保证实时性。fiq的限制就是只能有一个中断源被设置为fiq,其他都是irq。
(3)CPU如何保证fiq比irq快?
第一,fiq模式有专用的r8~r12,因此在fiq的isr中可以直接使用r8-r12而不用保存,这就能节省时间;
第二,异常向量表中fiq是最后一个异常向量入口。因此fiq的isr不需要跳转,可以直接写在原地,这样就比其他异常少跳转一次,省了些时间。

3.3.3 VICnIRQSTATUS和VICnFIQSTATUS

中断状态寄存器,是只读的。当发生了中断时,硬件会自动将该寄存器的对应位置为1,表示中断发生了。软件在处理中断第二阶段的第一阶段,就是靠查询这个寄存器来得到中断编号的。

3.3.4 VICnVECTPRIORITY0~VICnVECTPRIORITY31

中断优先级设置寄存器,设置多个中断同时发生时先处理谁后处理谁的问题。一般来说高优先级的中断可以打断低优先级的中断,从而嵌套处理中断。当然了有些硬件/软件可以设置不支持中断嵌套。

3.3.5 VICnVECTADDR0~VICnVECTADDR31、VICnADDR

(1)这三个寄存器和210中断处理第二阶段的第二阶段有关。
(2)VICnVECTADDR0到31这32个寄存器分别用来存放真正的各个中断对应的isr的函数地址。相当于每一个中断源都有一个VECTADDR寄存器,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。
(3)VICnADDR这个寄存器是只需要读的,它里面的内容是由硬件自动设置的。当发生了相应中断时,硬件会自动识别中断编号,并且会自动找到这个中断的VECTADDR寄存器,然后将其读出复制到VICnADDR中,供我们使用。这样的设计避免了软件查找中断源和isr,节省了时间,提高了210的中断响应速度。

3.3.6整个中断的流程梳理

整个中断的工作分为2部分:
第一部分是我们为中断响应而做的预备工作:
1. 初始化中断控制器
2. 绑定写好的isr到中断控制器
3. 相应中断的所有条件使能
第二部分是当硬件产生中断后如何自动执行isr:
1. 第一步,经过异常向量表跳转入IRQ/FIQ的入口
2. 第二步,做中断现场保护(在start.S中),然后跳入isr_handler
3. 第三步,在isr_handler中先去搞清楚是哪个VIC中断了,然后直接去这个VIC的ADDR
寄存器中取isr来执行即可。
4. 第四步,isr执行完,中断现场恢复,直接返回继续做常规任务。

3.3.7 外部中断需要的准备工作
什么是外部中断

(1)SoC支持的中断类型中有一类叫外部中断。内部中断就是指的中断源来自于SoC内部(一般是内部外设),譬如串口、定时器等部件产生的中断;外部中断是SoC外部的设备,通过外部中断对应的GPIO引脚产生的中断。
(2)按键在SoC中就使用外部中断来实现。具体实现方法是:将按键电路接在外部中断的GPIO上,然后将GPIO配置为外部中断模式。此时人通过按按键改变按键电路的电压高低,这个电压高低会触发GPIO对应的外部中断,通过引脚传进去给CPU处理。
(3)外部中断相关的介绍和寄存器都在2.2.60章节(属于GPIO部分)

电平触发和边沿触发

(1)外部中断的触发模式主要有2种:电平触发和边沿触发。
(1)电平触发就是说GPIO上的电平只要满足条件,就会不停触发中断。电平触发分为高电平触发和低电平触发。电平触发的特点是,只要电平满足条件就会不停触发中断。
(2)边沿触发分为上升沿触发、下降沿触发和双边沿触发三种。边沿触发不关心电平常规状态,只关心电平变化的瞬间(边沿触发不关心电平本身是高还是低,只关心变化是从高到低还是从低到高的这个过程)。
分析按键的工作:如果我们关注的是按键按下和弹起这两个事件本身,那么应该用边沿触发来处理按键;如果我们关心的是按键按下/弹起的那一段时间,那么应该用电平触发。

关键寄存器:CON、PEND、MASK

(1)外部中断的主要配置寄存器有3个:EXT_CON、EXT_PEND、EXT_MASK
(2)EXT_CON配置外部中断的触发方式。触发方式就是说外部电平怎么变化就能触发中断,也就是说这个外部中断产生的条件是什么
(3)EXT_PEND寄存器是中断挂起寄存器。这个寄存器中每一位对应一个外部中断,平时没有中断时值为0。当发生了中断后,硬件会自动将这个寄存器中该中断对应的位置1,我们去处理完这个中断后应该手工将该位置0。这个PEND寄存器的位就相当于是一个标志,如果发生了中断但是我们暂时忙来不及去处理时,这个位一直是1(这就是挂起),直到我有空了去处理了这个中断才会手工清除(写代码清除)这个挂起位表示这个中断被我处理了。
(4)EXT_MASK寄存器就是各个外部中断的使能/禁止开关。

编程实践

1 . 轮询方式处理按键编程

//使用轮询的方式实现按键中断子程序key.c,实际使用时只需要在主程序中调用key_init()和void key_polling()即可。//先定义使用到的寄存器#define  GPH0CON  0xE0200C00
#define  GPH0DAT  0xE0200C04
#define  GPH2CON  0xE0200C40
#define  GPH2DAT  0xE0200C44#define  rGPH0CON  (*(volatile unsigned int *)GPH0CON)
#define  rGPH0DAT  (*(volatile unsigned int *)GPH0DAT)
#define  rGPH2CON  (*(volatile unsigned int *)GPH2CON)
#define  rGPH2DAT  (*(volatile unsigned int *)GPH2DAT)void key_init(void)
{rGPH0CON &= ~(0xFF<<8);   //配置(bit8~15)SW1和SW2 为input模式//rGPH2CON  = 0<<15;       实践证明这种操作是不可行的,不能使用0 进行移位  rGPH0CON &= ~(0xFFFF<<0);   //配置bit0~bit15 (SW3~5 )为input模式
}void key_polling(void)
{while (1){if (rGPH0DAT & (1<<2)){led_off();}else led1();if (rGPH0DAT & (1<<3)){led_off();}else{led2();}if (rGPH2DAT & (1<<0)){led_off();}else{led3();}}
}

2 .中断方式处理按键编程

中断方式处理按键程序框图

详细程序解读
main.c

#include "stdio.h"
#include "int.h"
#include "main.h"void uart_init(void);//通过查询硬件电路可知,这6个按键对应的外部中断为EINT2~3 ,EINT16~19#define KEY_EINT2     NUM_EINT2       // left
#define KEY_EINT3       NUM_EINT3       // down
#define KEY_EINT16_19   NUM_EINT16_31   // 其余4个共用的void delay(int i)
{volatile int j = 10000;while (i--)while(j--);
}int main(void)
{uart_init();//key_init();key_init_interrupt();      // 以中断方式来处理按键的初始化// 如果程序中要使用中断,就要调用中断初始化来初步初始化中断控制器system_init_exception();  //绑定第一阶段异常向量表;禁止所有中断;选择所有中断类型为IRQ;printf("-------------key interrypt test--------------");// 绑定isr到中断控制器硬件intc_setvectaddr(KEY_EINT2, isr_eint2);intc_setvectaddr(KEY_EINT3, isr_eint3);intc_setvectaddr(KEY_EINT16_19, isr_eint16171819);// 使能中断intc_enable(KEY_EINT2);intc_enable(KEY_EINT3);intc_enable(KEY_EINT16_19);// 在这里加个心跳while (1){printf("A ");delay(10000);}return 0;
}

如下是一些比较重要的函数

(1)中断初始化函数:void key_init_interrupt()
第一步:配置这六个按键的寄存器为外部中断模式
第二步:中断触发模式的选择
第三步:中断允许Mask
第四步:清挂起,清除是写1,不是写0

// 以中断方式来处理按键的初始化
void key_init_interrupt(void)
{// 1. 外部中断对应的GPIO模式设置rGPH0CON |= 0xFF<<8;       // GPH0_2 GPH0_3设置为外部中断模式rGPH2CON |= 0xFFFF<<0;      // GPH2_0123共4个引脚设置为外部中断模式// 2. 中断触发模式设置rEXT_INT_0_CON &= ~(0xFF<<8);    // bit8~bit15全部清零rEXT_INT_0_CON |= ((2<<8)|(2<<12));       // EXT_INT2和EXT_INT3设置为下降沿触发rEXT_INT_2_CON &= ~(0xFFFF<<0);rEXT_INT_2_CON |= ((2<<0)|(2<<4)|(2<<8)|(2<<12));    // 3. 中断允许rEXT_INT_0_MASK &= ~(3<<2);            // 外部中断允许rEXT_INT_2_MASK &= ~(0x0f<<0);// 4. 清挂起,清除是写1,不是写0rEXT_INT_0_PEND |= (3<<2);rEXT_INT_2_PEND |= (0x0F<<0);
}

(2)第一阶段绑定异常向量表函数:void system_init_exception()
主要功能:绑定第一阶段异常向量表;禁止所有中断;选择所有中断类型为IRQ;
本次我们主要使用的是IRQ,并且irq和fiq 都使用IRQ_handle

IRQ_handle的作用:第二阶段产生中断如何执行isr
设置IRQ模式下的栈
保存LR
保存r0-r12和lr到irq模式下的栈上面
调用真正的isr来处理中断(因为中断向量表空间有限,所以一般中断向量表会使用一个跳转指令跳转到真正的执行地址处)。
处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起恢复


void system_init_exception(void)
{// 第一阶段处理,绑定异常向量表r_exception_reset = (unsigned int)reset_exception;r_exception_undef = (unsigned int)undef_exception;r_exception_sotf_int = (unsigned int)sotf_int_exception;r_exception_prefetch = (unsigned int)prefetch_exception;r_exception_data = (unsigned int)data_exception;r_exception_irq = (unsigned int)IRQ_handle;r_exception_fiq = (unsigned int)IRQ_handle;// 初始化中断控制器的基本寄存器intc_init();
}
IRQ_handle:// 设置IRQ模式下的栈ldr sp, =IRQ_STACK// 保存LR// 因为ARM有流水线,所以PC的值会比真正执行的代码+8,sub lr, lr, #4// 保存r0-r12和lr到irq模式下的栈上面stmfd sp!, {r0-r12, lr}// 在此调用真正的isr来处理中断bl irq_handler// 处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起恢复ldmfd sp!, {r0-r12, pc}^

(3)绑定isr到VICnVECTADDR寄存器函数:void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
绑定过之后我们就把isr地址交给硬件了,剩下的我们不用管了,硬件自己会处理
等发生相应中断的时候,我们直接到相应的VICnADDR中去取isr地址即可。

参数:intnum是int.h定义的物理中断号,handler是函数指针,就是我们写的isr

VIC0VECTADDR定义为VIC0VECTADDR0寄存器的地址,就相当于是VIC0VECTADDR0~31这个
数组(这个数组就是一个函数指针数组)的首地址,然后具体计算每一个中断的时候
只需要首地址+偏移量即可。


//每一个中断源都有一个VECTADDR寄存器,用KEY_EINT2 为例,
//  intc_setvectaddr(2,isr_eint2)
//   *( (volatile unsigned long *)(0xF2000100+ 4*(2-0)) ) = (unsigned)isr_eint2;
//  则将我们的isr_eint2写入到0xF2000108(VIC0VECTADDR2)的位置void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{//VIC0if(intnum<32){*( (volatile unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;}//VIC1else if(intnum<64){*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;}//VIC2else if(intnum<96){*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;}//VIC3else{*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;}return;
}

(4)使能中断函数:void intc_enable(unsigned long intnum)

// 使能中断
// 通过传参的intnum来使能某个具体的中断源,中断号在int.h中定义,是物理中断号
void intc_enable(unsigned long intnum)
{unsigned long temp;// 确定intnum在哪个寄存器的哪一位// <32就是0~31,必然在VIC0if(intnum<32){temp = VIC0INTENABLE;itemp |= (1<<intnum);       // 如果是第一种设计则必须位操作,第二种设计可以// 直接写。VIC0INTENABLE = temp;}else if(intnum<64){temp = VIC1INTENABLE;temp |= (1<<(intnum-32));VIC1INTENABLE = temp;}else if(intnum<96){temp = VIC2INTENABLE;temp |= (1<<(intnum-64));VIC2INTENABLE = temp;}else if(intnum<NUM_ALL){temp = VIC3INTENABLE;temp |= (1<<(intnum-96));VIC3INTENABLE = temp;}// NUM_ALL : enable all interruptelse{VIC0INTENABLE = 0xFFFFFFFF;VIC1INTENABLE = 0xFFFFFFFF;VIC2INTENABLE = 0xFFFFFFFF;VIC3INTENABLE = 0xFFFFFFFF;}}
  • C语言指针的使用详解

注: 以上内容来自朱老师物联网大讲堂裸机课程课件

嵌入式裸机按键和CPU的中断系统学习笔记相关推荐

  1. 《8.按键和CPU的中断系统》

    转自 https://edu.csdn.net/lecturer/505 朱老师物联网大讲堂 <8.按键和CPU的中断系统> 第一部分.章节目录 1.8.1.什么是按键 1.8.2.轮询方 ...

  2. 1.8.ARM裸机第八部分-按键和CPU的中断系统

    1.8.1.什么是按键 1.8.1.1.按键的物理特性 (1).平时没人按的时候,弹簧把按键按钮弹开.此时内部断开的. (2).有人按下的时候,手的力量克服弹簧的弹力,将按钮按下,此时内部保持接通(闭 ...

  3. 外设篇:按键和CPU的中断系统

    什么是按键 按键的物理特性 (1).平时没人按的时候,弹簧把按键按钮弹开.此时内部断开的. (2).有人按下的时候,手的力量克服弹簧的弹力,将按钮按下,此时内部保持接通(闭合)状态:如果手拿开,则弹簧 ...

  4. 这个设计思想能启蒙你很多年,嵌入式裸机按键扫描

    这个设计思想能启蒙你很多年,嵌入式裸机按键扫描 摘要:本文目的是讲述一个按键扫描处理的面向对象开发的设计思想,适用于裸机开发,通过按键扫描,检测到按键是否按下,松开等状态,并将该状态通过其他形式反馈给 ...

  5. 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)

    接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...

  6. uC/OS-II系统学习笔记(4)—— uC/OS-II概述上篇

    1 临界段 uC/OS-II在处理临界段代码时,是需要关闭中断的,处理完毕之后再开中断,这使得uC/OS-II能够避免同时有其他任务或中断服务进入临界代码段. uC/OS-II定义了两个宏(macro ...

  7. React系统学习笔记

    ***当前阶段的笔记 *** 「面向实习生阶段」https://www.aliyundrive.com/s/VTME123M4T9 提取码: 8s6v 点击链接保存,或者复制本段内容,打开「阿里云盘」 ...

  8. Dubbo -- 系统学习 笔记 -- 示例 -- 参数验证

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 参数验证 参数验证功能是基于JSR303实现的,用户只需标识JSR303标准的验证 ...

  9. Dubbo -- 系统学习 笔记 -- 示例 -- 服务分组

    Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 服务分组 当一个接口有多种实现时,可以用group区分. <dubbo:se ...

最新文章

  1. 数据中心的未来:一体化无人值守
  2. vuex modules 命名空间
  3. 牛客 - 血压游戏(虚树+dp)
  4. POJ - 3842 An Industrial Spy dfs(水)
  5. springboot怎么杀进程_线上服务平均响应时间太长,怎么排查?
  6. paddlenlp 任务清单 中文分词、中文纠错、文本相似度、情感分析、词性标注等一键
  7. 18 CO配置-控制-产品成本控制-产品成本计划编制-定义估价变式
  8. 奖励名单表格模板_“我用一套表格,解决了孩子的拖延症,一路用到小学高年级!”...
  9. python工业互联网应用实战13—基于selenium的功能测试
  10. [转] SQL Server试题
  11. SpringMVC之安全性(二)登录界面
  12. 6. Document close() 方法
  13. zemax验证高斯公式_Zemax中高斯光束设置的相关问题
  14. javascript 图片上传并显示
  15. Android集成微信支付时返回错误码errcode:40125解决方案
  16. 一种高带外抑制Ku波段滤波器设计
  17. 随记(七):Jboss漏洞检测利用工具
  18. 新手教程篇-阿里云账号如何注册?
  19. PEP8 python规范神器和jupyter notebook主题更改--Jupyter Notebook 快速入门
  20. 如何写出“简单“代码?

热门文章

  1. 电气工程计算机方向,电气工程及其自动化就业方向有哪些
  2. 浅谈游戏开发之2D手游工具
  3. 如何通过电脑发送短信——开始篇
  4. 2012中国数据库技术大会演讲PPT下载
  5. tiktok最新风控算法以及视频播放量问题研究
  6. TikTok独立站电商带货
  7. Photoshop入门与进阶实例:4.2 封尘的杂志
  8. HM4056D一款完整的单节锂离子电池充电器IC
  9. 基于51单片机智能路灯控制系统
  10. 查看redis信息命令