这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » ARM,uCOS,II 刚学ARM开发,问个问题,多多指教(在uCOS-II系统

共2条 1/1 1 跳转至

ARM,uCOS,II 刚学ARM开发,问个问题,多多指教(在uCOS-II系统下的中断、消息邮箱问题)

院士
2006-09-17 18:14:16     打赏
ARM,uCOS,II 刚学ARM开发,问个问题,多多指教(在uCOS-II系统下的中断、消息邮箱问题)



关键词: 刚学     开发     问个     问题     多多     指教     uCOS-II    

院士
2006-12-22 22:43:00     打赏
2楼
问 刚学习“周立功”的开发教程,打算实现:
在键盘的外部中断处理子程序中发送消息到消息邮箱,task0一直等待消息收到后对LED进行相应的控制。
问题是:我的中断进入几次后就再不进入了,还有调试时现象也不一致(代码没该动)。
现把拼凑的(呵呵)代码贴上,望指教!!!

#include "config.h"

#define    TaskStkLengh    64            //Define the Task0 stack length 定义用户任务0的堆栈长度
#define      KEY1    (1 << 20)           /* P0.20为KEY1 */

// LED控制宏函数定义。LED1--LED4的控制I/O为P2.28--P2.31
#define   LED_ADJ            28
#define   LED_IOCON            (0xFF<<LED_ADJ)
#define   LED_OFF()         IO2SET=LED_IOCON
#define   LED_DISP(dat)     LED_OFF(); IO2CLR=((dat)<<LED_ADJ)

#define      KeyNo1    0x01            //按键1
#define      KeyNo2    0x02            //按键2
#define      KeyNo3    0x03            //按键3
#define      KeyNo4    0x03            //按键4

OS_STK    TaskStk [TaskStkLengh];        //Define the Task0 stack 定义用户任务0的堆栈

void     Task0(void *pdata);            //Task0 任务0

OS_EVENT *MyMailBox=NULL;

void __irq  IRQ_Key1(void)
{  
    INT8U buf[8],i;
    OS_ENTER_CRITICAL();
    EXTINT = 1<<3;
    buf[0]=KeyNo1;
    for(i=1;i<8;i++)
     buf[i]=0;
    OSMboxPost(MyMailBox,(void *)buf);
      EXTINT = 1<<3;
    VICVectAddr = 0;
    OS_EXIT_CRITICAL();
}



int main (void)
{
    OSInit ();

    OSTaskCreate (Task0,(void *)0, &TaskStk[TaskStkLengh - 1], 1);        
    OSStart ();
    return 0;                                                            
}
/*********************************************************************************************************
**                            Task0 任务0
********************************************************************************************************/

void Task0    (void *pdata)
{
    INT8U *err,i;
    INT8U *Msg;
     const uint8  DISP_TAB[24] = { 0x0F,0x00,0x0F,0x00,0x0F,0x00,0x0F,0x00,
                                 0x01,0x02,0x04,0x08,0x04,0x02,0x01,0x00,
                                 0x05,0x0A,0x05,0x0A,0x05,0x0A,0x05,0x00 };
    pdata = pdata;
    
    MyMailBox=OSMboxCreate(NULL);    
    if (MyMailBox == NULL)
          while (1);
    
    TargetInit ();
       PINSEL1 = 3<<8;                        // 设置管脚连接,P0.20设置为EINT3
       PINSEL0 = 0x00000000;        // 设置P0口管脚连接GPIO  

    IO0DIR &= ~KEY1;
    IO2DIR = LED_IOCON;         // 设置LED1--LED4的控制口为输出
    LED_OFF();
                                            // 设置KEY1的控制I/O为输入                                    // 3<<8 等价于 0x00000180
    EXTMODE = 0x00;                        // 设置EINT3中断为电平触发模式
                                    
    /* 打开EINT3中断(使用非向量IRQ) */
    VICIntSelect = 0x00000000;            // 设置所有中断分配为IRQ中断
    VICDefVectAddr = (int)IRQ_Key1;        // 设置中断服务程序地址
    VICVectCntl0 = 0x29;
    EXTINT = 1<<3;                        // 清除EINT3中断标志
    VICIntEnable = 1<<17;                // 使能EINT3中断,EINT3在Bit17上
    for (;;)
    {
        Msg=(INT8U *)OSMboxPend(MyMailBox,0,err);
        switch(Msg[0])
        {
            case KeyNo1:
            {
                for(i=0; i<4; i++)
                {
                    LED_DISP(DISP_TAB[i]);          // 输出LED显示数据
                    OSTimeDly(OS_TICKS_PER_SEC/2);    // 延时0.5S
                }
               break;
            }              
            default:
            {
                OSMboxAccept(MyMailBox);
                break;
            }
        }
       }

}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

1: 都是周立功书上的代码,只不过想测试一下中断和消息邮箱上 2: 调试中。。。我把这句删除
    VICVectCntl0 = 0x29;
并删除了IRQ_Key1(void)中的第一句:EXTINT = 1<<3;

问题更奇怪了,
1。我不加断点:AXD起来后,按一下键盘则4个LED亮起(一直亮),而后再没有反映
2.我在IRQ_Key1(void)中设断点:AXD起来后,按一下键盘,跳到断点处,执行效果如预期的,再按几次键盘,总会有一次断点后执行,LED没有反映,且以后也不能停在断点处
3。我在switch(Msg[0])处设断点:效果如(2.)所列,基本相同


我觉得是程序在哪里跑飞掉了,又不是很确定,请大家调试下看看。。
我的环境是SmartARM2200  +  ADSv1_2  
谢谢了。
3: 我用的LPC2134调过。把堆栈设大点再试试。 4: 堆栈大了也没影响哦堆栈设大还一样啊。

我在我以为跑飞的时候stop它,程序停在startup.s文件中的



 ;取指令中止
 PrefetchAbort
      B       PrefetchAbort------》停在这里


是不是它跑飞掉了啊?正常不是应该停在消息等待处呢?
5: 难道这种中断+消息邮箱的机制有问题么?我觉得应该不会啊~~~! 6: 那么大家是怎么处理按键中断的中断处理函数里面不能写太多的处理,因此必须放在task中完成,
开始考虑用消息队列,想想可能会有延时的操作,对实时的系统比较难以接受,
那么我就选择了消息邮箱,

下一阶段,就尝试对不同的按键进行响应,大家有什么建议 7: 没人气啊是不是我要把程序烧到FLASH里面,才正常呢 8: 中断EINT3的中断号错了
    EXTMODE = 0x00;                        // 设置EINT3中断为电平触发模式
                                    
    /* 打开EINT3中断(使用非向量IRQ) */
    VICIntSelect = 0x00000000;            // 设置所有中断分配为IRQ中断
    VICDefVectAddr = (int)IRQ_Key1;        // 设置中断服务程序地址
    

VICVectCntl0 = 0x29;                 //分配给向量的中断请求和软 件 编号,EINT3是17号中断,所以设置VIC通道号为17的EINT3的中断源为优先级0的中断应该是VICVectCnt10 = 0x31; (0x20|17);既然设置EINT3为向量中断,就要设置向量中断的地址VICVectAddr0=(int)IRQ_Key1;而不是非向量中断的地址;




   

EXTINT = 1<<3;                        // 清除EINT3中断标志
    VICIntEnable = 1<<17;                // 使能EINT3中断,EINT3在Bit17上
9: 还是不行啊??我设为:

    VICIntSelect = 0x00000000;            // 设置所有中断分配为IRQ中断
    VICVectCntl0 = 0x31;
    VICVectAddr0=(int)IRQ_Key1;
    EXTINT = 1<<3;                        // 清除EINT3中断标志
    VICIntEnable = 1<<17;                // 使能EINT3中断,EINT3在Bit17上

中断时候怎么跳转到target.c下面的IRQ_Exception()函数中了呢?
我自己的IRQ_Key1没有响应啊。。。~
10: 改为使用非向量IRQ使用非向量IRQ:
EXTMODE = 0x00;                // 设置EINT3中断为电平触发模式                                    
VICIntSelect = 0x00000000;            // 设置所有中断分配为IRQ中断
VICDefVectAddr = (int)IRQ_Key1;        // 设置中断服务程序地址
EXTINT = 1<<3;                // 清除EINT3中断标志
VICIntEnable = 1<<17;                // 使能EINT3中断,EINT3在Bit17上


然后,我的中断可以进入,但只有我在IRQ_Key1(void)中下了断点,才可以响应,如果去掉断点,就再也进不去了。。。
有没有人用这个设备调试的? 11: re你应该看以下,targer.c里面的东西
中断服务程序应该是 irqhander  hander  IRQ_Key1;
VICVectAddr0 = irqhander; 12: 中断问题已经解决,谢谢各位定义:IRQ_KeyHandler    HANDLER IRQ_Key1;
然后再指向IRQ_KeyHandler;


多谢《《xiao李》》

顺便问个:如何防止按键抖动? 13: re用个延时程序就可以了
例如:
判断有键按下
延时
再判断是否键仍然按下
这样就可以去抖动,延时一般为1到十几个ms! 14: 我现在按一下键,就触发两次中断这个算是按键的抖动么?

再问《xiao李》,我的延时是不是加在中断处理子函数中啊?因为只有这里我才知道我触发了按键啊。

可是加了延时,它还是执行一次延时一会再执行一次,就是说还是执行了两次。
是不是程序里的问题啊? 15: re你如果用中断来确定按键的话
那你需要设置外部中断寄存器,应该设置为电平触发,好像就可以了,如果是普通IO口,上面的方法可用来去除查询式的抖动! 16: 我也遇到中断程序中使用邮箱的问题了请看我在本版的问题《奇怪的定时器中断》
帮我看一下好吗?
我的QQ:272184176
msn:linsf@ustc.edu
希望能讨论一下,
或者回复一下我的帖子,多谢!

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]