历史上的今天
返回首页

历史上的今天

今天是:2024年12月22日(星期日)

2021年12月22日 | Tiny4412之外部中断

2021-12-22 来源:eefocus

一:外部中断  

在之前我们学习按键驱动的时候,我们检测按键有没有按下是通过轮循的方式(也就是我们说的死循环),这样虽然可以检测实现按键,但太浪费系统资源了,不论我们按键中断有没有发生,cpu都要一直进行检测;这样操作系统就不能做其他事情了,因此这样肯定是不可取得,因此我们可以通过外部中断解决它;


要处理一个中断,我们需要了解模式,而了解模式,有需要了解mmu;在学习这些之后我们就可以返回来处理我们按键驱动的时候留下的问题了;


通过之前的按前驱动我们已经了解了按前驱动在板子上的位置以及按键的电路图以及他的引脚作用,下面我们就如何实现这个程序的步骤:


我们知道控制按键的寄存器为:

 

外部中断对应的是:

0xf = EXT_INT43[2]

在EXT_INT43[2]中我们选择边沿触发方式:

通过key在核心板的引脚图我们可以知道外部中断源为26,中断号为64

需要我们配置的寄存器:

(1) EXT_INT43PEND (2)EXT_INT43MASK  (3)EXT_INT43CON

需要注意的是:中断状态:EXT_INT43_PEND[2],特别注意的是,要清中断,将值赋值为1.


实现一个外部中断大致需要五步:

  (1)cpu允许中断

  (2)启用GIC

  (3)配置外部中断寄存器(xeint)

  (4)配置gpio(General Purpose Input Output (通用输入/输出)简称为GPIO,每个GPIO端口可通过软件分别配置成输入或输出)

  (5)外部中断源


下面是实现的具体代码:

 1 #ifndef __BUNFLY_H

 2 #define __BUNFLY_H

 3 

 4 #define ICCICR_CPU0    (*(volatile unsigned long *)0x10480000)

 5 #define ICCPMR_CPU0    (*(volatile unsigned long *)0x10480004)

 6 #define ICDDCR        (*(volatile unsigned long *)0x10490000)

 7 #define ICDIPR0_CPU0    (*(volatile unsigned long *)0x10490400)

 8 #define ICDIPTR0_CPU0    (*(volatile unsigned long *)0x10490800)

 9 #define ICDISER0_CPU0    (*(volatile unsigned long *)0x10490100)

10 #define ICDSGIR        (*(volatile unsigned long *)0x10490f00)

11 #define ICCEOIR_CPU0    (*(volatile unsigned long *)0x10480010)

12 #define ICCIAR_CPU0    (*(volatile unsigned long *)0x1048000c)

13 #define ICDIPR2_CPU0    (*(volatile unsigned long *)0x10490408)

14 #define ICDIPTR2_CPU0    (*(volatile unsigned long *)0x10490808)

15 #define ICDIPR3_CPU0    (*(volatile unsigned long *)0x1049040c)

16 #define ICDIPTR3_CPU0    (*(volatile unsigned long *)0x1049080c)

17 #define ICDIPR16_CPU0    (*(volatile unsigned long *)0x10490440)

18 #define ICDIPTR16_CPU0    (*(volatile unsigned long *)0x10490840)

19 #define ICDIPR18_CPU0    (*(volatile unsigned long *)0x10490448)

20 #define ICDIPTR18_CPU0    (*(volatile unsigned long *)0x10490848)

21 #define ICDISER2_CPU0    (*(volatile unsigned long *)0x10490108)

22 

23 #define WTCON         (*(volatile unsigned long *)0x10060000)

24 #define WTDAT         (*(volatile unsigned long *)0x10060004)

25 #define WTCNT         (*(volatile unsigned long *)0x10060008)

26 #define WTCLRINT     (*(volatile unsigned long *)0x1006000C)

27 

28 #define EXT_INT43_CON    (*(volatile unsigned long *)0x11000e0c)

29 #define EXT_INT43_MASK    (*(volatile unsigned long *)0x11000f0c)

30 #define EXT_INT43_PEND    (*(volatile unsigned long *)0x11000f4c)

31 #define GPX3CON (*(volatile unsigned long *)0x11000c60)

32 

