[ZigBee] 3、ZigBee基礎實驗——GPIO輸出控制實驗-控制Led亮滅


 

 

1、CC2530的IO口概述

  CC2530芯片有21 個數字輸入/輸出引腳,可以配置為通用數字I/O 或外設I/O 信號,配置為連接到ADC、定時器或USART外設。這些I/O 口的用途可以通過一系列寄存器配置,由用戶軟件加以實現。

  I/O 端口具備如下重要特性:

       􀁺 21 個數字I/O 引腳
    􀁺 可以配置為通用I/O 或外部設備I/O
    􀁺 輸入口具備上拉或下拉能力
    􀁺 具有外部中斷能力。


  21 個I/O 引腳都可以用作於外部中斷源輸入口。因此如果需要外部設備可以產生中斷。外部中斷功能也可以從睡眠模式喚醒設備

 

2、未使用的I/O 引腳處理

  未使用的I/O 引腳電平是確定的,不能懸空。一個方法是使引腳不連接,配置引腳為具有上拉電阻的通用I/O輸入。這也是所有引腳復位后的狀態(除了P1.0 和P1.1 沒有上拉/下拉功能)。或者引腳可以配置為通用I/O輸出。這兩種情況下引腳都不能直接連接到VDD 或GND,以避免過多的功耗

 

3、低I/O 電壓
  在數字I/O 電壓引腳DVDD1 和DVDD2 低於2.6V 的應用中,寄存器位PICTL.PADSC 應設置為1,以獲得DC 特性表中所述的輸出DC 特性。

 

4、通用I/O

  用作通用I/O 時,引腳可以組成3 個8 位端口,端口0、端口1 和端口2,表示為P0、P1 和P2。其中,P0和P1 是完全的8 位端口,而P2 僅有5 位可用。所有的端口均可以通過SFR 寄存器P0、P1 和P2 位尋址和字節尋址。每個端口引腳都可以單獨設置為通用I/O 或外部設備I/O。

  (驅動電流很重要,有時候和MOS管電路、上拉電阻的選擇等密切相關)除了兩個高驅動輸出口P1.0 和P1.1 各具備20 mA 的輸出驅動能力之外,所有的輸出均具備4 mA 的驅動能力。

  寄存器PxSEL(選擇為通用IO模式還是外設IO信號),其中x 為端口的標號0~2,用來設置端口的每個引腳為通用I/O 或者是外部設備I/O 信號。作為缺省的情況,每當復位之后,所有的數字輸入/輸出引腳都設置為通用輸入引腳。在任何時候,要改變一個端口引腳的方向,就使用寄存器PxDIR(選擇輸入或輸出)來設置每個端口引腳為輸入或輸出。因此只要設置PxDIR 中的指定位為1,其對應的引腳口就被設置為輸出了。當讀取端口寄存器P0、P1 和P2 的值,不管引腳配置如何,輸入引腳上的邏輯值都被返回。這在執行讀-修改-寫指令期間不適用。讀-修改-寫指令是:ANL,ORL,XRL,JBC,CPL,INC,DEC,DJNZ,MOV,CLR和SETB。在一個端口寄存器上操作,以下是正確的:當目標是端口寄存器P0、P1 或P2 中一個獨立的位,寄存器的值,而不是引腳上的值,被讀取、修改並寫回端口寄存器。

  用作輸入時,通用I/O 端口引腳可以設置為上拉、下拉或三態操作模式。作為缺省的情況,復位之后,所有的端口均設置為帶上拉的輸入。要取消輸入的上拉或下拉功能,就要將PxINP(輸入上拉、下拉、三態模式選擇)中的對應位設置為1。I/O 端口引腳P1.0 和P1.1 沒有上拉/下拉功能。注意配置為外設I/O 信號的引腳沒有上拉/下拉功能,即使外設功能是一個輸入。

  在電源模式PM1、PM2 和PM3 下I/O 引腳保留當進入PM1/PM2/PM3 時設置的I/O 模式和輸出值(如果可用的話)。

 

