3848|5

63

帖子

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技术论坛

最新回复

奇怪,我之前发的帖子怎么不见了? 搂主,你这个问题我解决了,你看看我下面贴的程序理注释的地方.没法改成红色的,就在注释未安装前的那个地方. 这个程序是可以运行的,你可以复制到你的机器上试试. /*  说明: 下面程序从ads1.2\EXAMPLES\EMBEDDED\RPS_IRQ移植而来.         程序主要用来演示怎样使用armulator的定时器中断.         关键的地方在:         1>.要打开中断.         2>.要更改IRQ的服务程序.         3>.'服务程序'必须离'矢量'在32MB范围内.即25位地址.         4>.无中断矢量初始化程序(无.s文件),只修改了IRQ.         5>.目标CPU必须与调试器一致(如同是arm920T). */ #include   // for printf() #include // for exit(1) /**********/ /* 中断源 */ /**********/ #define IRQUser         0x0001 #define IRQProgrammed   0x0002 #define IRQCommsRx      0x0004 #define IRQCommsTx      0x0008 #define IRQTimer1       0x0010 #define IRQTimer2       0x0020 /**************************/ /* 标准存储器映射外设基址 */ /**************************/ #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 Timer2Load       (*(volatile unsigned *)(TimerBase + 0x020)) #define Timer2Value      (*(volatile unsigned *)(TimerBase + 0x024)) #define Timer2Control    (*(volatile unsigned *)(TimerBase + 0x028)) #define Timer2Clear      (*(volatile unsigned *)(TimerBase + 0x02C)) /****************/ /* 定时器控制位 */ /****************/ #define TimerEnable      0x80 #define TimerPeriodic    0x40 #define TimerPrescale0   0x00 #define TimerPrescale4   0x04 #define TimerPrescale8   0x08 #define TimerDisable     0x00 #define TimerCyclic      0x00 /*************************/ /* 中断控制器 IRQ 寄存器 */ /*************************/ #define IRQStatus      (*(volatile unsigned *)IntBase) #define IRQRawStatus   (*(volatile unsigned *)(IntBase + 0x04)) #define IRQEnable      (*(volatile unsigned *)(IntBase + 0x08)) #define IRQEnableSet   (*(volatile unsigned *)(IntBase + 0x08)) #define IRQEnableClear (*(volatile unsigned *)(IntBase + 0x0c)) #define IRQSoft        (*(volatile unsigned *)(IntBase + 0x10)) int IntCT1 = 0; int IntCT2 = 0; int Count  = 0; unsigned *irqvec = (unsigned *)0x18;//IRQ void __irq IRQ_Handler(void) {   unsigned status;   status = IRQStatus;   /* 处理中断源 */   if (status & IRQTimer1)   {     Timer1Clear = 0;/* 清除中断 */     IntCT1++;        /* 置标记   */   }   else if (status & IRQTimer2)   {     Timer2Clear = 0;/* 清除中断 */     IntCT2++;        /* 置标记   */   } } /* ************************************************** */ /* 更新'矢量'的内容使他包含一个转移到'服务程序'的指令 */ /* 函数返回原'矢量'值.                                */ /* 注意: '服务程序'必须离'矢量'在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) {         printf("Timer Interrupt Example\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;        // 通过控制位关闭计数器         Timer2Control = 0;         Timer1Clear = 0 ;         // 通过写任何值到'清除'清除寄存器来清除中断         Timer2Clear = 0 ;         Timer1Load = 2000;        // 装计数器值         Timer2Load = 8000;            Timer1Control = (TimerEnable   |  // 使能定时器                                       TimerPeriodic  |  // 周期性产生中断                     TimerPrescale8 ); // 置最大预分频8位              Timer2Control = (TimerEnable   |                     TimerPeriodic  |                       TimerPrescale8 );         IRQEnableSet = IRQTimer1 | IRQTimer2; // 使能2个定时器中断         printf("Running...\n");         IntCT1 = 0;          // 清 CT1 标记                   IntCT2 = 0;          // 清 CT2 标记         Count  = 0;         while ( Count < 20 )         {                 if (IntCT1 != 0)        // 定时器1产生中断                 {                         Count++;                         printf("IntCT1\n");                         IntCT1 = 0;         // 复位定时器1中断标记                 }                 if (IntCT2 != 0)        // 定时器2产生中断                 {                         Count++;                         printf("IntCT2\n");                         IntCT2 = 0;         // 复位定时器2中断标记                 }         }         printf("Ended\n");         disable_IRQ(); }   详情 回复 发表于 2008-6-21 21:09
点赞 关注
 

回复
举报

63

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
你找找IRQ这样的宏标识...
仅跟的函数就是...
此帖出自ARM技术论坛
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
这一版块,太没人气了,是不是大家都成大侠了

如果成大侠了,也常回家看看嘛,家里太冷清了

据说努力顶帖也是一种美德,但我只想大家常回家看看

