mini2440下ucos-ii的按键和蜂鸣器的总结。

实现功能:按下案件后,蜂鸣器响一声,同时LED闪烁亮一下。按键采用中断方式,发送信号量。 系统主程序如下:   

//=======================================
#include "app_cfg.h"
#include "Printf.h"
//=========================================
OS_STK  MainTaskStk[MainTaskStkLengh];
OS_STK  Task3Stk [Task3StkLengh];       // Define the Task3 stack

int rYear, rMonth,rDay,rDayOfWeek,rHour,rMinute,rSecond;
void Rtc_Init(void);

void Task_LCD(void *p);

OS_EVENT *Semp;                         //Creat semp
U8 err;

int Main(int argc, char **argv)
{
     //初始化目标板
     TargetInit();
     //初始化uC/OS  
     OSInit ();  
     //初始化系统时基
     OSTimeSet(0); 
      //创建系统初始任务
      OSTaskCreate (MainTask,(void *)0, &MainTaskStk[MainTaskStkLengh - 1],       MainTaskPrio);                         
       OSStart ();
       return 0;

}

void MainTask(void *pdata) //Main Task create and task3
{
   U16 TestCnt=0;
   #if OS_CRITICAL_METHOD == 3       /* Allocate storage for CPU status    register */
   OS_CPU_SR  cpu_sr;
   #endif
   OS_ENTER_CRITICAL();
   Timer0Init();                      //initial timer0 for ucos time tick
   ISRInit();                         //initial interrupt prio or enable or disable
   OS_EXIT_CRITICAL();
   KeyScan_Init();
   Semp=OSSemCreate(0);               //create a Mbox, 0- a NULL semphore.
   OSTaskCreate (Task3,(void *)0, &Task3Stk[Task3StkLengh - 1], Task3Prio);
  while(1)
  {
        rGPBDAT = 0x07fe;             //light the LED
        OSTimeDly(OS_TICKS_PER_SEC);
  }

}

void Task3(void *pdata)
{
    INT8U err;
    INT16U msg;
    for(;;)
    {
        OSSemPend(Semp,0,&err);       //wait for the semphore.
        rGPBDAT = 0x0000;             //off the led
        Beep(2000,2000);              //beep
        Delay(100);
        OSTimeDly(OS_TICKS_PER_SEC);
    }
}

//************************[ Rtc_Init ]*********************************
void Rtc_Init(void)
{
 int wYear, wMonth,wDay,wDayOfWeek,wHour,wMinute,wSecond;

    wYear = 2008;
    wMonth = 9;
    wDay = 5;
    wDayOfWeek = 5;
    wHour= 9;
    wMinute = 41;
    wSecond = 30;
 
 rRTCCON = 1 ;  //RTC read and write enable

 rBCDYEAR = (unsigned char)TO_BCD(wYear%100); //
  rBCDMON  = (unsigned char)TO_BCD(wMonth);   //
  rBCDDAY  = (unsigned char)TO_BCD(wDay);     //
 rBCDDATE = wDayOfWeek+1;                     //星期
 rBCDHOUR = (unsigned char)TO_BCD(wHour);     //小时
 rBCDMIN  = (unsigned char)TO_BCD(wMinute);   //
 rBCDSEC  = (unsigned char)TO_BCD(wSecond);   //
 rRTCCON &= ~1 ;  //RTC read and write disable
}

按键中断函数放在keyscan.c文件中,内容如下:

/**************************************************************
4*4 Key Scan
**************************************************************/
#include "config.h"

#include "def1.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"

#include "keyscan.h"

