ARM7在UCOS下如何使用中断?
先说说状况:我在LPC2103开发板上使用UCOS模板,开发环境为IAR,模板没问题,创建简单任务比如呼吸灯之类都能正常运行。于是我想试着使用中断,因为系统节拍使用定时器...
先说说状况:
我在LPC2103开发板上使用UCOS模板,开发环境为IAR,模板没问题,创建简单任务比如呼吸灯之类都能正常运行。于是我想试着使用中断,因为系统节拍使用定时器tmer0,于是我仿照timer0的代码,复制后修改为timer1的代码,具体如下:
与timer0相关的有两个函数:
static void Tmr_TickInit (void)
{
CPU_INT32U pclk_freq;
CPU_INT32U tmr_reload;
VICIntSelect &= ~(1 << VIC_TIMER0);
VICVectAddr0 = (CPU_INT32U)Tmr_TickISR_Handler;
VICVectCntl0 = 0x20 |VIC_TIMER0;
VICIntEnable = (1 <<VIC_TIMER0);
pclk_freq =BSP_CPU_PclkFreq();
tmr_reload = pclk_freq /OS_TICKS_PER_SEC;
T0TCR = 0;
T0PC = 0;
T0MR0 = tmr_reload;
T0MCR = 3;
T0CCR = 0;
T0EMR = 0;
T0TCR = 1;
}
void Tmr_TickISR_Handler (void)
{
T0IR = 0xFF;
OSTimeTick();
}
仿照timer0修改的timer1函数:
static void Tmr_TIMER1_Init(void)
{
……
VICIntSelect &= ~(1 << VIC_TIMER1);
VICVectAddr1 = (CPU_INT32U)Tmr_TIMER1_Handler;
VICVectCntl1 = 0x20 | VIC_TIMER1;
VICIntEnable = (1 <<VIC_TIMER1);
……
T1MR0 = tmr_reload+50;
T1MCR = 3;
T1CCR = 0;
T1EMR = 0;
T1TCR = 1;
}
void Tmr_TIMER1_Handler (void)
{
T1IR= 0xFF;
LED_Toggle(1);
}
timer0使用的是VICVectAddr0和VICVectCntl0,修改后timer1使用的是VICVectAddr1和VICVectCntl1。
按理说编译后我应该能看到LED灯闪烁才对,可结果是一点反应也没有,不知道为什么。后来用仿真器看,用哪个“运行到当前位置”的功能,代码能运行到timer0的Tmr_TickISR_Handler()中去,同样方法不能运行到Tmr_TIMER1_Handler(void)中,不知道为什么。
请高手指点,不胜感激!
修改后将timer1的初始化代码添加到BSP_Init (void)中timer0的初始化代码后面:
void BSP_Init (void)
{
MEMMAP = 2;
……
VIC_Init();
LED_Init();
ADC_Init();
Tmr_TickInit();
Tmr_TIMER1_Init();
}。 展开
我在LPC2103开发板上使用UCOS模板,开发环境为IAR,模板没问题,创建简单任务比如呼吸灯之类都能正常运行。于是我想试着使用中断,因为系统节拍使用定时器tmer0,于是我仿照timer0的代码,复制后修改为timer1的代码,具体如下:
与timer0相关的有两个函数:
static void Tmr_TickInit (void)
{
CPU_INT32U pclk_freq;
CPU_INT32U tmr_reload;
VICIntSelect &= ~(1 << VIC_TIMER0);
VICVectAddr0 = (CPU_INT32U)Tmr_TickISR_Handler;
VICVectCntl0 = 0x20 |VIC_TIMER0;
VICIntEnable = (1 <<VIC_TIMER0);
pclk_freq =BSP_CPU_PclkFreq();
tmr_reload = pclk_freq /OS_TICKS_PER_SEC;
T0TCR = 0;
T0PC = 0;
T0MR0 = tmr_reload;
T0MCR = 3;
T0CCR = 0;
T0EMR = 0;
T0TCR = 1;
}
void Tmr_TickISR_Handler (void)
{
T0IR = 0xFF;
OSTimeTick();
}
仿照timer0修改的timer1函数:
static void Tmr_TIMER1_Init(void)
{
……
VICIntSelect &= ~(1 << VIC_TIMER1);
VICVectAddr1 = (CPU_INT32U)Tmr_TIMER1_Handler;
VICVectCntl1 = 0x20 | VIC_TIMER1;
VICIntEnable = (1 <<VIC_TIMER1);
……
T1MR0 = tmr_reload+50;
T1MCR = 3;
T1CCR = 0;
T1EMR = 0;
T1TCR = 1;
}
void Tmr_TIMER1_Handler (void)
{
T1IR= 0xFF;
LED_Toggle(1);
}
timer0使用的是VICVectAddr0和VICVectCntl0,修改后timer1使用的是VICVectAddr1和VICVectCntl1。
按理说编译后我应该能看到LED灯闪烁才对,可结果是一点反应也没有,不知道为什么。后来用仿真器看,用哪个“运行到当前位置”的功能,代码能运行到timer0的Tmr_TickISR_Handler()中去,同样方法不能运行到Tmr_TIMER1_Handler(void)中,不知道为什么。
请高手指点,不胜感激!
修改后将timer1的初始化代码添加到BSP_Init (void)中timer0的初始化代码后面:
void BSP_Init (void)
{
MEMMAP = 2;
……
VIC_Init();
LED_Init();
ADC_Init();
Tmr_TickInit();
Tmr_TIMER1_Init();
}。 展开
2个回答
展开全部
这个有几个原因,请参考下面分析:
1,ucos 是多任务操作系统,当系统正常运行时,必须建立一个以上的任务,否则系统处于死机崩溃状态,程序运行出现异常。
2,你的系统时钟中断程序有问题,应该关中断,调用过系统时钟后再开中断,否则系统时钟异常导致程序运行异常,具体程序如下:
void Tmr_TickISR_Handler (void)
{
T0IR = 0xFF; //清零中断标志位
OSIntEnter( ); // 关中断,必须有
OSTimeTick();
OSIntExit(); //临界代码完成,与关中断成对使用
}
3,看你上面的程序里面,你想使用定时器1中断来处理一些信息,而程序无法运行到其中,可能的原因有:1)你的定时器1初始化异常。2)你系统里面的中断使能关掉了。其实多任务的时候,你完全可以将它分配到一个任务里处理,这样既可以充分利用多任务,又不会因为中断没处理好而出现异常,如果你想要求实时性较高,那你可以将这个人物的优先级设为最高。
4,UCOS初始化异常,UCOS系统初始化有固定的顺序以及模式,颠倒了就会出现异常。
5,系统时钟tick一般建议为10hz-50hz,太高的话在你初始化的时候,还没创建任务的时候都已经进行任务切换了而导致ucos崩溃。
1,ucos 是多任务操作系统,当系统正常运行时,必须建立一个以上的任务,否则系统处于死机崩溃状态,程序运行出现异常。
2,你的系统时钟中断程序有问题,应该关中断,调用过系统时钟后再开中断,否则系统时钟异常导致程序运行异常,具体程序如下:
void Tmr_TickISR_Handler (void)
{
T0IR = 0xFF; //清零中断标志位
OSIntEnter( ); // 关中断,必须有
OSTimeTick();
OSIntExit(); //临界代码完成,与关中断成对使用
}
3,看你上面的程序里面,你想使用定时器1中断来处理一些信息,而程序无法运行到其中,可能的原因有:1)你的定时器1初始化异常。2)你系统里面的中断使能关掉了。其实多任务的时候,你完全可以将它分配到一个任务里处理,这样既可以充分利用多任务,又不会因为中断没处理好而出现异常,如果你想要求实时性较高,那你可以将这个人物的优先级设为最高。
4,UCOS初始化异常,UCOS系统初始化有固定的顺序以及模式,颠倒了就会出现异常。
5,系统时钟tick一般建议为10hz-50hz,太高的话在你初始化的时候,还没创建任务的时候都已经进行任务切换了而导致ucos崩溃。
追问
十分感谢您耐心细致的回答。
我是刚开始学习ucos,上面的问题我大概解决了,我用JLINK仿真时无法正确运行,拔掉jlink后再复位就能正常运行了,timer1中断服务中led程序也能被执行,后者使用ISP下载后也能正常运行。看来是JLINK仿真的问题。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询