引子

定时器中断,我以前在艾米电子论坛发帖讨论过;PIO中断我在博客里也讨论过,最近发现以前的总结有一点小错误。于是结合我最近玩触摸屏的一点点心得,写篇博文。

软硬件环境

硬件:艾米电子EP2C8核心板+2.4’ TFT套件

软件:Altera Quartus II 10.0  +  Nios II 10.0  Software Build Tools for Eclipse

内容

1 PIO中断

此处以ADS的nIRQ引脚为例。

1.1 在SOPC Builder中例化PIO

图1.1 例化PIO核

图1.2 Basic Setting

图1.3 Input Option

在ADS7843中,当用触摸笔触摸到TFT时,nIRQ引脚会拉低,因此我们可以检测nIRQ引脚的边沿,当为下降沿的时候,产生中断。查看手册Embedded Peripherals IP User Guide中的PIO一节,阅读相关片段。根据图1.4和1.5的描述,对nIRQ的PIO的输入选项的设置如图1.3所示。只需配置图1.2和图1.3所指的选项,其他选项缺省设置即可。

图1.4 Capture功用

图1.5 IRQ Generation功用

1.2 PIO中断的C代码

#include "system.h"                   // 系统
#include "altera_avalon_pio_regs.h"   // PIO,ads_nIRQ
#include "sys/alt_irq.h"              // 中断
//
unsigned int nirq_isr_context; // 定义全局变量以储存isr_context指针
void nIRQ_Initial(void);
void nIRQ_ISR(void* isr_context);
//
int main(void)
{nIRQ_Initial(); // 初始化PIO中断while(1){}
}
// nIRQ中断初始化
void nIRQ_Initial(void)
{// 改写timer_isr_context指针以匹配alt_irq_register()函数原型void* isr_context_ptr = (void*) &nirq_isr_context;IOWR_ALTERA_AVALON_PIO_IRQ_MASK(ADS_NIRQ_BASE, 1); // 使能中断IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器// 注册ISRalt_ic_isr_register(ADS_NIRQ_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从system.h复制ADS_NIRQ_IRQ,     // 硬件中断号,从system.h复制nIRQ_ISR,         // 中断服务子函数isr_context_ptr,  // 指向与设备驱动实例相关的数据结构体0x0);             // flags,保留未用
}
// 中断服务子函数
void nIRQ_ISR(void* nirq_isr_context)
{IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器// 用户中断代码
}

以第21行为例,使能中断和清清中断边沿捕获寄存器都是按位操作的。此处nIRQ引脚为1位,因此所写的值为0或1。

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(ADS_NIRQ_BASE, 1); // 使能中断

倘若是总线,比方说4位,那么使能的话,就应该如下操作。对其他寄存器的操作也是类似的。

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUS_4_BASE, 0xF); // 使能中断

同时需要注意若是在SOPC Builder中选择了enable bit-clearing for edge capture register的话,那么对于edge capture就应该是写1清中断;若是没有选择enable bit-clearing for edge capture register,则是写任意数清中断。(由韩彬总结)

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(ADS_NIRQ_BASE, 1); // 清中断边沿捕获寄存器

若是总线,便与上面类似。

在清中断这一点上,我们可以总结一下:arm和mips类的nios是写1清中断;而51单片机是写0清中断。

注意:
1 中断服务代码区不要使用printf(),否则会严重阻塞中断。
2 如果需要中断服务子函数传参,那么参数必须转为空类型。且所传参数为16位的全局变量。
3 9.1版本的以后的中断注册写法有两种,此处示范为增强版的中断注册写法。

2 定时器中断

此处以high_res_timer为例。

2.1 在SOPC Builder中例化Timer

图2.1 例化Interval Timer核

图2.2 配置Timer counter size和Hardware option

查看手册Embedded Peripherals IP User Guide中的Interval Timer核一节,阅读相关片段。参考图2.3和2.4的描述,配置为32位的全功能定时器(当然也可以配置为64位定时器,但是后面的软件需要稍微修改)。只需配置图2.2,其他选项缺省设置即可。

图2.3 Counter Size功用

图2.4 Hardware Options功用

2.2 定时器中断的C代码

