ARM中外部中断

发布时间:2024-09-18  

在整个ARM体系结构中,为了处理外部中断,依次学习了MMU,模式跳转,异常,GIC,看门狗程序,这些都是为了处理外部中断

具体如下:

处理外部中断有五个步骤:

 30      //step 1: cpu cpsr
 31       __asm__ __volatile__(
 32           'mrs r0, cpsrn'
 33           'bic r0, r0, #0x80n'//设置CPSR的I位,将IRQ位打开
 34           'msr cpsr, r0n'
 35           ::: 'r0'
 36       );
 37
 38     //setp1:GIC
 39     ICCICR_CPU0 = 1;
 40     ICCPMR_CPU0 = 0xff;
 41

  前面的代码不解释,和以前的差不多

外部中断号为:64


 42     //step2:设置中断号
 43     ICDDCR = 1;//总开关
 44     ICDIPR16_CPU0 = (0x0 << 0);//ICD一共40个寄存器,第16个寄存器,第0位
 45     ICDIPTR16_CPU0 = (0x1 << 0);//优先级,最高
 46     ICDISER2_CPU0 = (1 << 0);//一共五个,第2个使能中断

 


 47 

  第二步为设置中断号:

 详细看代码注释:寄存器参考手册第594页


 48     //step 3: set gpio
 49     GPX3CON = (0xf << 8);//是GPXCON为外部中断功能
 

查看到使用外部中断功能的对应外部寄存器:EXT_INT43:


 51     //step 4: extern
 52     EXT_INT43CON = (2 << 8);//设置上升沿触发
 53     EXT_INT43MASK = 0;//使能中断
 

     

设置外部中断控制器:寄存器参考手册第366页
 55     //step 5: source
 56     外部中断源这里设置由外部按键K触发:


1 #include'regs.h'

  2 

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

  4 int(*delay)(int)=0xc3e25f90;

  5 

  6 void init_ttb(unsigned long *addr);

  7 void enable_mmu(void);

  8 unsigned long data_abort_init();

  9 void memcopy(unsigned long* dest,unsigned long* source,int len);

 10 void do_irq();

 11 void pwm_on(void);

 12 void pwm_off(void);

 13 void led_on(void);

 14 void led_on(void);

 15 

 16 int main()

 17 {

 18      *(unsigned long *)0x66000000 = do_irq;

 19 

 20     //发生异常时会进入异常模式跳转到0000 0004地址处理异常事件   

 21     unsigned long source_addr=data_abort_init();

 22     //异常事件处理函数

 23     printf('swi_souce addr is %xn',source_addr);

 24     //将异常处理地址的值放到0x60000004

 25     memcopy(0x60000000,source_addr,0x1000);

 26 

 27     enable_mmu();

 28     //内存映射将0x00000004映射到0x6000000004    

 29 

 30      //step 1: cpu cpsr

 31       __asm__ __volatile__(

 32           'mrs r0, cpsrn'

 33           'bic r0, r0, #0x80n'//设置CPSR的I位,将IRQ位打开

 34           'msr cpsr, r0n'

 35           ::: 'r0'

 36       );

 37 

 38     //setp1:GIC

 39     ICCICR_CPU0 = 1;

 40     ICCPMR_CPU0 = 0xff;

 41 

 42     //step1:设置中断号

 43     ICDDCR = 1;

 44     ICDIPR16_CPU0 = (0x0 << 0);//ICD第16个寄存器,第0位

 45     ICDIPTR16_CPU0 = (0x1 << 0);//优先级,最高

 46     ICDISER2_CPU0 = (1 << 0);//一共五个,第2个使能中断

 47 

 48     //step 3: set gpio

 49     GPX3CON = (0xf << 8);//是GPXCON为外部中断功能

 50 

 51     //step 4: extern

 52     EXT_INT43CON = (2 << 8);//设置上升沿触发

 53     EXT_INT43MASK = 0;//使能中断

 54 

 55     //step 5: source

 56     //

 57     printf('welcome back! n');

 58 }

 59 

 60 void pwm_on(void)

 61     {

 62         GPD0CON &= ~0xffff;

 63         GPD0CON |= 0x1;//配置寄存器为2

 64         GPD0DAT |= 0x1;//date=0xf

 65     }

 66 

 67 void pwm_off(void)

 68     {

 69         GPD0CON &= ~0xffff;

 70         GPD0CON |= 0x0;

 71     //  GPD0DAT &=0x0 ;//date=0xf

 72 

 73     }

 74 void led_off(void)

 75     {

 76         GPM4CON &= ~0xffff;//清零

 77         GPM4CON |= 0x0000;//0---3位清零

 78         GPM4DAT |= 0x0;//date=0xf关闭置一

 79     }

 80 void led_on(void)

 81     {

 82         GPM4CON &= ~0xffff;

 83         GPM4CON |= 0x1111;//配置寄存器3-0-----3-3全为1111,全为输出模式

 84         GPM4DAT &= ~0xf;//打开置0-4位为0000

 85     }

 86 

 87 void do_irq()

 88     {

 89             printf('key 1 downn');

 90             static int flag=1;

 91             if(flag)

 92             {

 93                 printf('wtc_onn');

  94                 led_on();

 95                 pwm_on();

 96                 flag=0;

 97             }

 98             else if(flag == 0)

 99             {

100                 printf('wtc_offn');

101                 led_off();

102                 pwm_off();

103                 flag=1;

104             }

105             EXT_INT43PEND = (1 << 2);//清中断

106     }