5、通用I/O 中斷

  通用I/O 引腳設置為輸入后,可以用於產生中斷。中斷可以設置在外部信號的上升或下降沿觸發。P0、P1或P2 端口都有中斷使能位,對位於IENl(端口中斷使能寄存器)寄存器內的端口所有的位都是公共的,如下:

􀁺 IENI.P0 IE:P0 中斷使能
􀁺 IEN2.PI IE:P1 中斷使能
􀁺 IEN2.P2IE:P2 中斷使能

  除了這些公共中斷使能之外,每個端口的位都有位於SFR 寄存器P0IEN、P1IEN 和P2IEN(單獨引腳中斷使能寄存器)的單獨的中斷使能。即使配置為外設I/O 或通用輸出的I/O 引腳使能時都有中斷產生。

  當中斷條件發生在I/O 引腳之一上面,P0-P2 中斷標志寄存器P0IFG、P1IFG 或P2IFG(中斷標志寄存器)中相應的中斷狀態標志將設置為1。不管引腳是否設置了它的中斷使能位,中斷狀態標志都被設置。當中斷已經執行,中斷狀態標志被清除,該標志寫入0。這個標志必須在清除CPU 端口中斷標志(PxIF)之前被清除。用於中斷的SFR 寄存器描述在下一節。寄存器總結如下:

􀁺 P0IEN: P0 中斷使能
􀁺 P1IEN: P1 中斷使能
􀁺 P2IEN: P2 中斷使能
􀁺 PICTL: P0、P1 和P2 觸發沿設置
􀁺 P0FG: P0 中斷標志
􀁺 P1IFG: P1 中斷標志
􀁺 P2IFG: P2 中斷標志

 

6、通用I/O DMA

  當用作通用I/O 引腳時,每個P0 和P2 端口都關聯一個DMA 觸發。這些DMA 觸發對於P0 為IOC_0,對於P1 為IOC_1。當一個中斷發生在P0 引腳時IOC_0 觸發是被激活的。當一個中斷發生在P1 引腳時IOC_1 觸發是被激活的。

 

7、外設I/O

  本節描述了數字I/O 引腳是如何配置為外設I/O 的。對於可以通過數字輸入/輸出引腳和外部系統接口的每個外設單元,如何配置外設I/O 的描述給定在以下小節中。

  對於USART 和定時器I/O,在一個數字I/O 引腳上選擇外設I/O 功能,需要設置對應的PxSEL 位為1。

  注意,該外部單元具有兩個可以選擇的位置對應它們的I/O 引腳,參見下表。如果有關於I/O 映射的沖突設置,可以在這些之間設置優先級(使用P2SEL.PRIxP1 和P2DIR.PRIP0 位)。所有不會導致沖突的組合都可以使用。

  注意即使沒有使用,外設一般也會出現在選定的位置,使用引腳的其他外設必須給予較高的優先級。例外情況是流量控制禁用時UART 模式下USART 的RTS 和CTS 引腳, 以及SPI 主模式下USART 配置的SSN 引腳。

  還要注意不管PxINP 的設置,有輸入引腳的外設單元是從引腳接收輸入,這可能會影響外設單元的狀態。例如如果RX 引腳在用作一個UART 引腳之前,可能已經有活動, UART 在使用之前必須被清除。

 

7.1、定時器1

  PERCFG.T1CFG 選擇是否使用備用位置1 或備用位置2。

  在上表中,定時器1 的信號顯示如下:

● 0:通道0 捕獲/比較引腳
● 1:通道1 捕獲/比較引腳
● 2:通道2 捕獲/比較引腳
● 3:通道3 捕獲/比較引腳
● 4:通道4 捕獲/比較引腳

  P2DIR.PRIP0(指派端口0一些外設的優先順序)選擇為端口0 指派一些外設的優先順序。當設置為10,定時器通道0-1 優先,當設置為11,定時器通道2-3 優先。要所有定時器1 通道在備用位置1 上可見,移動USART 0 和USART 1 到備用位置2。P2SEL.PRI1P1 和P2SEL.PRI0P1(外設優先級設置)選擇為端口1 指派一些外設的優先順序。當前者設置為低電平而后者設置為高電平時,定時器1 通道優先。

 

 

