目錄設計模式
由上圖可知,Zigbee模塊的SW1按鈕鏈接在P1.2端口上,當SW1導通,P1.2電平從3.3V被拉低接地。因此P1.2輸入模式爲下拉輸入.api
寄存器名稱 | 寄存器做用 | 寄存器描述 |
---|---|---|
P1 (0x90) | *控制端口1的高低電平 | 端口1.通用I/O。能夠經過SFR位尋址 |
P1SEL (0xF4) | 端口1 8個子端口的功能選擇 | P1SEL的8個bit分別表明 => P1.7~P1.0的功能選擇. 值爲 0:表明通用I/0(GPIO)功能. 值爲 1 : 表明外設功能 |
P1DIR (0xFE) | 端口1 輸入輸出選擇 | P1DIR的bit定義同P1SEL; 值爲 0:表明從外部輸入信號至CC2530; 值爲 1:表明從CC2530輸出信號至外部 |
P1INP (0xF6) | 端口1 輸入模式選擇 | P1INP定義爲P1.7~P1.2的I/O輸入模式。其中P1.0和P1.1是沒有上拉/下拉功能。 值爲 0:上拉/下拉。 值爲 1:三態(高電平、低電平、高阻態) |
P2INP (0xINP) | 端口2 輸入模式及其它端口選擇 | P2INP比較特殊,由於P2端口引出的引腳只有3個,因此P2INP還有其它功能。 bit 0 ~ 4 : P2.4~P2.0的輸入模式。 0 : 上拉/下拉; 1:三態 bit 5 : 設置端口0上拉/下拉選擇。對端口P0上面的全部引腳設置爲上拉/下拉輸入 0 : 上拉; 1 : 下拉 bit 6 : 同bit 5功能,可是是設置端口1上全部引腳 bit 7 : 同bit5功能,可是是設置端口2上的全部引腳 |
P1IEN (0x8D) | 端口1 中斷屏蔽 | 端口P1.7~P1.0的中斷使能(也就是說中斷是否Enable*(打開)) 0 : 中斷禁用 1 : 中斷使能 |
PICTL (0x8C) | 端口中斷控制 P0ICON(bit0) | 端口0、一、2輸入模式下的中斷配置。 0 : 輸入的上升沿引發中斷 1 : 輸入的降低沿引發中斷 |
P1IFG (0x8A) | 端口0 中斷狀態標誌 | 端口0,bit7 ~ 0輸入中斷狀態標誌。當輸入端口中斷請求後,其相應的標誌位將會被置爲1. |
IEN2 (0x9A) | 中斷使能1 P0IE(bit5) | 端口1中斷使能 0 : 中斷禁止 1 : 中斷使能 |
EA | 中斷的總開關 | 只有打開該開關,中斷才能傳入51芯片 0 : 中斷禁止 1 : 中斷使能 |
如上圖所示,若是P1端口發生中斷,須要傳入51內核中,流程以下圖所示.函數
因此,咱們對中斷進行初始化的一個流程也和上圖同樣,一層一層的將中斷使能開關打開。學習
使用C語言爲51單片機編寫中斷程序,有一個特殊的函數聲明形式。如如下代碼所示:ui
#pragma vector = 中斷向量地址 __interrupt void P01_ISR(void) { /*Do something*/ }
其中中斷向量地址,能夠在ioCC2530.h頭文件中找到,能夠直接使用宏定義字符替換。加密
/* -------------------------------------------------------------------------- * Interrupt Vectors * -------------------------------------------------------------------------- */ #define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO下溢和RX FIFO溢出*/ #define ADC_VECTOR VECT( 1, 0x0B ) /* ADC轉換結束*/ #define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX完成*/ #define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX完成*/ #define ENC_VECTOR VECT( 4, 0x23 ) /* AES加密/解密完成*/ #define ST_VECTOR VECT( 5, 0x2B ) /* 睡眠定時器比較*/ #define P2INT_VECTOR VECT( 6, 0x33 ) /* 端口2輸入*/ #define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX完成*/ #define DMA_VECTOR VECT( 8, 0x43 ) /* DMA傳輸完成*/ #define T1_VECTOR VECT( 9, 0x4B ) /* 定時器1(16位)捕捉/比較/溢出 */ #define T2_VECTOR VECT( 10, 0x53 ) /* 定時器2(MAC定時器)*/ #define T3_VECTOR VECT( 11, 0x5B ) /* 定時器3(8位)捕捉/比較/溢出*/ #define T4_VECTOR VECT( 12, 0x63 ) /* 定時器4(8位)捕捉/比較/溢出*/ #define P0INT_VECTOR VECT( 13, 0x6B ) /* 端口0輸入*/ #define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX完成*/ #define P1INT_VECTOR VECT( 15, 0x7B ) /* 端口1輸入*/ #define RF_VECTOR VECT( 16, 0x83 ) /* 射頻通用中斷*/ #define WDT_VECTOR VECT( 17, 0x8B ) /* 定時器模式下看門狗溢出*/
本節爲選擇學習內容,是筆者在學習按鍵中斷時,思考的一個問題。想實現高級語言中事件機制,在高級語言中事件主要是靠方法指針和觀察者設計模式一併完成。方法指針就是一個指向方法的指針。而C語言中的指針同樣能夠指向一個函數。如:設計
例1,簡單的事件實現,函數指針。
#include <ioCC2530.h> typedef unsigned int uint; /************************/ void (*timer_ow)(); // 定義一個返回值爲void參數爲空的函數指針 int (*timer_ow1)(); // 定義一個返回值爲int參數爲void的函數指針 int (*timer_ow2)(int); // 定義一個返回值爲int參數爲int的函數指針 /************************/ void timer_Overflow(void) { /*Do something*/ } int timer_Overflow1(void) { /*Do something*/ } int timer_Overflow2(int z) { /*Do something*/ } void main(void) { // 將函數timer_Overflow賦值給函數指針timer_ow timer_ow = timer_Overflow; // 調用函數指針 (*timer_ow)(); timer_ow1 = timer_Overflow1; int result = (*timer_ow1)(); timer_ow2 = timer_Overflow2; result = (*timer_ow2)(result); }
#include <ioCC2530.h> // 初始化通用端口 void init_gpio(void) { // 將p1_0,1,2設置成GPIO P1SEL &=~ 0x07; // 將p1_0,1設置成輸出 P1DIR |= 0x03; // 將p1_2設置成輸入 P1DIR &=~ 0x04; // 下拉P1所有端口,使LED全滅 P1 = 0x00; // 設置端口1爲上下拉功能 P1INP &=~ 0x04; // 設置端口1輸入模式爲上拉 P2INP &=~ 0x40; } // 初始化通用端口中斷 void init_gpio_interrupt(void) { // 將P1設置爲輸入降低沿引發中斷 PICTL |= 0x02; // 設置P1引腳2爲中斷使能 P1IEN |= 0x04; // 設置端口P1爲中斷使能 IEN2 |= 0x10; // 打開中斷總開關 EA = 1; //清空中斷標誌 P1IFG = 0; P1IF = 0; } #pragma vector = P1INT_VECTOR __interrupt void P1_ISR(void) { // 判斷中斷信號是否從P1.2 SW1引腳發生 if(P1IFG == 0x04) { // 讓LED翻轉 P1_0 = ~P1_0; P1_1 = ~P1_1; } // 清空中斷標誌 P1IFG = 0; P1IF = 0; } void main() { init_gpio(); init_gpio_interrupt(); while(1){;} }
代碼並無特別困難的地方,根據前面的預備知識和流程圖基本能夠看得懂。指針