毕竟每天都有新手需要帮忙,而我能帮的只能是把帖子顶起来
此帖出自ARM技术论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

4
 
仍未解决,郁闷中...
此帖出自ARM技术论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

5
 
什么呀
此帖出自ARM技术论坛
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

6
 
奇怪,我之前发的帖子怎么不见了?

搂主,你这个问题我解决了,你看看我下面贴的程序理注释的地方.没法改成红色的,就在注释未安装前的那个地方. 这个程序是可以运行的,你可以复制到你的机器上试试.

/*  说明: 下面程序从ads1.2\EXAMPLES\EMBEDDED\RPS_IRQ移植而来.
        程序主要用来演示怎样使用armulator的定时器中断.
        关键的地方在:
        1>.要打开中断.
        2>.要更改IRQ的服务程序.
        3>.'服务程序'必须离'矢量'在32MB范围内.即25位地址.
        4>.无中断矢量初始化程序(无.s文件),只修改了IRQ.
        5>.目标CPU必须与调试器一致(如同是arm920T).
*/
#include   // for printf()
#include // for exit(1)
/**********/
/* 中断源 */
/**********/
#define IRQUser         0x0001
#define IRQProgrammed   0x0002
#define IRQCommsRx      0x0004
#define IRQCommsTx      0x0008
#define IRQTimer1       0x0010
#define IRQTimer2       0x0020
/**************************/
/* 标准存储器映射外设基址 */
/**************************/
#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 Timer2Load       (*(volatile unsigned *)(TimerBase + 0x020))
#define Timer2Value      (*(volatile unsigned *)(TimerBase + 0x024))
#define Timer2Control    (*(volatile unsigned *)(TimerBase + 0x028))
#define Timer2Clear      (*(volatile unsigned *)(TimerBase + 0x02C))
/****************/
/* 定时器控制位 */
/****************/
#define TimerEnable      0x80
#define TimerPeriodic    0x40
#define TimerPrescale0   0x00
#define TimerPrescale4   0x04
#define TimerPrescale8   0x08
#define TimerDisable     0x00
#define TimerCyclic      0x00
/*************************/
/* 中断控制器 IRQ 寄存器 */
/*************************/
#define IRQStatus      (*(volatile unsigned *)IntBase)
#define IRQRawStatus   (*(volatile unsigned *)(IntBase + 0x04))
#define IRQEnable      (*(volatile unsigned *)(IntBase + 0x08))
#define IRQEnableSet   (*(volatile unsigned *)(IntBase + 0x08))
#define IRQEnableClear (*(volatile unsigned *)(IntBase + 0x0c))
#define IRQSoft        (*(volatile unsigned *)(IntBase + 0x10))


int IntCT1 = 0;
int IntCT2 = 0;
int Count  = 0;

unsigned *irqvec = (unsigned *)0x18;//IRQ

void __irq IRQ_Handler(void)
{
  unsigned status;

  status = IRQStatus;
  /* 处理中断源 */
  if (status & IRQTimer1)
  {
    Timer1Clear = 0;/* 清除中断 */
    IntCT1++;        /* 置标记   */
  }
  else if (status & IRQTimer2)
  {
    Timer2Clear = 0;/* 清除中断 */
    IntCT2++;        /* 置标记   */
  }
}
/* ************************************************** */
/* 更新'矢量'的内容使他包含一个转移到'服务程序'的指令 */
/* 函数返回原'矢量'值.                                */
/* 注意: '服务程序'必须离'矢量'在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)
{
        printf("Timer Interrupt Example\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;        // 通过控制位关闭计数器
        Timer2Control = 0;

        Timer1Clear = 0 ;         // 通过写任何值到'清除'清除寄存器来清除中断
        Timer2Clear = 0 ;

        Timer1Load = 2000;        // 装计数器值
        Timer2Load = 8000;   

        Timer1Control = (TimerEnable   |  // 使能定时器                  
                    TimerPeriodic  |  // 周期性产生中断
                    TimerPrescale8 ); // 置最大预分频8位     

        Timer2Control = (TimerEnable   |
                    TimerPeriodic  |  
                    TimerPrescale8 );

        IRQEnableSet = IRQTimer1 | IRQTimer2; // 使能2个定时器中断

        printf("Running...\n");

        IntCT1 = 0;          // 清 CT1 标记
         
        IntCT2 = 0;          // 清 CT2 标记
        Count  = 0;

        while ( Count < 20 )
        {
                if (IntCT1 != 0)        // 定时器1产生中断
                {
                        Count++;
                        printf("IntCT1\n");
                        IntCT1 = 0;         // 复位定时器1中断标记
                }
                if (IntCT2 != 0)        // 定时器2产生中断
                {
                        Count++;
                        printf("IntCT2\n");
                        IntCT2 = 0;         // 复位定时器2中断标记
                }
        }
        printf("Ended\n");
        disable_IRQ();
}

此帖出自ARM技术论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表