Chinaunix首页 | 论坛 | 博客
  • 博客访问: 97797
  • 博文数量: 24
  • 博客积分: 431
  • 博客等级: 一等列兵
  • 技术积分: 245
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-24 09:44
文章分类
文章存档

2013年(1)

2012年(23)

分类: 嵌入式

2012-11-01 17:05:45

1.正确识别中断源,根据中断类型初始化中断
   虽然中断源很多,但是不外乎以下两种类型:
   A.该类中断有很多子中断,如UART0,有发送中断,接收中断和错误中断3个子中断。
   B.该类中断没有子中断,如外部中断0.
   对于第一类型的中断,初始化时需要将总中断屏蔽位置为无效,同时还需要将子中断屏蔽位也置为无效。
   对于第二类型中断,由于没有子中断,因此,只需要将总中断屏蔽位置为无效即可。
   例如:初始化UART0的接收中断和发送中断,可使用如下代码实现。
   rINTMSK  &=~(1<<28);
   rINTSUBMSK &=~((1<<0)|(1<<1)); 首先将UART0总中断屏蔽位置为无效,然后将发送中断和接收中断屏蔽位置为无效。
   初始化定时器0中断,可以使用如下代码。
   rINTMSK &=~(1<<10); 只需要将定时器0的中断屏蔽位置为无效即可。
2.编写中断处理函数
  编写中断处理函数时需要使用关键字__irq。这样,在编译阶段,编译器会自动生成中断现场的保护和恢复时所需要的代码,用户只需要关注对具体中断的处理即可。
  中断处理函数中需要将中断标志清除,方法是想相应的中断标志位写1即可。
  对于第一种类型的中断,需要清除SRCPND、INTPND寄存器中相应的中断标志位,还需要清除SUBSRCPND中断相应的中断标志位。
  对于第二种类型的中断,只需要清除SRCPND、INRPND寄存器中相应的中断标志位即可。
  例:清除UART0发送中断标志和接收中断标志,可以使用如下代码实现。
  1. void __irq Uart0)_Ist(void)
  2. {
  3.    if(rSUBSRCPND&(1<<0)) //进一步判断是接收中断
  4.    {
  5.      …… //在此处进行相应的中断处理
  6.      
  7.      rSUBSRCPND |=1<<0; //清除接收中断
  8.    }
  9.    if(rSUBSRCPND&(1<<1)) //进一步判断是发送中断
  10.     {
  11.        …… //在此处进行相应的中断处理
  12.      
  13.         rSUBSRCPND |=1<<1; //清除发送中断
  14.     }
  15.    rSRCPND |=1<<28;//清除UART0总中断
  16.     rINTPND |=1<<28;
  17. }
      清除定时器0中断标志。
  1. void __irq Timer0_Isr(void)
  2. {
  3.    …… //在此处进行相应的中断处理
  4.      
  5.     rSRCPND |=1<<10;
  6.    rINTPND |=1<<10;
  7. }
3.安装中断处理函数
  因为在启动代码阶段寂静在内存中定义好了中断向量表,所以安装中断处理函数只需要将中断处理函数地址写入中断向量表的对于地址即可。在启动代码里,使用MAP和FIELD定义了第2级中断向量表。
  在汇编语言中,标号代表的是地址。因此,HandEINT0与0x33FFFF20是等价的。现在的问题是,如何将中断函数的地址写入到中断向量表中对应的地址处呢?
 在2440addr.h文件中,使用define定义的指针,指向这些地址处。这里的__ISR_STARTADDRESS=0x33FFFF00
 因此会有如:
   #define pISR_EINT0   (*(unsigned *)(_ISR_STARTADDRESS 0x20)
   #define pISR_Timer0  (*(unsigned *)(_ISR_STARTADDRESS 0x48)
   相当于 
   #define pISR_Timer0  (*(unsigned *)(0x33FFFF48))这里(unsigned *)修饰,表示将0x33FFFF48强制转换为一个地址指针,即指向内存中0x33FFFF48处,准确地说,是指向内存中从0x33FFFF48开始的连续4个字节的内存片中(48~4B)。然后前面再加个*,这里的*是指针运算符(也叫减价访问运算符),表示去该内存单元的数据。
    因此在程序中,可以看到下面的语句void Isr_Int(void)中:
    pISR_TIMER0=(unsigned int)Timer0_Isr.
 上述相当于(*(unsigned *)(0x33FFFF48))=(unsigned int)Timer0_Isr。Timer0_Isr是定时器0中断函数的入口地址,也叫函数地址,因为每个函数入口地址占4个字节,因此使用了强制转换,其实就是想内存单元0x33FFFF48中写入定时器0中断函数的入口地址。unsigned int占四个字节。
    到此,中断函数入口已经顺利添加到中断向量表的对应地址处。
4.软中断,通俗地说是为了从其他工作模式切换到管理模式(在管理模式,可以使用的资源更多),处理器提供软中断,主要是为了支持操作系统的系统功能调用,在一般应用中很少使用到软中断,当然在移植uC/OS-II操作系统时可以使用软中断来实现任务的切换。启动代码主要工作在管理模式,所以发生软中断时,并没有发生处理器工作模式的切换。
  
阅读(1823) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~