107 

108 void memcopy(unsigned long* dest, unsigned long* source,int len)

109 {

110     int i=0;;

111     for(i=0;i112         dest[i]=source[i];

113 }

114 

115 unsigned long  data_abort_init()

116 {

117     unsigned long source;

118     __asm__ __volatile__(

119          'ldr %0, =voliate_startn'

120          : '=r' (source)

121      );

122     return source;

123 

124 }

125 

126 __asm__(

127 

128 'voliate_start:n'

129     //跳转目录

130     ' b resetn'

131     ' b undefinedn'

132     ' b swin'

133     ' b pre_abtn'

134     ' b data_abtn'

135     ' .word 0n'//占位符号,一个位占4个字节

136     ' b irqn'

137     ' b fiqn'

138 'n'

139 

140     //跳转要分三部:

141     //1:将PC保存到新模式下的lr中;

142     //2:将CPSR保存在SPSR中

143     //3:初始化SP

144     //前两步由硬件完成,而第三部需要手动完成

145 'reset:n'

146 

147 'undefined:n'

148      'mov sp, #0x66000000n'//初始化SP

149      'stmfd sp!, {r0-r12, lr}n'//初始化sp,入栈保护寄存器 

150     //打印一句话 

151      'ldr r0, =und_stringn'

152      'ldr r2, shown'

153      'blx r2n'

154     //跳回来分两部

155     //1:将CPSR保存在SPSR中

156     //2:将PC保存到新模式下的lr中;

157      'mov sp, #0x66000000n'//

158      'ldmea sp, {r0-r12, pc}^n'// 

159 

160 'swi:n'

161 

162 'pre_abt:n'

163 'data_abt:n'

164      'sub lr, lr, #4n'

165      'mov sp, #0x66000000n'//初始化SP

166      'stmfd sp!, {r0-r12, lr}n'//初始化sp,入栈保护寄存器 

167     //打印一句话 

168      'ldr r0, =data_stringn'

169      'ldr r2, shown'

170      'blx r2n'

171     //跳回来分两部

172     //1:将CPSR保存在SPSR中

173     //2:将PC保存到新模式下的lr中;

174      'mov sp, #0x66000000n'//

175      'ldmea sp, {r0-r12, pc}^n'// 

176 

177 'irq:n'

178     'sub lr, lr, #4n'

179      'mov sp, #0x66000000n'//初始化SP

180      'stmfd sp!, {r0-r12, lr}n'//初始化sp,入栈保护寄存器 

181     //打印一句话 

182      'mov r2, #0x66000000n'

183      'ldr r1, [r2]n'

184      'blx r1n'

185 

186     'mov sp, #0x66000000n'//

187      'ldmea sp, {r0-r12, pc}^n'//

188 'fiq:n'

189     'show:n'

190      '.word 0xc3e114d8n'

191 

192     'und_string:n'

193      '.asciz 'This is  UND! ' n'

194      'data_string:n'

195      '.asciz 'This DATA_ABORT! ' n'

196      'irq_string:n'

197      '.asciz 'This IRQ! ' n'

198 

199         );

200 

201 void init_ttb(unsigned long *addr)

202 {

203     unsigned long va = 0;//定义虚拟地址

204     unsigned long pa = 0;//定义物理地址

205 

206     //40000000-------80000000   ====  40000000------80000000

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>