#include "system.h"                   // 系统
#include "altera_avalon_timer_regs.h" // 定时器
#include "sys/alt_irq.h"              // 中断
//
unsigned int timer_isr_context; // 定义全局变量以储存isr_context指针
void Timer_Initial(void);
void Timer_ISR(void* isr_context);
//
int main(void)
{Timer_Initial(); // 初始化定时器中断while(1){}
}
// 定时器中断初始化
void Timer_Initial(void)
{// 改写timer_isr_context指针以匹配alt_irq_register()函数原型void* isr_context_ptr = (void*) &timer_isr_context;// 设置PERIOD寄存器// PERIODH << 16 | PERIODL = 计数器周期因子 * 系统时钟频率因子 - 1// PERIODH << 16 | PERIODL = 5m*100M - 1 = 499999 = 0x7A11FIOWR_ALTERA_AVALON_TIMER_PERIODH(HIGH_RES_TIMER_BASE, 0x0007);IOWR_ALTERA_AVALON_TIMER_PERIODL(HIGH_RES_TIMER_BASE, 0xA11F);// 设置CONTROL寄存器//    位数 |  3   |  2   |  1   |  0  |// CONTROL | STOP | START| CONT | ITO |// ITO   1,产生IRO;                      0,不产生IRQ// CONT  1,计数器连续运行直到STOP被置一;   0,计数到0停止// START 1,计数器开始运行;                0,无影响// STOP  1,计数器停止运行;                0,无影响IOWR_ALTERA_AVALON_TIMER_CONTROL(HIGH_RES_TIMER_BASE,ALTERA_AVALON_TIMER_CONTROL_START_MSK | // START = 1ALTERA_AVALON_TIMER_CONTROL_CONT_MSK  | // CONT  = 1ALTERA_AVALON_TIMER_CONTROL_ITO_MSK);   // ITO   = 1// 注册定时器中断alt_ic_isr_register(HIGH_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID, // 中断控制器标号,从system.h复制HIGH_RES_TIMER_IRQ,     // 硬件中断号,从system.h复制Timer_ISR,              // 中断服务子函数isr_context_ptr,        // 指向与设备驱动实例相关的数据结构体0x0);                   // flags,保留未用
}
// 定时器中断服务子函数
void Timer_ISR(void* timer_isr_context)
{// 应答中断,将STATUS寄存器清零IOWR_ALTERA_AVALON_TIMER_STATUS(HIGH_RES_TIMER_BASE,~ ALTERA_AVALON_TIMER_STATUS_TO_MSK);   // TO = 0// 用户中断代码
}

图2.3 32位的Interval Timer核的寄存器结构。

查看手册Embedded Peripherals IP User Guide中的Interval Timer核一节,阅读相关片段。参考图2.3,设置寄存器。此处以5ms为例,系统时钟为100Mhz。之所以还要减去1,是因为从0开始计数的。关于其他寄存器的功用,请参阅手册的相关片段。

  // 设置PERIOD寄存器// PERIODH << 16 | PERIODL = 计数器周期因子 * 系统时钟频率因子 - 1// PERIODH << 16 | PERIODL = 5m*100M - 1 = 499999 = 0x7A11FIOWR_ALTERA_AVALON_TIMER_PERIODH(HIGH_RES_TIMER_BASE, 0x0007);IOWR_ALTERA_AVALON_TIMER_PERIODL(HIGH_RES_TIMER_BASE, 0xA11F);

与PIO注意事项类似。
注意:
1 中断服务代码区不要使用printf(),否则会严重阻塞中断。
2 如果需要中断服务子函数传参,那么参数必须转为空类型。且所传参数为16位的全局变量。
3 9.1版本的以后的中断注册写法有两种,此处示范为增强版的中断注册写法。

3 一点心得

Nios II的中断操作基本类似。今后我会写点其他IP和自定义IP里面的中断如何使用。

Embedded Peripherals IP User Guide提供了很多IP核的功能和用法说明,是学习Nios II的红宝书。关于Nios II软件编程的更多细节,可以参阅Nios II Software Developer's Handbook;关于Nios II软核的更多细节,可以参阅Nios II Processor Reference Handbook。如果你有一些解决不了的问题,可以去alterafoum.com检索相关关键字,很多时候是可以找到前人的经验和答案的。

另见

[笔记].Nios II 9.1的sys/alt_irq.h与之前版本的区别.[Nios II]

参考

Altera.Embedded Peripherals IP User Guide

转载于:https://www.cnblogs.com/yuphone/archive/2010/11/25/1887621.html

