7天快速入門Zigbee:如何在協議棧中添加中斷處理程序
1. 概述
這篇文章主要是想讓大家瞭解如何在協議棧中添加中斷處理函數。
2. 如何在協議棧中添加中斷處理程序
我們先看一下Z-Stack Mesh協議棧“_hal_uart_isr.c”文件中關於串口0的接收中斷處理程序:
/***************************************************************************************************
* @fn halUartRxIsr
* @brief UART Receive Interrupt
* @param None
* @return None
***************************************************************************************************/
HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
{
uint8 tmp = UxDBUF;
isrCfg.rxBuf[isrCfg.rxTail] = tmp;
// Re-sync the shadow on any 1st byte received.
if (isrCfg.rxHead == isrCfg.rxTail)
{
isrCfg.rxShdw = ST0;
}
if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
{
isrCfg.rxTail = 0;
}
isrCfg.rxTick = HAL_UART_ISR_IDLE;
}
其中函數頭“HAL_ISR_FUNCTION”部分是個宏定義,其直接展開爲:
#define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)
這裏面有兩部分代碼“HAL_ISR_FUNC_PROTOTYPE”和“HAL_ISR_FUNC_DECLARATION”,第一部分代碼爲“函數聲明”,第二部分代碼爲函數原型。這兩部分的代碼展開皆爲“_PRAGMA(vector=v) __near_func __interrupt void f(void)”,現在我們將“HAL_ISR_FUNCTION”部分完全展開可得下列程序:
// 函數聲明
_PRAGMA(vector= URX0_VECTOR) __near_func __interrupt void halUart0RxIsr (void);
// 函數原型
_PRAGMA(vector= URX0_VECTOR) __near_func __interrupt void halUart0RxIsr (void)
{
uint8 tmp = UxDBUF;
isrCfg.rxBuf[isrCfg.rxTail] = tmp;
// Re-sync the shadow on any 1st byte received.
if (isrCfg.rxHead == isrCfg.rxTail)
{
isrCfg.rxShdw = ST0;
}
if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
{
isrCfg.rxTail = 0;
}
isrCfg.rxTick = HAL_UART_ISR_IDLE;
}
其中“_PRAGMA”是編譯器預定義聲明中斷服務程序的一個方法,“URX0_VECTOR”是中斷編號,其在“ioCC2530.h”文件中定義。“halUart0RxIsr”是“HAL_ISR_FUNCTION(f,v)”中“f”所指的函數,也就是我們的中斷服務函數。
_PRAGMA(URX0_VECTOR) // 定義中斷向量
__near_func // IAR的特殊字
__interrupt // 中斷函數標誌
void halUart0RxIsr(void); // halUart0RxIsr函數名
3. 實例:寫一個P1_2的外部中斷處理函數
根據協議棧定義串口0接收中斷處理函數的方法,我們可以模仿寫一個P1_2的外部中斷處理函數。
HAL_ISR_FUNCTION( P1_ISR, P1INT_VECTOR )
{
// 進入中斷程序,保存 EA 寄存器狀態,開啓 EA
HAL_ENTER_ISR();
// 清除端口1中斷標誌
IRCON2 &= ~(1<<3);
// 如果是 P1_2 的中斷
if(P1IFG&0x04)
{
// 清除 P1_2 口中斷標誌
P1IFG &= ~(1<<2);
// 處理 P1_2 中斷事件
}
// 退出中斷程序,恢復 EA 寄存器狀態
HAL_EXIT_ISR();
}
4. 中斷向量
ioCC2530.h
/* ------------------------------------------------------------------------------------------------
* Interrupt Vectors
* ------------------------------------------------------------------------------------------------
*/
#define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO Underflow and RX FIFO Overflow */
#define ADC_VECTOR VECT( 1, 0x0B ) /* ADC End of Conversion */
#define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX Complete */
#define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX Complete */
#define ENC_VECTOR VECT( 4, 0x23 ) /* AES Encryption/Decryption Complete */
#define ST_VECTOR VECT( 5, 0x2B ) /* Sleep Timer Compare */
#define P2INT_VECTOR VECT( 6, 0x33 ) /* Port 2 Inputs */
#define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX Complete */
#define DMA_VECTOR VECT( 8, 0x43 ) /* DMA Transfer Complete */
#define T1_VECTOR VECT( 9, 0x4B ) /* Timer 1 (16-bit) Capture/Compare/Overflow */
#define T2_VECTOR VECT( 10, 0x53 ) /* Timer 2 (MAC Timer) */
#define T3_VECTOR VECT( 11, 0x5B ) /* Timer 3 (8-bit) Capture/Compare/Overflow */
#define T4_VECTOR VECT( 12, 0x63 ) /* Timer 4 (8-bit) Capture/Compare/Overflow */
#define P0INT_VECTOR VECT( 13, 0x6B ) /* Port 0 Inputs */
#define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX Complete */
#define P1INT_VECTOR VECT( 15, 0x7B ) /* Port 1 Inputs */
#define RF_VECTOR VECT( 16, 0x83 ) /* RF General Interrupts */
#define WDT_VECTOR VECT( 17, 0x8B ) /* Watchdog Overflow in Timer Mode */
大家的支持就是我分享技術的動力,希望大家需轉載時能附上原作者的博客:https://blog.csdn.net/u012993936,謝謝。