TI-RTOS 之 GPIO中斷(按鍵)
前面已經用過LED, 定時器,這次來了解GPIO的中斷是怎么用的,從CC1310+TI-RTOS的例程可以直接找到相應的例子程序,它的關鍵是在於要使能中斷,也就是在引腳配置時要選擇方向為輸入(PIN_INPUT_EN), 中斷選項為(PIN_IRQ_NEGEDGE)下降沿有效。代碼如下:
/*
* Application button pin configuration table:
* - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
Board_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
Board_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
在初始化之后,還要注冊中斷回調函數,應用TI-RTOS就不能再去寫中斷函數了,而使用回調函數,這個回調函數就相當於中斷函數的一個子函數了。它的寫法是:
/**************************************************************************************************
* @fn buttonCallbackFxn
*
* @brief 按鍵中斷的回調函數
*
* @param PIN_Handle handle, PIN_Id pinId
*
* @return void
**************************************************************************************************/
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId)
{
uint_t ledState;
/* Debounce logic, only toggle if the button is still pushed (low) */
CPUdelay(8000*50);
// 延時之后再次讀 IO, 仍然為低則按鍵有效
if (!PIN_getInputValue(pinId))
{
// 不同的按鍵控制不同的燈
if ( pinId == Board_BUTTON0 )
{
ledState = PIN_getOutputValue(Board_LED0);
PIN_setOutputValue(ledPinHandle, Board_LED0, !ledState);
}
else if ( pinId == Board_BUTTON1 )
{
ledState = PIN_getOutputValue(Board_LED1);
PIN_setOutputValue(ledPinHandle, Board_LED1, !ledState);
}
}
}
這里將按鍵的觸發和執行都寫在回調函數了,看起來比較簡單些,在實際應用中,可能是得到按鍵鍵值並傳遞到應用的任務或者菜單任務。
最后是演示任務的整體代碼:
/**************************************************************************************************
Filename: keyDemo.c
Editor: Tome @ newbit
Revised: $Date: 2016-8-10 11:20:02 +0800 $
Revision: $Revision: 00001 $
Description: 了解 TI-RTOS的使用之,IO中斷【按鍵】
History:
Notes: 要了解到這部分的接口,可閱讀TI文檔
1. TI-RTOS 2.20 User's Guide.pdf
2. Bios User Guide.pdf
硬件平台 CC1130_LAUNCHPAD Rev1.3
**************************************************************************************************/
/**************************************************************************************************
// INCLUDES
**************************************************************************************************/
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include "Board.h"
/**************************************************************************************************
// TYPEDEF
**************************************************************************************************/
/**************************************************************************************************
// CONSTANTS
**************************************************************************************************/
#define TASKSTACKSIZE 768
/**************************************************************************************************
// LOCAL VERIABLE
**************************************************************************************************/
Task_Struct keyTaskStruct;
Char keyTaskStack[TASKSTACKSIZE]; // 本任務的棧空間,靜態分配
/* Global memory storage for a PIN_Config table */
static PIN_State ledPinState;
static PIN_State buttonPinState;
PIN_Handle ledPinHandle;
PIN_Handle buttonPinHandle;
/*
* Initial LED pin configuration table
* - LEDs Board_LED0 is on.
* - LEDs Board_LED1 is off.
*/
PIN_Config ledPinTable[] = {
Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/*
* Application button pin configuration table:
* - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
Board_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
Board_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
/**************************************************************************************************
// FUNCTIONS DECLERATION
**************************************************************************************************/
Void keyFxn(UArg arg0, UArg arg1);
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId);
/**************************************************************************************************
// FUNCTIONS
**************************************************************************************************/
/**************************************************************************************************
* @fn keyTaskAdd
*
* @brief
*
* @param void
*
* @return void
**************************************************************************************************/
void keyTaskAdd(void)
{
Task_Params taskParams;
/* Construct BIOS objects */
Task_Params_init(&taskParams); // 創建任務所要的參數,都設置為默認值
taskParams.stackSize = TASKSTACKSIZE; // 棧空間
taskParams.stack = &keyTaskStack; // 棧地址
// 向bios 傳遞參數,建立控制燈的任務
Task_construct(&keyTaskStruct, (Task_FuncPtr)keyFxn, &taskParams, NULL);
}
/*
* ======== keyFxn ========
* Task for this function is created statically. See keyTaskAdd().
*/
Void keyFxn(UArg arg0, UArg arg1)
{
// 這里不是為了初始化,而是為了拿到操作的句柄 (handle)
// 函數說明:Allocate one or more pins for a driver or an application.
ledPinHandle = PIN_open(&ledPinState, ledPinTable);
if(!ledPinHandle) {
System_abort("Error initializing board LED pins\n");
}
// 得到按鍵IO的操作句柄
buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
if(!buttonPinHandle) {
System_abort("Error initializing button pins\n");
}
/* Setup callback for button pins */
// 注冊按鍵的中斷回調函數
if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
System_abort("Error registering button callback function");
}
//任務只有休眠
while(1)
{
// 任務休眠 1 秒, 1000000us, 下面函數的單位是10us
Task_sleep(100000);
}
}
/**************************************************************************************************
* @fn buttonCallbackFxn
*
* @brief 按鍵中斷的回調函數
*
* @param PIN_Handle handle, PIN_Id pinId
*
* @return void
**************************************************************************************************/
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId)
{
uint_t ledState;
/* Debounce logic, only toggle if the button is still pushed (low) */
CPUdelay(8000*50);
// 延時之后再次讀 IO, 仍然為低則按鍵有效
if (!PIN_getInputValue(pinId))
{
// 不同的按鍵控制不同的燈
if ( pinId == Board_BUTTON0 )
{
ledState = PIN_getOutputValue(Board_LED0);
PIN_setOutputValue(ledPinHandle, Board_LED0, !ledState);
}
else if ( pinId == Board_BUTTON1 )
{
ledState = PIN_getOutputValue(Board_LED1);
PIN_setOutputValue(ledPinHandle, Board_LED1, !ledState);
}
}
}
/**************************************************************************************************
Copyright 2016 Newbit Studio. All rights reserved.
**************************************************************************************************/