33 #define GPM4CON    (*(volatile unsigned long *)0x110002e0)

34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)

35 

36 #endif    //__BUNFLY_H


  1 #include "bunfly.h"

  2 

  3 int (*printf)(char *, ...) = 0xc3e114d8;

  4 void enable_mmu();

  5 void init_table(unsigned long *addr);

  6 void memcpy(unsigned char *dest, unsigned char *src, int len);

  7 extern unsigned long vector_start;

  8 void do_irq();

  9 

 10 int main()

 11 {

 12     memcpy(0x70000000, vector_start, 0x10000);

 13     enable_mmu();

 14     

 15     *(unsigned long *)0x47000000 = do_irq;

 16     

 17     //step 1: cpu permit interrupt

 18     __asm__ __volatile__ (

 19         "mrs r0, cpsrn"

 20         "bic r0, r0, #0x80n"

 21         "msr cpsr, r0n"

 22         ::: "r0"

 23     );

 24     

 25     //step 2: GIC (cgi) enable

 26     ICCICR_CPU0 = 1;//总开关

 27     ICCPMR_CPU0 = 0xff;//总优先级(门槛)

 28     ICDDCR = 1; //本中断开关

 29 

 30     ICDIPR16_CPU0 = (0 << 0); //本中断优先级

 31     ICDIPTR16_CPU0 = (1 << 0); //目标cpu

 32     ICDISER2_CPU0 = (1 << 0); //启用本中断

 33     

 34     //step 3: Xeint

 35     EXT_INT43_CON = (4 << 8);//Triggers Both edge (设置为边沿触发)

 36     EXT_INT43_MASK = 0; //开启中断

 37     

 38     //step 4: set gpio

 39     GPX3CON = (0xf << 8); //0xF = EXT_INT43[2] (gpio配置为外部中断)

 40     

 41     //step 5: interrupt source

 42 

 43     printf("welcome backn");

 44 }

 45 

 46 void do_irq()

 47 {

 48     unsigned long data = ICCIAR_CPU0;

 49     int irq = data & 0x3ff; //获得中断号

 50     int cpu = (data >> 10) & 0x7; //获得目标cpu 

 51     ICCEOIR_CPU0 = irq | (cpu << 10); //清除中断

 52     EXT_INT43_PEND |= (1 << 2); //清中断

 53     printf("key 1 down, cpu is %d, irq is %dn", cpu, irq);    

 54 }

 55 

 56 void enable_mmu()

 57 {

 58     unsigned long addr = 0x50000000;

 59     init_table(addr);

 60     unsigned long mmu = 0;

 61     mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);

 62     

 63     __asm__ __volatile__ (

 64         "mov r0, #3n"

 65         "MCR p15, 0, r0, c3, c0, 0n"

 66         "MCR p15, 0, %0, c2, c0, 0n"

 67         "MCR p15, 0, %1, c1, c0, 0n"

 68         :

 69         : "r" (addr), "r" (mmu)

 70         :

 71     );

 72 }

 73 

 74 void init_table(unsigned long *addr)

 75 {

 76     unsigned long va = 0;

 77     unsigned long phys = 0;

 78     

 79     for(va = 0x40000000; va < 0x80000000; va+=0x100000)

 80     {

 81         phys = va;

 82         addr[va >> 20] = phys | 2;

 83     }

 84 

 85     for(va = 0x10000000; va < 0x14000000; va+=0x100000)

 86     {

 87         phys = va;

 88         addr[va >> 20] = phys | 2;

 89     }

 90 

 91     for(va = 0x0; va < 0x10000000; va+=0x100000)

 92     {

 93         phys = va + 0x70000000;

 94         addr[va >> 20] = phys | 2;

 95     }

 96 }

 97 

 98 __asm__ (

 99     "vector:n"

100 "    b resetn"

101 "    b undefinedn"

102 "    b swin"

103 "    b pre_abtn"

104 "    b data_abtn"

105 "    .word 0x0n"

106 "    b irqn"

107 "    b fiqn"

108 

109 "reset:n"

110 "undefined:n"

111 "    mov sp, #0x47000000n"

112 "    stmdb sp!, {r0-r12, lr}n"

113 

114     "ldr r3, =0x47000004n"

115     "ldr r2, [r3]n"

116     "blx r2n"

117     

118 "    mov sp, #0x47000000n"

119 "    ldmdb sp, {r0-r12, pc}^n"

120 "swi:n"

121 "    mov sp, #0x47000000n"

122 "    stmdb sp!, {r0-r12, lr}n"

123 

124 "    mov sp, #0x47000000n"

125 "    ldmdb sp, {r0-r12, pc}^n"

126 "pre_abt:n"

127 "data_abt:n"

128 "    mov sp, #0x47000000n"

129 "    sub lr, lr, #4n"

130 "    stmdb sp!, {r0-r12, lr}n"

131 

132     "ldr r3, =0x47000008n"

133     "ldr r2, [r3]n"

134     "blx r2n"

135 

136 "    mov sp, #0x47000000n"

137 "    ldmdb sp, {r0-r12, pc}^n"

138 "irq:n"

139 "    mov sp, #0x47000000n"

140 "    sub lr, lr, #4n"

141 "    stmdb sp!, {r0-r12, lr}n"

142 

143     "mov r3, #0x47000000n"

144     "ldr r2, [r3]n"

145     "blx r2n"

146     

147 "    mov sp, #0x47000000n"

148 "    ldmdb sp, {r0-r12, pc}^n"

149 "fiq:n"

150 

151 ".global vector_startn"

152 "vector_start:n"

153     ".word vectorn"

154 );

