4299|5

76

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

求高手点拨:ARMulator 中如何使用定时器? [复制链接]


求高手点拨:ARMulator 中如何使用定时器?  

我按照《ADS_DEBUGTARGETGUIDE_D.PDF》写了 Timer1 的初始化函数,但是不知道怎样关联中断处理函数了。请高手点拨,呵呵:

#define CLK           20000000
#define TimerBase     0x0a800000
#define Timer1Load    (*((volatile unsigned long *)(TimerBase)))
#define Timer1Value   (*((volatile unsigned long *)(TimerBase + 0x04)))
#define Timer1Control (*((volatile unsigned long *)(TimerBase + 0x08)))
#define Timer1Clear   (*((volatile unsigned long *)(TimerBase + 0x0C)))

Timer1Load = CLK/OS_TICKS_PER_SEC;
Timer1Control = 0x00000000;
Timer1Control  ?= 0xC0;
此帖出自ARM技术论坛

最新回复

我的写完了,你看看吧 /****************************************************************************************/ /*  NAME:   test.c                                                                      */ /*  DESC:   test doby through I/O Port with timer interrupt(1s).                        */ /*  Date:   06.18.2008                                                                  */ /*  version:    0.0                                                                     */ /*  Program:    Shen Hui (Shh)                                                          */ /****************************************************************************************/ /*  程序主要演示怎样使用armulator的定时器中断.输入也可以不在程序中赋值,直接在内存中改  */ /*  关键的地方在:                                                                       */ /*  1>.要打开中断.                                                                      */ /*  2>.要更改IRQ的服务程序.                                                             */ /*  3>.'服务程序'必须离'矢量'在32MB范围内.即25位地址.                                   */ /*  4>.无中断矢量初始化程序(无.s文件),只设置了IRQ.                                      */ /*  5>.目标CPU必须与调试器一致(例如,同是arm920T).                                       */ /*  6>.MMU/PU initialization Pagetab必须设置为NO_PAGERABLES,否则映射不对                */ /****************************************************************************************/ /*Input:                                                                                */ /*  0805ff01: D0-start  h active                                                        */ /*  0805ff02: D0-stop   l active                                                        */ /*Output:                                                                               */ /*  0805ff0d: D0-doby1  l active            0805ff0e:   D0-doby1    l active            */ /*            D1-doby1  l active                        D1-doby1    l active            */ /*            D2-doby1  l active                        D2-doby1    l active            */ /*            D3-doby1  l active                        D3-doby1    l active            */ /*            D4-doby1  l active                        D4-doby1    l active            */ /*            D5-doby1  l active                        D5-doby1    l active            */ /*            D6-doby1  l active                        D6-doby1    l active            */ /*            D7-doby1  l active                        D7-doby1    l active            */ /****************************************************************************************/ #include "test.h" void itoa2(unsigned short n, unsigned char *str) {//not find itoa in stdlib.h     int i=0;     int swap;     do     {         str=n%2+'0';         i++;         }while(n/=2);     str[i--]='\0';     for(n=0; n>2);     if (vec & 0xff000000)     {         printf ("Installation of Handler failed");         exit(1);     }     vec = 0xea000000 | vec;//EA=     oldvec = *vector;     *vector = vec;     return (oldvec); }/* ************************************************** */ /* 打开或关闭中断                                     */ /* 通过读 cpsr 标记然后更新第7位来打开或关闭中断      */ /* 这些函数只能用于 privileged 模式,因为cpsr和spsr的  */ /* 控制位在用户模式下不能改变.                        */ /* ************************************************** */ __inline void enable_IRQ(void) {     int tmp;     __asm     {         MRS tmp, CPSR         BIC tmp, tmp, #0x80         MSR CPSR_c, tmp     } } // __inline void disable_IRQ(void) {     int tmp;     __asm     {         MRS tmp, CPSR         ORR tmp, tmp, #0x80         MSR CPSR_c, tmp     } }// 如果目标为920T则要清除所有中断捕获! int main(void) {     unsigned short  Mask=1;     unsigned char *str;         DOBYINPUT0_7=0xff;     DOBYINPUT8_F=0xff;     //  itoa2(0x1234,str ); //  printf("str %s\n",str);         printf("Timer Interrupt\n");     //未安装前   00000018       [0xe7ff0010]   dci      0xe7ff0010 ; ? undefined //使地址(IRQ)00000018处为:  [0xea002022]  * b  IRQ_Handler     Install_Handler ((unsigned)IRQ_Handler, irqvec);         printf("Normal (RAM at 0x8000, semihosting) version\n\n");     printf("Initializing...\n"); //     enable_IRQ();    IRQEnableClear = ~0;      // 清除所有的中断         Timer1Control = 0;        // 通过控制位关闭计数器     Timer1Clear = 0 ;         // 通过写任何值到'清除'清除寄存器来清除中断     Timer1Load = 2000;        // 装计数器值,可通过晶频计算,这里2000只是为了测试     Timer1Control = (TimerEnable | TimerPeriodic | TimerPrescale8 );         IRQEnableSet = IRQTimer1;     printf("Running...\n");    IntCT1 = 0;          // 清 CT1 标记           while (START)     {         if(STOP) break;         if (IntCT1 != 0)        // 定时器1产生中断         {             IntCT1 = 0;         // 复位定时器1中断标记             DOBYOUTPUT0_7 = (~Mask) & 0xFF;             DOBYOUTPUT8_F =((~Mask) & 0xFF00)>>8;             itoa2(Mask,str);             printf("%016s\n",str);             Mask  详情 回复 发表于 2008-6-24 21:40
点赞 关注
 

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我不清楚你的寄存器,总之是往一个寄存器里(Timer Match Registers)写初值,当Timer Counter  register的
值与它相等时产生中断,在Timer Status register寄存器可以找到中断位.
此帖出自ARM技术论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
贴给你Timer的ARMulate实现代码。自己翻翻。