7.2、定時器3

  PERCFG.T3CFG 選擇是否使用備用位置1 或備用位置2。

  在表中,定時器3 的信號顯示如下:

● 0:通道0 比較引腳
● 1:通道1 比較引腳

  P2SEL.PRI2P1 和P2SEL.PRI3P1 選擇為端口1 指派一些外設的優先順序。當這兩個位都設置為高電平時,定時器3 通道優先。如果P2SEL.PRI2P1 設置為高電平且P2SEL.PRI3P1 設置為低電平時,定時器3 通道優先於USART 1,但是USART 0 優先於定時器3 通道以及USART 1。

 

 

7.3、定時器4

  PERCFG.T4CFG 選擇是否使用備用位置1 或備用位置2。

  在表中,定時器4 的信號顯示如下:

● 0:通道0 比較引腳
● 1:通道1 比較引腳

  P2SEL.PRI1P1 選擇為端口1 指派一些外設的優先順序。當這個位設置時,定時器4 通道優先。

 

 

7.4、USART 0

  SFR 寄存器位PERCFG.U0CFG 選擇是否使用備用位置1 或備用位置2。

  在表中,USART 0 信號顯示如下:

UART:
● RX:RXDATA
● TX:TXDATA
● RT:RTS
● CT:CTS


SPI:
● MI:MISO
● MO:MOSI
● C:SCK
● SS:SSN

  P2DIR.PRIP0 選擇為端口0 指派一些外設的優先順序。當設置為00 時,USART 0 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,UART 1 或定時器1 將優先使用端口P0.4 和P0.5。P2SEL.PRI3P1 和P2SEL.PRI0P1 選擇為端口1 指派一些外設的優先順序。當它們兩個都設置為0 時,USART0 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,定時器1 或定時器3 將優先使用端口P1.2 和P1.3。

 

 

7.5、USART 1

  SFR 寄存器位PERCFG.U1CFG 選擇是否使用備用位置1 或備用位置2。

  在表中,USART 1 信號顯示如下:

UART:
● RX:RXDATA
● TX:TXDATA
● RT:RTS
● CT:CTS


SPI:
● MI:MISO
● MO:MOSI
● C:SCK
● SS: SSN

  P2DIR.PRIP0 選擇為端口0 指派一些外設時的優先順序。當設置為01,USART 1 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,USART 0 或定時器1 將優先使用P0.2 和P0.3。P2SEL.PRI3P1 和P2SEL.PRI2P1 選擇為端口1 指派一些外設的優先順序。當前者設置為1 而后者設置為0時,USART 1 優先。注意如果選擇了UART 模式,且硬件流量控制禁用,USART 0 或定時器3 將優先使用P1.4和P1.5。

 

 

7.6、ADC

  當使用ADC 時,端口0 引腳必須配置為ADC 輸入。可以使用多達八個ADC 輸入引腳。要配置一個端口0引腳為一個ADC 輸入,APCFG 寄存器中相應的位必須設置為1。這個寄存器的默認值選擇端口0 引腳為非ADC輸入,即數字輸入/輸出。

  APCFG 寄存器的設置將覆蓋P0SEL的設置。

  ADC 可以配置為使用通用I/O 引腳P2.0 作為內部觸發器來啟動轉換。當用作ADC 內部觸發器時,P2.0 必須在輸入模式下配置為通用I/O。

 

 

7.7、調試接口

  端口P2.1 和P2.2 分別用於調試數據和時鍾信號。這些顯示為表中的DD(調試數據)和DC(調試時鍾)。當處於調試模式,調試接口控制這些引腳的方向。當處於調試模式在這些引腳上禁用上拉/下拉。

 


7.8、32 kHz XOSC 輸入

  端口P2.3 和P2.4 用於連接一個外部32 kHz 晶振。當CLKCONCMD.OSC32K 是低電平時,不管寄存器設置如何,這些端口引腳由32 kHz XOSC 使用。當CLKCONCMD.OSC32K 是低電平,這些端口引腳將設置在模擬模式。


