Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1166273
  • 博文数量: 173
  • 博客积分: 4048
  • 博客等级:
  • 技术积分: 2679
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-12 18:53
文章分类

全部博文(173)

文章存档

2018年(1)

2016年(1)

2013年(1)

2012年(118)

2011年(52)

分类: 嵌入式

2011-03-29 19:50:04

主要参考http://blog.ednchina.com/summerooooo/1770874/message.aspx

在本例中不通过pio,直接自定义外设控制irq信号,实现中断处理。

硬件部分:
自定义一个简单的键盘控制器,按下FPGA板上的键盘就产生irq中断信号。
其源代码如下:
  1. module buttoncontroller(buttonin,clk,reset_n,chipselect,address,read,write,readdata,writedata,byteenable,irq);
  2. input buttonin,clk,reset_n,byteenable,chipselect,read,write;
  3. input address;
  4. input [31:0] writedata;
  5. output [31:0] readdata;
  6. output irq;

  7. reg buttonin_0,buttonpush,irq;

  8. initial
  9. begin
  10. irq=0;
  11. end

  12. always@(posedge clk)
  13. begin
  14. buttonin_0=buttonin;
  15. end

  16. always@(posedge clk)
  17. begin
  18. if(buttonin_0 && !buttonin)
  19. buttonpush=1;
  20. else
  21. buttonpush=0;
  22. end

  23. always@(posedge clk)
  24. begin
  25. if(chipselect && write && address==0)
  26. irq=0;
  27. else if(buttonpush)
  28. irq=1;

  29. end

  30. endmodule
在上述代码中,只要按下按键,buttonin则为0。buttonpush产生一个周期的高电平,表示按下一次按键。此时irq被置1。但当进入中断处理程序时,会对控制器发出写请求以使irq清0。
对irq清0是非常重要的,因为irq的持续周期不好确定。如果太长会使cpu一直在处理中断。而如果太短则可能不会触发中断处理程序。因此本例中使用的方法是在进入中断处理程序后,对控制器发出写请求以使irq清0。
进入sopc builder后在自己的系统中加入自定义的外设。

其中各信号类型设置如下:

信号接口如下:

最后完整的sopc系统如图:
绑定管脚后编译即完成了硬件系统。

软件系统:
软件代码如下:
  1. #include <stdio.h>
  2. #include <io.h>
  3. #include "system.h"
  4. #include "alt_types.h"
  5. #include "sys/alt_irq.h"

  6. void button_isr(void* context, alt_u32 id)
  7. {
  8.     IOWR(BUTTONCONTROLLER_0_BASE,0,0);
  9.     printf("you have pushed %d times\n",++(*((int *)context)));  
  10.              //最好还是不要在中断处理程序里使用printf这样的不可重入函数
  11. }

  12. int main()
  13. {
  14.   volatile int i=0;
  15.   alt_irq_init(ALT_IRQ_BASE);
  16.   if(!alt_irq_register(BUTTONCONTROLLER_0_IRQ,&i,button_isr))
  17.     printf("the irq is set\n");
  18.   printf("oh yeah\n");
  19.   while(1);
  20.   return 0;
  21. }
注意在中断处理程序中:
1,如果使用变量,变量类型必须为volatile。确保每次都从内存中获得该变量值。
2,不能使用printf这样的不可重入的函数,否则可能死锁。

编译运行后,按下按键则产生如下结果:

使用signal tap捕捉到的按下按键时的信号如下:
阅读(4277) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~