打印

定时器0中断流水灯问题

[复制链接]
4230|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
奋斗1986|  楼主 | 2011-11-1 20:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 奋斗1986 于 2011-11-2 20:27 编辑

我用的是TQ2440的板子,在裸奔用定时器做个定时中断,用小灯来检测下,无奈做了一天一直没解决问题,总是进不去中断,而且程序的switch语句在JLINK仿真时也有问题,只能在部分的case语句那放置断点,请指点下,谢谢,下面我贴下我的程序
#define GLOBAL_CLK  1
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"
//宏定义---------------------------------------------------------
#define LED1_ON   (rGPBDAT&=(0<<5))
#define LED1_OFF  (rGPBDAT&=(1<<5))
#define LED2_ON   (rGPBDAT&=(0<<6))
#define LED2_OFF  (rGPBDAT&=(1<<6))
#define LED3_ON   (rGPBDAT&=(0<<7))
#define LED3_OFF  (rGPBDAT&=(1<<7))
#define LED4_ON   (rGPBDAT&=(0<<8))
#define LED4_OFF  (rGPBDAT&=(1<<8))
#define M_DIV    92
#define M_PDIV   1
#define M_SDIV   1
#define U_DIV    56
#define U_PDIV   2
#define U_SDIV   2
#define CLKDIVN_VAL 5
#define CNT_TIM0  25000
//变量声明--------------------------------------
unsigned char ucFlag1s;
unsigned char ucCntTime;
//----------定时器0中断处理子程序---------------
void __irq TIME0_INT()
{
rSRCPND|=(1<<10);//写1来清除标志位
rINTPND|=(1<<10);;//写1来清除标志位
if(++ucCntTime==10)
{
  ucCntTime=0;
  ucFlag1s=1;
}
}
//-----------初始化GPORTB用来控制LED-------------------
void init_PORT()
{                                 
  rGPBUP =0x7ff;
    rGPBCON =0x155555;    //设置为输出  
    rGPFCON =0X0000;    //设置为输入  
    rGPBDAT |=0x1e0;   //
}
//------------初始化TIME0作为定时功能
void init_Time0()
{
rLOCKTIME=0xFFFFFFFF;   //锁定时间计数寄存器
rUPLLCON=(U_DIV<<12)+(U_PDIV<<2)+U_SDIV; //UPLL控制寄存器:Fin=12M,UCLK=48M
rMPLLCON=(M_DIV<<12)+(M_PDIV<<2)+M_SDIV; //MPLL控制寄存器:Fin=12M,FCLK=400M
rCLKDIVN=CLKDIVN_VAL;           //时钟分频控制寄存器:运算结果PCLK=FCLK/8=50M
//定时器输入时钟频率=PCLK/{预分频值+1}/分频值
rTCFG0&=~0xFF;     //定时器0配置寄存器
rTCFG0=99;     //预分频值=99;
rTCFG1=0;      //MUX0=1/2;
//至此,计数周期为250000
rTCNTB0=CNT_TIM0;  //25000/250000=0.1s,即0.1s中断一次
rTCON|=0x0000000f;    //开定时器0中断,开启手动更新,自动重载
rTCON|=(1<<1);    //关闭手动更新
rINTMSK &=~(1<<10); //开中断
pISR_TIMER0=(U32)TIME0_INT;//中断处理函数
}
//-----------初始化看门狗-----------------------
void init_WatchDog()
{
rWTCON=0x0000;    //关狗
}
//-----------主程序的初始化---------------------
void init_main()
{
init_WatchDog();
init_Time0();
init_PORT();
ucFlag1s=0;
}
//-----------显示主程序-------------------------
//1s到了,LED顺序点亮,再顺序熄灭
void DispLed()
{
static unsigned char ucTemp;
if(ucFlag1s==0)return;
ucFlag1s=0;
switch(ucTemp)
{
  case 0:
   LED1_OFF;
   LED2_OFF;
   LED3_OFF;
   LED4_OFF;
   break;
  case 1:
   LED1_ON;
   break;
  case 2:
   LED2_ON;
   break;
  case 3:
   LED3_ON;
   break;
  case 4:
   LED4_ON;
   break;
  case 5:
   LED4_OFF;
   break;
  case 6:
   LED3_OFF;
   break;
  case 7:
   LED2_OFF;
   break;
  case 8:
   LED1_OFF;ucTemp=0;
   break;
  default :ucTemp=0;break;
}
ucTemp++;
}
//-----------主程序循环-------------------------
void Main(void)
{
init_main();
while(1)
{
  DispLed();
}
}