OS_CPU_SR  cpu_sr;
/******************************************************************************
 1X6 矩阵键盘
六个输入引脚: EINT8 -----( GPG0  )
    EINT11 -----( GPG3  )
    EINT13-----( GPG5  )
    EINT14-----( GPG6 )
    EINT15-----( GPG7 )
    EINT19-----( GPG11 )
******************************************************************************/
U8 Key_Scan( void )
{

 if(      (rGPGDAT&(1<< 0)) == 0 )
 {
    // Delay(80);
     while((rGPGDAT&(1<< 0)) == 0);
      
  return 1 ;
 }
 else if( (rGPGDAT&(1<< 3)) == 0 )
 {
    // Delay(80);
     while( (rGPGDAT&(1<< 3)) == 0  );
  return 2;
 }
 else if( (rGPGDAT&(1<< 5)) == 0 )
 {
     //Delay(80);
     while( (rGPGDAT&(1<< 5)) == 0 );
    return 3 ;
 }
 else if( (rGPGDAT&(1<< 6)) == 0 )
 {
     //Delay(80);
     while( (rGPGDAT&(1<< 6)) == 0 );
     return 4 ;
 }
 else if( (rGPGDAT&(1<< 7)) == 0 )
 {
     //Delay(80);
     while( (rGPGDAT&(1<< 7)) == 0 );
      return 5 ;
 }
 else if( (rGPGDAT&(1<<11)) == 0 )
 {
    // Delay(80);
     while( (rGPGDAT&(1<<11)) == 0 );
    return 6 ;
 }
   return 0xff;

}
void  Key_ISR(void)
{
 U8 key;
 U32 r;

   OS_ENTER_CRITICAL() ;
   DisableIrq(BIT_EINT8_23);
   Delay(200);
  
 if(rINTPND==BIT_EINT8_23)
  {
  ClearPending(BIT_EINT8_23);
  
  if(rEINTPEND&(1<<8)) {
   rEINTPEND |= 1<< 8;
  }
  if(rEINTPEND&(1<<11)) {
   rEINTPEND |= 1<< 11;
  }
  if(rEINTPEND&(1<<13)) {
   rEINTPEND |= 1<< 13;
  }
  if(rEINTPEND&(1<<14)) {
  //Uart_Printf("eint11\n");
   rEINTPEND |= 1<< 14;
  }
  if(rEINTPEND&(1<<15)) {
  //Uart_Printf("eint11\n");
   rEINTPEND |= 1<< 15;
  }
  if(rEINTPEND&(1<<19)) {
  // Uart_Printf("eint19\n");  
   rEINTPEND |= 1<< 19;
  }
     key =Key_Scan();
        if(key!=0xff)
        {
           OSSemPost(Semp);
        }
  } 
  ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);
  OS_EXIT_CRITICAL() ;
  EnableIrq(BIT_EINT8_23);  
}

void KeyScan_Init(void)
{
 
 rGPGCON = rGPGCON & (~((3<<22)|(3<<6)|(3<<0)|(3<<10)|(3<<12)|(3<<14))) |
       ((2<<22)|(2<<6)|(2<<0)|(2<<10)|(2<<12)|(2<<14)) ;  //GPG11,3 set EINT
 
 rEXTINT1 &= ~(7|(7<<0)); 
 rEXTINT1 |= (2|(2<<0)); //set eint8 falling edge int
 
 rEXTINT1 &= ~(7<<12);
 rEXTINT1 |= (2<<12); //set eint11 falling edge int
 
 rEXTINT1 &= ~(7<<20);
 rEXTINT1 |= (2<<20); //set eint13 falling edge int
 rEXTINT1 &= ~(7<<24);
 rEXTINT1 |= (2<<24); //set eint14 falling edge int
 rEXTINT1 &= ~(7<<28);
 rEXTINT1 |= (2<<28); //set eint15 falling edge int
 rEXTINT2 &= ~(0xf<<12);
 rEXTINT2 |= (2<<12); //set eint19 falling edge int

 rEINTPEND |= (1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19);       //clear eint 11,19
 rEINTMASK &= ~((1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));    //enable eint11,19
 ClearPending(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);
 pISR_EINT0 = pISR_EINT2 = pISR_EINT8_23 = (U32)Key_ISR;
 EnableIrq(BIT_EINT0|BIT_EINT2|BIT_EINT8_23);   
}

以上程序,经过调试,消除了原来2440test程序中的按键连击多次进入中断中的问题,可以实现基本功能。按下按键后,蜂鸣器响一下,同时LED,亮一下。

   这里去除连击消抖,采用了按下按键,进入中断,一直等待按键释放后,再执行相应的功能,发送相应信号量给任务3。执行任务,效果还可以,不过给人的感觉是按键有点反应迟钝。此外,也可以采用进入中断后先执行任务,然后等待按键释放,这样也可以达到消除连击的问题。

 

posted on 2013-03-08 11:36  AI_JJ  阅读(531)  评论(0)    收藏  举报

导航