7.9 無線測試輸出信號

  通過使用OBSSELx 寄存器(OBSSEL0-OBSSEL5),用戶可以從RF 內核輸出不同的信號到GPIO 引腳。這些信號可以用於調試低級別的協議或控制外部PA、LNA 或交換機。控制寄存器OBSSEL0-OBSSEL5 可以用於覆蓋標准的GPIO 行為,以及在引腳P1[0:5]上輸出RF 內核信號(rfc_obs_sig0、rfc_obs_sig1 和rfc_obs_sig2)。可用信號的列表見第19 章。


7.10、掉電信號MUX (PMUX)

  PMUX 寄存器可以用於輸出32 kHz 時鍾和/或數字穩壓器的狀態。所選的32 kHz 時鍾源可以輸出在P0 其中的一個引腳上。使能位CKOEN 使得輸出在P0 上,使用CKOPIN(詳細信息見PMUX 寄存器描述)選擇P0 的引腳。當CKOEN 被設置,所選引腳的所有其他配置都被覆蓋。時鍾在所有供電模式下都輸出;但是,在PM3 下時鍾停止(見第4 章的PM3)。而且,數字穩壓器的狀態可以輸出在P1 其中的一個引腳上。當DREGSTA 位被設置,數字穩壓器的狀態就被輸出。DREGSTAPIN 選擇P1 引腳(詳細信息見PMUX 寄存器描述)。當DREGSTA 被設置,所選引腳的所有其他配置都被覆蓋。當1.8V 片上數字穩壓器上電(芯片有調整過的電壓),所選的引腳輸出1。當1.8V片上數字穩壓器掉電,即在PM2 和PM3 下,所選的引腳輸出0。

 

7.11 I/O 引腳

  I/O 端口的寄存器描述在本節中。寄存器如下:

● P0 :端口0

● P1 :端口1
● P2 :端口2
● PERCFG :外設控制寄存器
● APCFG :模擬外設I/O 配置
● P0SEL :端口0 功能選擇寄存器
● P1SEL :端口1 功能選擇寄存器
● P2SEL :端口2 功能選擇寄存器
● P0DIR :端口0 方向寄存器
● P1DIR :端口1 方向寄存器
● P2DIR :端口2 方向寄存器
● P0INP :端口0 輸入模式寄存器
● P1INP :端口1 輸入模式寄存器
● P2INP :端口2 輸入模式寄存器
● P0IFG :端口0 中斷狀態標志寄存器
● P1IFG :端口1 中斷狀態標志寄存器
● P2IFG :端口2 中斷狀態標志寄存器
● PICTL :中斷邊緣寄存器
● P0IEN :端口0 中斷掩碼寄存器
● P1IEN :端口1 中斷掩碼寄存器
● P2IEN :端口2 中斷掩碼寄存器
● PMUX :掉電信號Mux 寄存器
● OBSSEL0 :觀察輸出控制寄存器0
● OBSSEL1 :觀察輸出控制寄存器1
● OBSSEL2 :觀察輸出控制寄存器2
● OBSSEL3 :觀察輸出控制寄存器3
● OBSSEL4 :觀察輸出控制寄存器4
● OBSSEL5 :觀察輸出控制寄存器5

 

 

8、隔一秒閃爍例程(引腳輸出控制)

  下面代碼是控制P1_0引腳上的LED每隔1s閃爍一次的實驗。黃色部分P1DIR用來設置P1的8個端口的每個的輸入輸出方向。

 

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 作    者: Andy
 4 * 修    訂: 2013-01-08
 5 * 版    本: 1.0
 6 * 描    述: GPIO輸出控制實驗1 操作IO口控制LED燈的亮和滅
 7 ****************************************************************************/
 8 #include <ioCC2530.h>
 9 