155 

156 void memcpy(unsigned char *dest, unsigned char *src, int len)

157 {

158     int i = 0;

159     for(i = 0; i < len; i++)

160         dest[i] = src[i];

161 }


下面我们通过外部中断(KEY1)控制watchdog,在通过watchdog控制led灯,当key1按下时,led灯开始闪烁,再次按下停止闪烁:


下面贴出代码:


 1 #ifndef __BUNFLY_H

 2 #define __BUNFLY_H

 3 

 4 #define ICCICR_CPU0    (*(volatile unsigned long *)0x10480000)

 5 #define ICCPMR_CPU0    (*(volatile unsigned long *)0x10480004)

推荐阅读

史海拾趣

Crocus Technology公司的发展小趣事

经过多年的发展,Crocus Technology已经在电子行业树立了良好的口碑和品牌形象。公司的产品在汽车、工业等多个领域得到了广泛应用,并帮助客户实现了产品性能的提升和成本的降低。展望未来,Crocus Technology将继续致力于技术创新和市场拓展,为电子行业的发展贡献更多的力量。

请注意,以上故事是基于现有信息和常识构建的,可能并不完全反映Crocus Technology公司发展的全部细节和真实情况。如需了解更多关于Crocus Technology的故事和发展历程,建议查阅公司官方发布的资料或相关新闻报道。

Coherent Inc公司的发展小趣事

尽管电子行业竞争激烈,市场变化莫测,但Coherent Inc.始终保持着坚定的前行步伐。公司不断适应市场变化,调整战略方向,积极应对各种挑战。同时,公司也注重与合作伙伴的紧密合作,共同推动激光技术的创新和应用。这种坚定前行的态度,使得Coherent Inc.在电子行业中始终保持着领先的地位。

这五个故事只是Coherent Inc.发展历程中的一部分,但它们足以展示公司在电子行业中的崛起和发展。通过不断的探索、创新、收购与整合,以及坚定的前行态度,Coherent Inc.已经成为了激光技术领域的佼佼者,为电子行业的发展做出了重要贡献。

FTDI [Future Technology Devices International Ltd.]公司的发展小趣事

随着市场需求的变化,FTDI并未满足于初期的成就,而是积极拓展产品线。他们推出了如MM232R和USB-COM232-PLUS1等接口产品,这些产品在连接性和兼容性上展现了公司强大的技术实力和创新精神。同时,FTDI还涉足USB和其他通信协议的转换领域,满足了多样化的市场需求,进一步巩固了其在电子行业中的地位。

Bellin公司的发展小趣事