没时间给你找了。



/*
Function Name: Timer1Timeout.
Parameters: void *handle - This is void * because we are re-using the
                        armul_Event typedef for pointers to event functions
                        and this specified that a void* is used instead
                        of a specific type.
Return: unsigned - always return 0;
Description: This function is registered as the function to call when timer 1
                times out.

Notes:  Note that we check that the intcInterface has been installed correctly
        by MemInit - if it hasn't then we do a late installation.
        The check is prudent for pointers to functions/handles.
        The late installation is an alternative to bombing out - this
        is really a protection against user who don't read the documentation
        and ignore the warnings that intc MUST be the first peripheral
        in the peripheral list in armul.cnf. - or for users who have simply
        left out the intc from their armul.cnf.  These checks could be removed
        to slightly improve performace for very timer intensive systems.
*/
static void Timer1Timeout(void *handle)
{
    TimerState *ts = (TimerState*)handle;
    timer_state *myTimer = &ts->timer1;
   
#ifdef VERBOSE_TIMEOUT
    printf("Timer:1:Timeout.\n");
#endif
        myTimer->timedCallback = NULL;
    /* Check that we have the intc interface installed */
    if (iCheckIntcIf(ts))
    {
#ifdef VERBOSE_NOINTC
        printf("Timer:1: no interrupt controller available.\n");
#endif
        return;
    }
    {
        GenericAccessCallback *cb1 = *ts->intcInterface;
        ARMword data = 1;
        cb1->func(cb1,myTimer->interruptNumber,&data,ACCESS_WRITE_WORD);
    }
   
    /* See if the timer should be restarted - and if so in what mode */
    RunTimerAgain( ts, myTimer);
}