终于解决了,但是还是存在一定的问题,就是在SDRAM中不能运行,要在NAND FLASH中运行,估计是SDRAM的中断映射问题吧,现在把调试好的程序发下,大家互相交流下
#define GLOBAL_CLK  1
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"
//宏定义---------------------------------------------------------
#define LED1_ON   (rGPBDAT&=~(1<<5))
#define LED1_OFF  (rGPBDAT|=(1<<5))
#define LED2_ON   (rGPBDAT&=~(1<<6))
#define LED2_OFF  (rGPBDAT|=(1<<6))
#define LED3_ON   (rGPBDAT&=~(1<<7))
#define LED3_OFF  (rGPBDAT|=(1<<7))
#define LED4_ON   (rGPBDAT&=~(1<<8))
#define LED4_OFF  (rGPBDAT|=(1<<8))
#define M_DIV    92
#define M_PDIV   1
#define M_SDIV   1
#define U_DIV    56
#define U_PDIV   2
#define U_SDIV   2
#define CLKDIVN_VAL 5
#define CNT_TIM0  2500
//变量声明--------------------------------------
unsigned char ucFlag1s;
unsigned char ucCntTime;
//----------定时器0中断处理子程序---------------
void __irq TIME0_INT(void)
{
//LED1_OFF;//测试用
//LED2_ON;//测试用
//LED3_OFF;//测试用
//LED4_ON;//测试用
//ClearPending(BIT_TIMER0);//清除TIMER0中断挂起寄存器,防止其反复相应
rSRCPND|=(1<<10);//写1来清除标志位
rINTPND|=(1<<10);;//写1来清除标志位
//rGPBDAT =~0x1e0;
if(++ucCntTime==10)
{
  ucCntTime=0;
  ucFlag1s=1;
}
}
//-----------初始化GPORTB用来控制LED-------------------
void init_PORT()
{                                 
  rGPBUP =0x7ff;
    rGPBCON =0x155555;    //设置为输出  
    rGPFCON =0X0000;    //设置为输入  
    rGPBDAT|=0x1e<<4;   //
}
//------------初始化TIME0作为定时功能
void init_Time0()
{
rLOCKTIME=0xFFFFFFFF;   //锁定时间计数寄存器
rUPLLCON=(U_DIV<<12)+(U_PDIV<<4)+U_SDIV; //UPLL控制寄存器:Fin=12M,UCLK=48M
rMPLLCON=(M_DIV<<12)+(M_PDIV<<4)+M_SDIV; //MPLL控制寄存器:Fin=12M,FCLK=400M
rCLKDIVN|=CLKDIVN_VAL;           //时钟分频控制寄存器:运算结果PCLK=FCLK/8=50M
//定时器输入时钟频率=PCLK/{预分频值+1}/分频值
rTCFG0&=~0xFF;     //定时器0配置寄存器
rTCFG0|=249;     //预分频值=249;
rTCFG1&=~0XF;
rTCFG1|=2;      //MUX0=1/8;
//至此,计数周期为25000
rTCNTB0=CNT_TIM0;  //2500/25000=0.1s,即0.1s中断一次
rTCON|=(1<<1);      //开启手动更新
rTCON=0;   
rTCON|=(1<<3|1<<0);   //开定时器0中断,自动重载
rSRCPND|=(1<<10);//写1来清除标志位
rINTPND|=(1<<10);;//写1来清除标志位
//ClearPending(BIT_TIMER0);//清除计数器0中断挂起寄存器
pISR_TIMER0=(U32)TIME0_INT;//中断处理函数
rINTMSK &=~(1<<10); //开中断
//EnableIrq(BIT_TIMER0);
}
//-----------初始化看门狗-----------------------
void init_WatchDog()
{
rWTCON=0x0000;    //关狗
}
//-----------主程序的初始化---------------------
void init_main()
{
init_WatchDog();
init_PORT();
init_Time0();
LED1_OFF;LED2_OFF;LED3_OFF;LED4_OFF;
}
//-----------显示主程序-------------------------
//1s到了,LED顺序点亮,再顺序熄灭
void DispLed()
{
static int iTemp;
if(ucFlag1s==1)
{
  ucFlag1s=0;
  switch(iTemp)
  {
   case 0:LED1_ON;break;
   case 1:LED2_ON;break;
   case 2:LED3_ON;break;
   case 3:LED4_ON;break;
   case 4:LED4_OFF;break;
   case 5:LED3_OFF;break;
   case 6:LED2_OFF;break;
   case 7:LED1_OFF;break;
   default :iTemp=0;break;
  }
  if(++iTemp==8)
  {
   iTemp=0;
  }
}
}
//-----------主程序循环-------------------------
void Main(void)
{
init_main();
//ucFlag1s=1;
while(1)
{
  DispLed();
}
}

相关帖子

沙发
Chiffre| | 2011-11-2 14:02 | 只看该作者
同样学习中

使用特权

评论回复
板凳
Chiffre| | 2011-11-2 14:06 | 只看该作者
楼主,我自己刚把2440的板子买回来,我也回答不上你的问题,
但是,我玩过51,我记得51的中断是要先打开的,然后还有给寄存器赋初值,难道是因为arm是高级单片机,所以不用开中断?

使用特权

评论回复
地板
奋斗1986|  楼主 | 2011-11-2 20:20 | 只看该作者
3# Chiffre
是要开中断的哟,我代码里面已经有开中断的语句咯,现在问题已经解决了,不能在SDRAM中运行,但是可以在nand flash中运行,猜测是SDRAM中的中断映射问题,但还不确定,努力寻找答案中。。。
另外贴出来的程序有点错误,UPLL和MPLL中的位4到位9的赋值语句应该是右移4位,我错写成了右移俩位

使用特权

评论回复
5
奋斗1986|  楼主 | 2011-11-2 20:21 | 只看该作者
3# Chiffre
互相学习啊

使用特权

评论回复
6
mage心寒| | 2011-11-3 11:08 | 只看该作者
中断控制流水灯跟51的一样。。配置下中断寄存器设置一个时间,就相当于延迟,然后控制流水灯左移右移就好了。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

5

帖子

1

粉丝