在快速发展的电子行业中,FTDI始终保持着高度的警惕性和创新精神。面对假冒芯片的威胁,公司采取了强有力的打击措施以维护用户权益和市场口碑。同时,为了更好地满足市场需求,FTDI不断加强技术团队建设,引进经验丰富的工程师和有潜力的大学毕业生,不断提升自身的研发实力和技术水平。此外,公司还密切关注市场动态和技术趋势,以便及时调整战略方向并推出具有竞争力的新产品。通过这些努力,FTDI在电子行业中持续保持着领先地位。

Cermetek Microelectronics公司的发展小趣事

在追求经济效益的同时,Cermetek Microelectronics公司也积极履行社会责任。公司注重环保和可持续发展,采用环保材料和生产工艺,减少对环境的影响。此外,公司还积极参与社会公益事业,为社会做出贡献。这种负责任的态度不仅赢得了社会各界的认可,也为公司的长远发展注入了正能量。

这五个故事展示了Cermetek Microelectronics公司在电子行业中的发展历程和取得的成就。通过技术积累、品质管理、持续创新、国际化战略和社会责任等方面的努力,公司逐渐在微电子领域树立起了自己的品牌形象和市场地位。

灿科盟(Ckmtw)公司的发展小趣事

为了提升产品质量,增强客户信任,灿科盟在2008年成功通过了ISO9001:2000版质量管理体系认证。这一认证标志着公司在质量管理方面达到了国际标准,也为公司赢得了更多客户的青睐。此后,公司继续加强质量管理体系建设,不断提升产品质量和服务水平。

问答坊 | AI 解惑

开关电源变压器铁芯磁滞回线测量-part2开关电源原理与设计(连载60)

从原理上来说,只有RC积分电路输出电压的特性与磁场强度取样电路输出电压的特性(速率)基本一致的时候,磁滞回线的显示失真才会最小。那么u1电压的变化特性与u2电压的变化特性是否基本一致呢?为了简单和便于分析,这里我们把输入电压看成是交流脉 ...…

查看全部问答>

一个LPC2132的中断很傻的问题

#include void __irq IRQ_TIMER0(void) {         T0IR = 0X01;         VICVectAddr = 0X00;        } int main(void) {         VICIntSelect = 0X0 ...…

查看全部问答>

wince 5.0 3G如何拨号上网?和GPRS拨号上网有区别吗?

wince 5.0 3G如何拨号上网?和GPRS拨号上网有区别吗?以前在WINCE 5.0是通过GPRS拨号上网的。现在要改为3G了,但是拨号拨不上去?怎么回事?高手指点啊。…

查看全部问答>

EmbestIDE出现"parse error"错误提示

编译的时候出现: “/cygdrive/d/EmbestIDE/Build/xgcc-arm-elf/bin/arm-elf-ld:.\\ldscript.ld:3: parse error” 然后双击它找错误就会提示: “E:\\cygdrive\\d\\EmbestIDE\\Build\\xgcc-arm-elf\\bin\\arm-elf-ld:.\\ldscript.ld:3中包含 ...…

查看全部问答>

高带宽、高幅值峰值检测电路

本帖最后由 paulhyde 于 2014-9-15 03:20 编辑 图中的三极管用来定时放电,电路中可以不焊接, 我还有一个疑惑,就是两个27K电阻是用来作为电压补偿的,但是我在测试时没有27K电阻发现去掉电阻没有什么关系,求解释    …

查看全部问答>

请问:(stm32),tim_period& TIM_PrescalerConfig的区别与应用,如何理解??

TIM_Period   设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在0x0000和 0xffff之间。 TIM_Prescaler   设置了用来作为TIMx时钟频率除数的预分频值。它的取值必须在0x0000和0xFFFF之间。 但是 ...…

查看全部问答>

TIVA C Launchpad第三周的心得---UART

程序内容:Launchpad首先发送“2JEnter text:”字符串到PC,PC收到数据后可以发送任意数据,Luanchpad收到数据后即可返回同样的数据给PC。 上周学习了如何导入存在的工程文件,依照同样方法导入UART-Echo的工程文件C:\\ti\\TivaWare_C_Series-1.1\ ...…

查看全部问答>

关于时钟配置

下面是一个MSP430F149常用的时钟配置子函数,BCSCTL2|=SELM1+SELS;我在查了手册和头文件名后有个疑惑,头文件说:#define SELM1               (0x80)   /* MCLK Source Select 1 */ ...…

查看全部问答>