/* See TimerTimeout for function comment block */
static void Timer2Timeout(void *handle)
{
    TimerState *ts = (TimerState*)handle;
    timer_state *myTimer = &ts->timer2;

#ifdef VERBOSE_TIMEOUT
    printf("Timer:2:Timeout.\n");
#endif
        myTimer->timedCallback = NULL;
    /* Check that we have the intc interface installed */
    if (iCheckIntcIf(ts))
    {
#ifdef VERBOSE_NOINTC
        printf("Timer:2: no interrupt controller available.\n");
#endif
        return;
    }
    {
        GenericAccessCallback *cb1 = *ts->intcInterface;
        ARMword data = 1;
        cb1->func(cb1,myTimer->interruptNumber,&data,ACCESS_WRITE_WORD);
    }
    RunTimerAgain( ts,  myTimer);
}

此帖出自ARM技术论坛
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

4
 
feng_me,
你的代码好像只是中断响应函数啊,请问把这个函数地址赋值给哪个寄存器地址可以关联中断啊?
此帖出自ARM技术论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

5
 
楼主,我遇到的问题和你的一样,不知道你解决没有?
此帖出自ARM技术论坛
 
 
 

回复

48

帖子

0

TA的资源

一粒金砂(初级)

6
 
我的写完了,你看看吧

