[X]关闭

Mis603开发板MB SOC开发教程:第五章 系统定时器中断

文档创建者:Milinker_XU
浏览次数:4645
最后更新:2016-01-12
本帖最后由 Milinker_XU 于 2016-1-12 21:48 编辑

    我们在前几章遇到延时,通常的做法是直接写个延时函数,但这样延时的时间其实是非常不精确的。那么如何在MB系统中,做出精准的延时呢。这一章我们通过定时器中断的方法来实现。首先得清楚,这里的定时器,是硬件系统提供的一个稳定的计数源。当定时器启动时,通过累加或累减的方式,当定时器的存储值溢出时,定时器就产生一个使能信号,MB系统由此产生定时中断,响应该信号。
◎紧接上一章的工程,在XPS中添加一个定时控制器。在弹出窗口中,将Only one Timer is present选中。关于IP的详细信息,xilinx公司在每个ip的窗口右上方的pdf文件来查看。
◎将该定时器与MB系统连接,修改定时器名称为,此时timer_0挂到了axi4lite总线下。
◎再添加一个中断控制器。该ip保持默认即可,将ip名称改为intc_0。同样,该ip自动添加到MB系统,通过axi4lite总线连接。
◎在MB系统中,将MB系统的中断和中断控制器相连。
◎在Ports端口中,为中断控制器添加中断信号源。点击intc_0下面的intr,单击即可。
◎从弹出对话框中,设置中断源为timer_0。
◎保存XPS文件后,点击Hardware->Generate Bitstream,产生bit文件。

◎启动SDK,新建个TIMER_INTR工程,选择Helloworld为模板,程序将在helloworld.c文件中编写。
◎将helloworld.c文件改成intr.c文件(备注:也可以自己新建文件,然后搭建个MB软件系统,但通常我习惯直接建个helloworld模板在上面做修改)。
◎初学者这时候就纠结了,做好了硬件平台,软件平台也搭建好了,那么如何写个定时器中断程序呢。这章我们来详细理解下各个头文件和BSP文件包的应用。

◎首先我们看看BSP包里面的头文件,在include文件夹下面,包含了一对乱起八糟的头文件。如下图所示。通常只有对具体的应用时,才查看对应的头文件。
◎本章节中,我们采用定时器定时,当定时器到达指定时间时,产生中断,MB系统在响应改中断后,通知外设该干嘛。这里,我们以LED来做测试,当MB系统开起定时器中断,定时器计时达到1s时,中断控制器通知MB系统,MB系统响应后,告知LED灯闪烁一次。基本示意图如下所示。
◎搞明白上面的流程图之后,我们需要的外设也就出来了,那么程序中所要用到的头文件也就清晰了。包括:
#include "xparameters.h"  MB参数:包含外设的地址、状态标志以及中断向量号等
#include "xgpio.h"         外设GPIOIO初始化、如何往指定IO寄存器读写等、IO中断使能等
#include "xintc.h"         中断控制器:包括中断如何初始化、中断开始、中断枚举等
#include "xtmrctr.h"       定时器:定时器初始化、开始、启动、定时器状态函数等
#include "mb_interface.h" MB接口:MB接口同其他外设接口,包括硬件开中断、异常、启动指令缓存等
#include "platform.h"     MB系统的指令、数据缓存使能,MB系统平台初始化,作用其实不大
◎我们再定义几个文件。1.定义一个中断开启和设置的文件set_intc.c;2.定义一个中断响应文件,即中断处理程序文件handler_intc.c;3.包含各个文件中函数的头文件intc.h。

◎在set_intc.c文件中,对定时器0中断进行注册,开启中断并设置定时器开始计算值,产生中断信号。
  
#include "intc.h"                   //包含中断intc.h头文件
  
void set_intc(void)
  
{
  
    //注册定时器0中断,中断处理函数到中断控制器,中断处理函数入口
  
    XIntc_RegisterHandler(XPAR_INTC_0_BASEADDR,  XPAR_INTC_0_TMRCTR_0_VEC_ID,              
  
(XInterruptHandler) timer_int_handler, (void  *)XPAR_TIMER_0_BASEADDR);
  
    //开启MB系统中断使能
  
    microblaze_enable_interrupts();            
  
    //启动所有中断寄存器控制器
  
    XIntc_MasterEnable(XPAR_INTC_0_BASEADDR);                                      
  
    //使能定时器0中断
  
    XIntc_EnableIntr(XPAR_INTC_0_BASEADDR,  XPAR_TIMER_0_INTERRUPT_MASK);      
  
    //设置定时器,主频100Mhz,周期10ns1s1000000000/10=100000000
  
    XTmrCtr_SetLoadReg(XPAR_TIMER_0_BASEADDR,  0, 100000000);      
  
    //使能定时器0产生中断信号
  
    XTmrCtr_EnableIntr(XPAR_TIMER_0_BASEADDR,  0);               
  
   
  
    //设置定时器控制状态寄存器
  
    XTmrCtr_SetControlStatusReg(XPAR_TIMER_0_BASEADDR,  0, XTC_CSR_ENABLE_TMR_MASK |
  
                                                          XTC_CSR_ENABLE_INT_MASK  |
  
                                                         XTC_CSR_AUTO_RELOAD_MASK |
  
                                                         XTC_CSR_DOWN_COUNT_MASK);
  
}
  
[/table]
◎中断处理函数中,读取定时器控制状态寄存器,判断是否有中断产生,如果有,则led灯移位一次。
  
/*
  
* handler.c
  
*
  
*   Created on: 2016-1-12
  
*       Author: Administrator
  
*/
  
  
#include  "intc.h"
  
/**************************  interrupt handler process****************************/
  
  
void  timer_intc_handler(void * baseaddr_p)
  
{
  
    unsigned int rcs;
  
    //读取定时器控制状态寄存器
  
    rcs = XTmrCtr_GetControlStatusReg(XPAR_TIMER_0_BASEADDR,0);
  
    //判断有中断产生,若有,led左移一位
  
    if(rcs & XTC_CSR_INT_OCCURED_MASK)      // if interrupt is occurred
  
    {
  
        led<<=1;
  
    }
  
    //清除定时器控制状态寄存器
  
    XTmrCtr_SetControlStatusReg(XPAR_TIMER_0_BASEADDR,0,  rcs);   
  
}
  

◎在intc.h中,做了函数和全局变量的声明,还包括所需头文件的声明。
  
/*
  
* intc.h
  
*
  
*   Created on: 2016-1-12
  
*       Author: Administrator
  
*/
  
  
#ifndef INTC_H_
  
#define INTC_H_
  
  
#include  "xparameters.h"
  
#include  "xgpio.h"
  
#include  "xintc.h"
  
#include  "xtmrctr.h"
  
#include  "mb_interface.h"
  
#include  "platform.h"
  
  
extern unsigned int  led;
  
void  set_timer_intc(void);
  
void  timer_intc_handler(void * baseaddr_p);
  
  
#endif /* INTC_H_ */
  
◎主函数中,调用中断设置函数,定义了个全局变量led,led通过mis603开发板上的灯显示。可以看出,每秒led灯移位一次。寄存器初始值的改变,将会是led状态发送变化。
◎这样,关于定时器中断的例子就到此结束了。中断是单片机系统中使用非常多的,在描述中断处理函数时,要确保函数处理简单,简洁,复杂的程序,可以在其他调用程序或主函数中进行。




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

发表评论已发布 1

uisrc

发表于 2016-1-12 22:01:36 | 显示全部楼层

越努力越幸运!加油!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则