实现功能:按下案件后,蜂鸣器响一声,同时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。执行任务,效果还可以,不过给人的感觉是按键有点反应迟钝。此外,也可以采用进入中断后先执行任务,然后等待按键释放,这样也可以达到消除连击的问题。