/****************************************************************************************/
/*  NAME:   test.c                                                                      */
/*  DESC:   test doby through I/O Port with timer interrupt(1s).                        */
/*  Date:   06.18.2008                                                                  */
/*  version:    0.0                                                                     */
/*  Program:    Shen Hui (Shh)                                                          */
/****************************************************************************************/
/*  程序主要演示怎样使用armulator的定时器中断.输入也可以不在程序中赋值,直接在内存中改  */
/*  关键的地方在:                                                                       */
/*  1>.要打开中断.                                                                      */
/*  2>.要更改IRQ的服务程序.                                                             */
/*  3>.'服务程序'必须离'矢量'在32MB范围内.即25位地址.                                   */
/*  4>.无中断矢量初始化程序(无.s文件),只设置了IRQ.                                      */
/*  5>.目标CPU必须与调试器一致(例如,同是arm920T).                                       */
/*  6>.MMU/PU initialization Pagetab必须设置为NO_PAGERABLES,否则映射不对                */
/****************************************************************************************/
/*Input:                                                                                */
/*  0805ff01: D0-start  h active                                                        */
/*  0805ff02: D0-stop   l active                                                        */
/*Output:                                                                               */
/*  0805ff0d: D0-doby1  l active            0805ff0e:   D0-doby1    l active            */
/*            D1-doby1  l active                        D1-doby1    l active            */
/*            D2-doby1  l active                        D2-doby1    l active            */
/*            D3-doby1  l active                        D3-doby1    l active            */
/*            D4-doby1  l active                        D4-doby1    l active            */
/*            D5-doby1  l active                        D5-doby1    l active            */
/*            D6-doby1  l active                        D6-doby1    l active            */
/*            D7-doby1  l active                        D7-doby1    l active            */
/****************************************************************************************/ #include "test.h" void itoa2(unsigned short n, unsigned char *str)
{//not find itoa in stdlib.h
    int i=0;
    int swap;
    do
    {
        str=n%2+'0';
        i++;
   
    }while(n/=2);
    str[i--]='\0';
    for(n=0; n     {
        swap=str[n];
        str[n]=str;
        str=swap;
    }
}void __irq IRQ_Handler(void)
{
  unsigned status;  status = IRQStatus;
  /* 处理中断源 */
  if (status & IRQTimer1)
  {
    Timer1Clear = 0; /* 清除中断 */
    IntCT1++;        /* 置标记   */
  }
}/* ************************************************** */
/* 更新'矢量'的内容使他包含一个转移到'服务程序'的指令 */
/* 函数返回原'矢量'值.                                */
/* 注意: '服务程序'必须离'矢量'在32MB范围内.          */
/* ************************************************** */
unsigned Install_Handler (unsigned routine, unsigned *vector)
{
    unsigned vec, oldvec;
    vec = ((routine - (unsigned)vector - 0x8)>>2);
    if (vec & 0xff000000)
    {
        printf ("Installation of Handler failed");
        exit(1);
    }
    vec = 0xea000000 | vec;//EA=
    oldvec = *vector;
    *vector = vec;
    return (oldvec);
}/* ************************************************** */
/* 打开或关闭中断                                     */
/* 通过读 cpsr 标记然后更新第7位来打开或关闭中断      */
/* 这些函数只能用于 privileged 模式,因为cpsr和spsr的  */
/* 控制位在用户模式下不能改变.                        */
/* ************************************************** */
__inline void enable_IRQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        BIC tmp, tmp, #0x80
        MSR CPSR_c, tmp
    }
}
//
__inline void disable_IRQ(void)
{
    int tmp;
    __asm
    {
        MRS tmp, CPSR
        ORR tmp, tmp, #0x80
        MSR CPSR_c, tmp
    }
}// 如果目标为920T则要清除所有中断捕获!
int main(void)
{
    unsigned short  Mask=1;
    unsigned char *str;
   
    DOBYINPUT0_7=0xff;
    DOBYINPUT8_F=0xff;
   
//  itoa2(0x1234,str );
//  printf("str %s\n",str);
   
    printf("Timer Interrupt\n");
   
//未安装前   00000018       [0xe7ff0010]   dci      0xe7ff0010 ; ? undefined
//使地址(IRQ)00000018处为:  [0xea002022]  * b  IRQ_Handler
    Install_Handler ((unsigned)IRQ_Handler, irqvec);
   
    printf("Normal (RAM at 0x8000, semihosting) version\n\n");
    printf("Initializing...\n");
//
    enable_IRQ();    IRQEnableClear = ~0;      // 清除所有的中断
   
    Timer1Control = 0;        // 通过控制位关闭计数器
    Timer1Clear = 0 ;         // 通过写任何值到'清除'清除寄存器来清除中断
    Timer1Load = 2000;        // 装计数器值,可通过晶频计算,这里2000只是为了测试     Timer1Control = (TimerEnable | TimerPeriodic | TimerPrescale8 );         IRQEnableSet = IRQTimer1;     printf("Running...\n");    IntCT1 = 0;          // 清 CT1 标记
     
    while (START)
    {
        if(STOP) break;
        if (IntCT1 != 0)        // 定时器1产生中断
        {
            IntCT1 = 0;         // 复位定时器1中断标记
            DOBYOUTPUT0_7 = (~Mask) & 0xFF;
            DOBYOUTPUT8_F =((~Mask) & 0xFF00)>>8;
            itoa2(Mask,str);
            printf("%016s\n",str);
            Mask<<=1;
            if(Mask==0) Mask=1;
        }
    }
    printf("Ended\n");
    disable_IRQ();
}

/****************************************************************************************/
/* NAME: test.c */
/* DESC: test doby through I/O Port with timer interrupt(1s). */
/* Date: 06.18.2008 */
/* version: 0.0 */
/* Program: Shen Hui (Shh) */
/****************************************************************************************/

#include
#include

/**********/
/* 中断源 */
/**********/
#define IRQUser 0x0001
#define IRQProgrammed 0x0002
#define IRQCommsRx 0x0004
#define IRQCommsTx 0x0008
#define IRQTimer1 0x0010

/**************************/
/* 标准存储器映射外设基址 */
/**************************/
#define IntBase 0x0A000000 /* 中断控制器 */
#define TimerBase 0x0A800000 /* 定时器 */

/*****************/
/* 定时器寄存器 */
/*****************/
#define Timer1Load (*(volatile unsigned *)TimerBase)
#define Timer1Value (*(volatile unsigned *)(TimerBase + 0x04))
#define Timer1Control (*(volatile unsigned *)(TimerBase + 0x08))
#define Timer1Clear (*(volatile unsigned *)(TimerBase + 0x0C))

/****************/
/* 定时器控制位 */
/****************/
#define TimerEnable 0x80
#define TimerPeriodic 0x40
#define TimerPrescale0
此帖出自ARM技术论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表