[笔记].如何使用Nios II的中断:PIO中断与定时器中断相关推荐

  1. [笔记].浅析在Nios II中的两种寄存器映射方法的异同

    此处以我所写的MAX7219为范例,从HDL接口描述到C语言软件编程,分析两种表面不一样.但实质是一样的寄存器映射方法,找出其中联系与区别. 方法1 使用Altera提供的API 1. 使用HDL描述 ...

  2. 51C语言中断LED闪烁,单片机定时器中断实现LED灯闪烁程序

    运用定时器0工作在方式1(16位计数器)实现LED灯的闪烁.先来看看定时器0工作在方式1的逻辑结构图. 从上图可以看到,GATE先经过非门,再和INT0引脚作为或门的输入.这里简单提一下数字电路中的与 ...

  3. 定时器中断程序 c语言,定时器中断函数的使用

    1.定时器与延时的区别 大家可能会觉得我们用延时函数照样可以实现上一讲代码的实验现象,但是定时器与延时的概念不同,延时函数需要占用CPU的使用权,正在延时的时候其他任务没有CPU的使用权就会拖慢执行效 ...

  4. [原创].关于编写Nios II的延时函数的一点心得

    平台 硬件:nios/f 100MHz 软件: 内容 0 一点说明 本文仅讨论所述平台的一点心得,若其他等级的nios或优化,请自行研究. 1 usleep()有多准 参考[笔记].怎样使用Nios ...

  5. 51单片机学习笔记(郭天祥版)(3)——引脚讲解、数码管静态显示、中断系统(外部中断,定时器中断)...

    学习引脚的功能 9引脚 复位管脚,当给2个机器周期(24个时钟振荡周期)的高电平时会复位,单片机正常工作时会给0.5v的低电平 VPD备用电源的输入端,当主电源VCC发生故障降低到某一规定的低电平时, ...

  6. STM32定时器中断实验-学习笔记

    目录 目录 目录 通用定时器简介 寄存器 控制寄存器 (TIMx_CR1) DMA/中断使能寄存器(TIMx_DIER) 预分频寄存器(TIMx_PSC) TIMx_CNT 寄存器 自动重装载寄存器( ...

  7. RT1064学习笔记-PIT定时器中断

    RT1064 周期中断定时器简介 PIT模块是一组计时器,可用于引发中断和触发DMA通道. PIT定时器框图如下图所示: PIT定时器内部有4个计数器(Timer0~Timer3) PIT定时器功能包 ...

  8. 快速复习51单片机的外部中断、计数/定时器中断和串行口中断,加代码实现

    目录 1.中断系统的概念 1.1中断的概念 1.2中断系统的概念 1.3中断系统的优点 1.4我们要说的三种中断源 2.外部中断 2.1 外部中断0 代码示范 2.2 外部中断 分析 3.计数/定时器 ...

  9. STC10F10XE定时器中断输出10KHz的方波程序

    //咱做硬件的也动手做点测试程序,为了测试新做的电机驱动板,找了个51的板子当10K信号发生器测试IGBT开关延时时间. #include <STC_NEW_8051.H> #includ ...

最新文章

  1. [转]C#日期格式化 文档
  2. 看看专科程序员与本科程序员之间,到底有什么区别?
  3. C#程序如何对接比特币钱包节点?
  4. php reids的geo功能,Redis GEO相关命令和功能,你造吗?
  5. matplot 绘图总结
  6. 运维监控工具之 Nagios 客户端安装(二)
  7. 基于Qt\C++实现的网络远程控制系统
  8. JavaScript使用技巧精萃 经典代码收藏版
  9. 请教大家:如何把.DCU文件反编译回源代码?谢谢。
  10. 一步步编写操作系统 32 linux内核获取内存容量的方法
  11. 一键离线下载python安装包:
  12. linux swap 分区调控(swap分区 lvm管理)
  13. 细胞增殖曲线_高中生物高分技巧13-细胞增殖
  14. php增加会员功能_在帝国CMS后台增加手动添加会员功能
  15. c语言小型编译器编写,小型C语言编译器设计(4页)-原创力文档
  16. matlab编辑器风格定制,怎么使用135编辑器编辑出文艺清新的风格排版(附文艺排版素材)?...
  17. 银行登录页面html代码,银行管理系统(带界面)
  18. 9.5 预测市场和真实世界的数据源
  19. 创业起步 中小型网吧的组建解决方案(转)
  20. CTFshow之36Dweb做题记录

热门文章

  1. Codeforces Round #Pi (Div. 2)(A,B,C,D)
  2. 前端应该了解的颜色的寓意
  3. python经典问题在stack overflow上的回答
  4. ThinkPHP 模板循环输出 Volist 标签
  5. 深入理解Java Proxy和CGLIB动态代理原理
  6. IBM整合管理服务:云时代驱动IT服务创新
  7. 《 自动化测试最佳实践:来自全球的经典自动化测试案例解析》一一2.4 开发内部测试工具...
  8. 数据不能产生价值都是耍流氓
  9. mxGraph改变图形大小重置overlay位置
  10. SQLServer 扫盲