10 typedef unsigned char uchar;
11 typedef unsigned int  uint;
12 
13 #define LED1 P1_0                //定義P1.0口為LED1控制端
14 
15 
16 /****************************************************************************
17 * 名    稱: DelayMS()
18 * 功    能: 以毫秒為單位延時,系統時鍾不配置時默認為16M(用示波器測量相當精確)
19 * 入口參數: msec 延時參數,值越大,延時越久
20 * 出口參數: 無
21 ****************************************************************************/
22 void DelayMS(uint msec)
23 { 
24     uint i,j;
25     
26     for (i=0; i<msec; i++)
27         for (j=0; j<535; j++);
28 }
29 
30 /****************************************************************************
31 * 名    稱: InitLed()
32 * 功    能: 設置LED燈相應的IO口
33 * 入口參數: 無
34 * 出口參數: 無
35 ****************************************************************************/
36 void InitLed(void) 37 { 38 P1DIR |= 0x01; //P1.0定義為輸出口 39 } 40 
41 /****************************************************************************
42 * 程序入口函數
43 ****************************************************************************/
44 void main(void)
45 {     
46     InitLed();                   //設置LED燈相應的IO口
47 
48     while(1)                     //死循環
49     {
50         LED1 = 0;                //點亮LED1      
51         DelayMS(1000);           //延時1秒
52 
53         LED1 = 1;                //LED1熄滅
54         DelayMS(1000);           //延時1秒
55     }    
56 }

上面的例子是控制1個引腳,下面的流水燈例子展示了同時控制3個引腳,其實大同小異:

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 作    者: Andy
 4 * 修    訂: 2013-01-08
 5 * 版    本: 1.0
 6 * 描    述: 操作IO口控制3盞LED燈的全亮和全滅、閃爍、流水燈
 7 ****************************************************************************/
 8 #include <ioCC2530.h>
 9 
10 typedef unsigned char uchar;
11 typedef unsigned int  uint;
12 
13 #define LED1 P1_0       //定義P1.0口為LED1控制端
14 #define LED2 P1_1       //定義P1.1口為LED2控制端
15 #define LED3 P1_4       //定義P1.4口為LED3控制端
16 
17 
18 /****************************************************************************
19 * 名    稱: DelayMS()
20 * 功    能: 以毫秒為單位延時,系統時鍾不配置時默認為16M(用示波器測量相當精確)
21 * 入口參數: msec 延時參數,值越大,延時越久
22 * 出口參數: 無
23 ****************************************************************************/
24 void DelayMS(uint msec)
25 { 
26     uint i,j;
27     
28     for (i=0; i<msec; i++)
29         for (j=0; j<535; j++);
30 }
31 
32 /****************************************************************************
33 * 名    稱: LedOnOrOff()
34 * 功    能: 點亮或熄滅所有LED燈    
35 * 入口參數: mode為0時LED燈亮  mode為1時LED燈滅
36 * 出口參數: 無
37 ****************************************************************************/
38 void LedOnOrOff(uchar mode)
39 {
40     LED1 = mode;
41     LED2 = mode;
42     LED3 = mode; //由於P1.4與仿真器共用,必須拔掉仿真器的插頭才能看到LED3的變化
43 }
44 
45 /****************************************************************************
46 * 名    稱: InitLed()
47 * 功    能: 設置LED燈相應的IO口
48 * 入口參數: 無
49 * 出口參數: 無
50 ****************************************************************************/
51 void InitLed(void)
52 {
53     P1DIR |= 0x13;      //P1.0、P1.1、P1.4定義為輸出
54     LedOnOrOff(1);      //使所有LED燈默認為熄滅狀態
55 }
56 
57 /****************************************************************************
58 * 程序入口函數
59 ****************************************************************************/
60 void main(void)
61 {
62     uchar i;
63     
64     InitLed();               //設置LED燈相關IO口
65     
66     while(1)                 //死循環
67     {  
68         LED1 = !LED1;         //流水燈,初始化時LED為熄滅執行后則點亮
69         DelayMS(200);         
70         LED2 = !LED2;         
71         DelayMS(200);            
72         LED3 = !LED3;        
73         DelayMS(200);     
74         
75         for (i=0; i<2; i++)  //所有燈閃爍2次
76         {
77            LedOnOrOff(1);    //關閉所有LED燈
78            DelayMS(200);
79            LedOnOrOff(0);    //打開所有LED燈
80            DelayMS(200);
81         }
82         
83         LedOnOrOff(1);       //使所有LED燈熄滅狀態
84         DelayMS(500);
85     }
86 }
流水燈例子

 

 

9、按鍵控制LED亮滅(外部信號輸入讀取)

  外設電路圖如下,P10低電平時LED亮,按鍵沒有按下P01為高電平,按下為低電平:

 

 

  這里重點講P01按鍵信號讀取的設置:黃色部分P0SEL將P01設置為通用IO:

  

  P0DIR將P01設置為輸入模式:

 

  P0INP打開P01上的上拉電阻:

 

  這里讀取一個引腳的狀態,和讀取51單片機一個引腳狀態一樣,比較簡單~

 1 /****************************************************************************
 2 * 文 件 名: main.c
 3 * 作    者: Andy
 4 * 修    訂: 2013-01-08
 5 * 版    本: 1.0
 6 * 描    述: 按下按鍵S1控制LED1燈亮和滅
 7 ****************************************************************************/
 8 #include <ioCC2530.h>
 9 
10 typedef unsigned char uchar;
11 typedef unsigned int  uint;
12 
13 #define LED1 P1_0       // P1.0口控制LED1
14 #define KEY1 P0_1       // P0.1口控制S1
15 
16 /****************************************************************************
17 * 名    稱: DelayMS()
18 * 功    能: 以毫秒為單位延時,系統時鍾不配置時默認為16M(用示波器測量相當精確)
19 * 入口參數: msec 延時參數,值越大,延時越久
20 * 出口參數: 無
21 ****************************************************************************/
22 void DelayMS(uint msec)
23 { 
24     uint i,j;
25     
26     for (i=0; i<msec; i++)
27         for (j=0; j<535; j++);
28 }
29 
30 /****************************************************************************
31 * 名    稱: InitLed()
32 * 功    能: 設置LED相應的IO口
33 * 入口參數: 無
34 * 出口參數: 無
35 ****************************************************************************/
36 void InitLed(void)
37 {
38     P1DIR |= 0x01;      // P1.0定義為輸出
39     LED1 = 1;           // LED1燈熄滅     
40 }
41 
42 /****************************************************************************
43 * 名    稱: InitKey()
44 * 功    能: 設置按鍵相應的IO口
45 * 入口參數: 無
46 * 出口參數: 無
47 ****************************************************************************/
48 void InitKey(void) 49 { 50 P0SEL &= ~0x02; //設置P0.1為普通IO口  51 P0DIR &= ~0x02; //按鍵接在P0.1口上,設P0.1為輸入模式  52 P0INP &= ~0x02; //打開P0.1上拉電阻 53 } 54 
55 /****************************************************************************
56 * 名    稱: KeyScan()
57 * 功    能: 讀取按鍵狀態
58 * 入口參數: 無
59 * 出口參數: 0為抬起   1為按鍵按下
60 ****************************************************************************/
61 uchar KeyScan(void) 62 { 63 if (KEY1 == 0) 64  { 65 DelayMS(10); 66 if (KEY1 == 0) 67  { 68 while(!KEY1); //松手檢測 69 return 1; //有按鍵按下 70  } 71  } 72 73 return 0; //無按鍵按下 74 } 75 
76 /****************************************************************************
77 * 程序入口函數
78 ****************************************************************************/
79 void main(void)
80 {
81     InitLed();              //設置LED1相應的IO口
82     InitKey();            //設置S1相應的IO口
83     
84     while(1)
85     {
86         if (KeyScan())    //按鍵按下則改變LED狀態
87             LED1 = ~LED1;       
88     }
89 }

 

小結

  本篇幾乎把和IO相關的寄存器全部介紹完了,最后又介紹了簡單的IO輸入輸出的控制,一個是流水燈,一個是按鍵讀取,接下來會介紹IO的更多功能~

 

 

系列:

[ZigBee] 1、 ZigBee簡介

[ZigBee] 2、 ZigBee開發環境搭建

 

PS:如果您覺得還不錯,點個贊,讓更多人受益~

@beautifulzzzz 2016-07-10 continue~  
e-mail:beautifulzzzz@qq.com
sina:http://weibo.com/beautifulzzzz?is_all=1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM