《Zigbee開發(fā)技術及實踐》課件第4章_第1頁
《Zigbee開發(fā)技術及實踐》課件第4章_第2頁
《Zigbee開發(fā)技術及實踐》課件第4章_第3頁
《Zigbee開發(fā)技術及實踐》課件第4章_第4頁
《Zigbee開發(fā)技術及實踐》課件第4章_第5頁
已閱讀5頁,還剩420頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第4章CC2530基礎開發(fā)4.1概述 4.2CC2530的結構框架4.3CC2530編程基礎4.4I/O4.5振蕩器和時鐘4.6電源管理和復位4.7串口4.8DMA4.9ADC4.10定時器

掌握I/O的使用。

理解存儲器與映射的關系。

掌握ADC的使用方法。

掌握串口和DMA的使用方法。

掌握定時器的使用。

【描述4.D.】

通過掃描方式實現(xiàn)按鍵觸發(fā)LED亮滅。

【描述4.D.2】

通過外部中斷來改變LED亮滅。

【描述4.D.3】

初始化系統(tǒng)時鐘。

【描述4.D.4】

串口發(fā)送數據。

【描述4.D.5】

串口接收數據控制LED亮滅。

【描述4.D.6】

將字符數組sourceString的內容通過DMA傳輸到字符數組destString中,通過串口在PC機顯示結果。

【描述4.D.7】

將AVDD(3.3V)AD轉換,通過串口在PC機顯示結果。

【描述4.D.8】

定時器1溢出標志控制LED亮滅。

【描述4.D.9】

定時器2中斷控制LED亮滅。

【描述4.D.10】

用定時器3自由模式溢出中斷控制LED亮滅。

CC2530是TI公司推出的用來實現(xiàn)嵌入式Zigbee應用的片上系統(tǒng),它支持2.4

GIEEE802.15.4/Zigbee協(xié)議。根據芯片內置閃存的不同容量,提供給用戶4個版本,即CC2530F32/64/128/256,4.1概述分別具有32

KB/64

KB/128

KB/256

KB的內置閃存。CC2530F256結合了TI業(yè)界領先的Zigbee協(xié)議棧(Zstack),提供了一個強大的完整的Zigbee解決方案。另外,CC2530F64還提供了一個強大的和完整的ZigbeeRF4CE(消費電子射頻通信標準)遠程控制解決方案。

CC2530芯片的特點如下:

高性能、低功耗的8051微控制器內核。

適應2.4

GHzIEEE802.15.4的RF收發(fā)器。極高的接收靈敏度和抗干擾性。

32

KB/64

KB/128

KB/256

KB閃存。

8

KBSRAM,具備各種供電方式下的數據保持能力。

強大的DMA功能。

只需極少的外接元件,即可形成一個簡單的應用系統(tǒng)。

只需一個晶振,即可滿足網狀型網絡系統(tǒng)的需要。

低功耗,主動模式RX(CPU空閑):24

mA;

主動模式TX在1

dB(CPU空閑):29

mA;

供電模式1(4

μs喚醒):0.2

mA;供電模式2(睡眠定時器運行):1

μA;

供電模式3(外部中斷):0.4

μA;

寬電源電壓范圍為2~3.6

V。

硬件支持CSMA/CA。

支持數字化的接收信號強度指示器/鏈路質量指示(RSSI/LQI)。

具有8路輸入8~14位ADC。

高級加密標準AES協(xié)處理器。具有看門狗和2個支持多種串行通信協(xié)議的USART。

1個通用的16位定時器和2個8位定時器,1個IEEE802.15.4MAC定時器。

21個通用I/O引腳。

本章將重點介紹CC2530芯片的基礎開發(fā),主要講解CC2530的結構框架、CC2530的I/O引腳的使用、串口的使用、DAM的使用和定時器的使用,無線收發(fā)將在第5章中詳細講解。

圖4-1所示為CC2530的內部結構框圖。CC2530內部模塊大致可以分為三種類型:CPU和內存相關的模塊;外設、時鐘和電源管理模塊;射頻相關模塊。

本節(jié)將講解CC2530的CPU以及內存相關模塊,主要內容有兩部分:CC2530CPU;存儲器以及映射。4.2CC2530的結構框架

圖4-1CC2530的內部結構框圖

4.2.1CC2530CPU

CC2530包含一個“增強型”工業(yè)標準的8位8051微控制器內核,運行時鐘32

MHz,具有8倍的標準8051內核的性能。增強型8051內核使用標準的8051指令集,并且每個指令周期是一個時鐘周期,而標準的8051每個指令周期是12個時鐘周期,因此增強型8051消除了總線狀態(tài)的浪費,指令執(zhí)行比標準的8051更快。除了速度改進之外,CC2530的“增強型8051內核”與“標準的8051微控制器”相比,使用時要注意以下兩點:

內核代碼:CC2530的“增強型8051”內核的“目標代碼”兼容“標準8051”內核的“目標代碼”,即CC2530的8051內核的“目標代碼”可以使用“標準8051”的編譯器或匯編器進行編譯。微控制器:由于CC2530的“增強型8051”內核使用了不同于“標準8051”的指令時鐘,因此“增強型8051”在編譯時與“標準8051”代碼編譯時略有不同,例如“標準8051”的微控制器包含的“外設單元寄存器”的指令代碼在CC2530的“增強型8051”上不能正確運行。

4.2.2CC2530存儲器以及映射

本小節(jié)講解CC2530存儲器與映射,包括四部分內容:CC2530的物理存儲器、CC2530的存儲空間、映射和存儲器仲裁。

1.物理存儲器

CC2530的物理存儲器是CC2530本身固有的存儲設備,包括SRAM、FLASH、信息頁面、SFR寄存器和XREG。其各部分的描述如下:

SRAM:上電時,SRAM的內容是未定義的,SRAM內容在所有的供電模式下都保留。

FLASH:片上閃存存儲器,主要是為了保存程序和常量數據。FLASH由一組2

KB的頁面組成。CC2530的FLASH有以下幾個特點。

頁面大?。?

KB。

閃存頁面擦除時間:20

ms。

閃存芯片批量擦除時間:20

ms。

閃存寫時間(4字節(jié)):20

μs。

數據保留(室溫下):100年。

編程/擦出次數:20

000次。

信息頁面是一個2

KB的只讀區(qū)域,它的主要作用是存儲全球唯一的IEEE地址。

SFR寄存器:特殊功能的寄存器(SFR)。目的是控制8051CPU內核或外設的一些功能。大部分8051CPU內核的SFR和標準的8051SFR相同。

XREG寄存器:是SFR的擴展寄存器,比如射頻寄存器。XREG的大小為1

KB,且訪問速度比SFR要慢。

2.存儲空間

CC2530的8051CPU有四個不同的存儲空間,分別是CODE、DATA、XDATA和SFR,其各個存儲空間的描述如下:

CODE:程序存儲器,只讀存儲空間,用于存放程序代碼和一些常量,有16根地址總線,尋址范圍為0x0000~0xFFFF,共64

KB。

DATA:數據存儲器,可讀/寫的數據存儲空間,用于存放程序運行過程中的數據。有8根地址總線,因此尋址空間為0x00~0xFF,共256個字節(jié)。其中較低的128字節(jié)可以直接或間接尋址,較高的128字節(jié)只能間接尋址。

XDATA:外部數據存儲器,可讀/寫的數據存儲空間,主要用于DMA尋址。有16根地址總線(與CODE共用地址總線),因此XDATA的尋址空間是0x0000~0xFFFF,共64

KB,只能進行間接尋址,與DATA相比訪問速度比較慢。

SFR:特殊功能寄存器,可讀/寫的寄存器存儲空間,共有128字節(jié)。對于地址是被8整除的SFR寄存器,每一位還可以單獨尋址。

注意:以上的4種存儲空間只是4種不同的尋址方式概念,并不代表具體的物理存儲設備,只是存儲空間的概念;而FLASH、SRAM、EEPROM等是具體的物理存儲設備。他們兩者之間的關系是通過映射來聯(lián)系起來的。例如FLASH或者EEPROM都可以作為物理存儲媒介映射到CODE上。

3.映射

映射就是將CC2530的物理存儲器映射到其存儲空間上,有兩個作用,一是方便DMA訪問存儲設備,二是可在CODE區(qū)執(zhí)行FLASH或SRAM中的代碼。映射分為CODE存儲器映射和XDATA存儲器映射。

1)

CODE存儲器映射

CODE存儲器映射的主要功能有兩個:一是將FLASH映射至CODE存儲空間;二是執(zhí)行來自SRAM的代碼(將SRAM映射至CODE存儲空間)。

對于FLASH的映射,首先要解決存儲空間不對稱的問題,即CODE的尋址空間為

64

KB,而對于CC2530F256設備來說FLASH的存儲空間為256

KB。為了解決這一問題,CC2530將FLASH存儲器分為幾個bank,每個bank的大小是32

KB。對于CC2530F256設備來說,它有8個bank,分別為bank0~bank7。通過操作寄存器FMAP.MAP[2:0](詳見存儲器仲裁)來控制將哪個編號的bank映射到CODE區(qū)域。FLASH與CODE的映射關系如圖4-2所示。

將CODE尋址空間地址0x0000~0xFFFF分為兩個區(qū)域:普通區(qū)域和bank0~7區(qū)域。其中:

普通區(qū)域的尋址空間為0x0000~0x7FFF,只可以映射FLASH的bank0,即FLASH的最低32

KB的存儲空間。

bank0~7區(qū)域的尋址空間在0x8000~0xFFFF之間,通過操作FMAP.MAP[2:0](詳見存儲器仲裁)寄存器,選擇映射bank0~bank7之間的哪個區(qū)域,比如FMAP.MAP

=

001,則映射bank1區(qū)域。

對于SRAM映射(以便在SRAM中執(zhí)行代碼),可以將SRAM映射到CODE存儲空間的0x8000~(0x8000

+

SRAM_SIZE

-

1)的區(qū)域,如圖4-3所示。需要注意的是,雖然程序從SRAM中運行代碼,但是并不代表程序是從SRAM中啟動的。程序仍舊是從CODE的普通區(qū)域0x0000開始執(zhí)行,當程序執(zhí)行到0x8000時,將執(zhí)行SRAM中的代碼。

圖4-2CODE存儲空間

圖4-3SRAM映射到CODE存儲空間

2)

XDATA存儲器映射

為了方便DMA控制器能訪問所有的物理存儲空間,CC2530把所有的物理存儲器以及寄存器都映射到XDATA上,包括CODE和SFR部分存儲空間。XDATA存儲器映射如圖4-4所示。

圖4-4XDATA存儲空間映射從圖中可以看出XDATA包含了所有物理存儲器的映射,包括8

KB的SRAM存儲器、XREG、SFR、信息頁面和FLASH存儲器,其映射區(qū)域如下所述:

SRAM映射的地址范圍是0x0000到SRAM_SIZE

-

1。其中SRAM較高的256字節(jié)映射到DATA存儲空間8位地址區(qū)域,即地址范圍從SRAM_SIZE

-

256到SRAM_SIZE

-

1。

XREG區(qū)域映射到1

KB地址區(qū)域0x6000~0x63FF。

SFR寄存器映射到地址區(qū)域0x7080~0x70FF。128個條目的硬件寄存器區(qū)域是通過這一存儲空間訪問的。閃存信息頁面2

KB映射到地址區(qū)域0x7800~0x7FFF。這是一個只讀區(qū)域,包含有關設備的各種信息。

信息頁面映射到地址區(qū)域0x7800~0x7FFF。

XBANK為CODE存儲空間的bank0~7區(qū)域的映射,其地址仍然是0x8000~0xFFFF??梢耘渲么鎯ζ骺刂萍拇嫫鱉EMCTR.XBANK[2:0](詳見存儲器仲裁)決定選擇映射bank0~bank7之間的哪個區(qū)域,比如MEMCTR.XBANK

=

001,則映射bank1區(qū)域。

4.存儲器仲裁

“存儲器仲裁”的主要功能是為了解決CPU與DMA訪問所有物理存儲器(除了CPU內部寄存器)之間的沖突問題。當CPU和DMA之間發(fā)生沖突時,“存儲器仲裁”停止CPU或DMA的總線,這樣沖突就被解決。存儲器仲裁主要有兩個寄存器,即存儲器仲裁控制寄存器MEMCTR和閃存區(qū)映射寄存器FMAP,這兩個寄存器用于控制存儲器子系統(tǒng)的各個方面。其描述如下:

MEMCTR.XMAP必須設置以使得程序從SRAM執(zhí)行;MEMCTR.XBANK決定XDATA的高32KB映射CODE存儲空間的哪個bank區(qū)域,如表4-1所示。

表4-1MEMCTR(0XC7)存儲器仲裁控制閃存區(qū)映射寄存器FMAP控制物理32

KB代碼區(qū)映射到CODE存儲空間的程序地址區(qū)域0x8000~0xFFFF,如表4-2所示。

表4-2FMAP(0x9F)閃存區(qū)映射

IAR對CC2530的編程操作提供了良好的C語言支持,包括頭文件、運行庫以及中斷編程等。4.3CC2530編程基礎

4.3.1寄存器和匯編指令

CC2530的CPU寄存器與標準的8051的CPU寄存器相同,都包括8組寄存器R0~R7、程序狀態(tài)字PSW、累加器ACC、B寄存器和堆棧指針SP等。

CC2530的CPU指令與標準的8051的指令集相同,因此本小節(jié)不再詳細介紹CC2530的寄存器以及匯編指令,詳細內容請查閱有關8051的書籍。

4.3.2編程基礎

CC2530編程的風格基本上與普通的基于8051的C語言編程相同。包括頭文件、初始化函數、主函數以及其他中斷函數。

1.頭文件

在C語言中頭文件以“XXX.h”的格式存在,其中“XXX”為文件名,在頭文件中一般定義程序需要的變量或函數的聲明等。一般頭文件在源程序的一開始使用“包含命令”將頭文件包含在源程序中,以便源程序調用頭文件中的變量等。頭文件“包含命令”使用“#include”命令。

以CC2530為例,CC2530的頭文件為“ioCC2530.h”,“ioCC2530.h”是TICC2530芯片專門定義的,包括CC2530芯片內部寄存器以及存儲器的訪問地址、芯片引腳和中斷向量的定義。在基于CC2530的編程中,必須在源程序的一開始將頭文件“ioCC2530.h”包含到源程序中。示例如下。

【示例4-1】CC2530頭文件

#include<ioCC2530.h>

在一個工程里面還會有其他的頭文件,比如要控制CC2530開發(fā)板的LED,一般由用戶新建一個頭文件,此頭文件可以由用戶命名,例如“LED.h”。

【示例4-2】CC2530頭文件

#include<LED.h>

在此頭文件中定義與LED相關的變量以及可能用到的引腳或寄存器信息。一般用戶定義的頭文件格式如示例4-3所示。

【示例4-3】LED.h

/**************************************************

*函數原型及相關變量

*相關文件:LED.H

**************************************************/

//以下兩行和最后一行預處理指令用于防止該頭文件被多次包含

#ifndefLED_H_

#defineLED_H_

#include<ioCC2530.h>

#defineuintunsignedint

#defineucharunsignedchar

//定義LED的端口

#definelED1P1_0

#definelED2P1_1

//函數聲明

voidDelay(uint);

voidinitLED(void);

#endif需要注意的是在用戶編寫的頭文件中,也需要將“ioCC2530.h”包含在內。如果其中一個頭文件中包含了另外一個頭文件,那么在主函數文件中只需要包含前者即可,例如在LED.h中包含了頭文件“ioCC2530.h”,那么在主函數文件中只需要包含“LED.h”文件即可。

2.初始化函數

在一個項目工程中為了增強程序的可移植性和可維護性,一般將一些初始化配置信息編寫成一個函數,稱作初始化函數。在一個工程中可以有多個初始化函數,例如LED的初始化、串口的初始化、按鍵的初始化等。以LED初始化為例,在初始化函數中對LED對應的寄存器以及端口進行配置,以便LED在程序開始的時候保持規(guī)定的狀態(tài)。以下示例為一個簡單的LED初始化函數。

【示例4-4】InitialLED()

/****************************

*函數功能:LED初始化程序

*函數參數:無

*函數返回值:無

*****************************/

voidInitLED(void)

{

//P10、P11定義為輸出

P1DIR|=0x03;

//關LED1

LED1=OFF;

//關LED2

LED2=OFF;

}

3.主函數

與常規(guī)的C語言程序一樣,IAR下的CC2530程序依然將main()函數設定為程序的入口函數,也稱主函數。當程序比較大時,在主函數內一般不直接編寫與程序相關的業(yè)務算法,而是調用其他子函數(如用庫函數、戶編寫的硬件初始化函數和業(yè)務算法或其他功能函數等)來實現(xiàn)整個程序的邏輯,使主函數看起來簡單明了并且易于程序的維護。以下示例為一個主函數,在此主函數中除了調用LED初始化函數和按鍵初始化函數之外,還調用了延時函數和按鍵掃描函數KeyScan()函數,實現(xiàn)了按鍵控制LED的功能。

【示例4-5】main()

voidmain(void)

{

ucharKeyvalue;

Delay(10);

//調用初始化函數

InitLED();

InitKey();

while(1)

{

//給按鍵標志位賦值

Keyvalue=KeyScan();

//如果按鍵為SW6

if(Keyvalue==1)

{

//LED切換狀態(tài)

LED1=!LED1;

//清除鍵值

Keyvalue=0;

}

//檢測按鍵為SW5

if(Keyvalue==2)

{

//LED2切換狀態(tài)

LED2=!LED2;

//清除鍵值

Keyvalue=0;

}

Delay(10);

}

}

以上程序比較簡單,因此把按鍵對LED的控制直接在main()函數內完成,當然也可把這部分代碼(算法)封裝成一個業(yè)務算法函數,例如KeyLed()。

4.其他子函數

在一個程序中,為了程序的可維護性,除了初始化函數之外,還需要將某個業(yè)務算法或功能封裝成一個函數,稱為子函數。以下示例為按鍵掃描的子函數。

【示例4-6】KeyScan()

ucharKeyScan(void)

{

//檢測SW6是否為低電平,低電平有效

if(SW6==0)

{

Delay(100);

//檢測到按鍵

if(SW6==0)

{

//直到松開按鍵

while(!SW6);

//返回值為1

return(1);

}

}

//檢測SW5是否為低電平,低電平有效

if(SW5==0)

{

Delay(100);

//檢測到按鍵

if(SW5==0)

{

//檢測到按鍵

while(!SW5);

//返回值為2

return(2);

}

}

return(0);

}

5.中斷函數

當需要中斷處理時,需要編寫中斷處理函數,中斷處理函數是當有中斷發(fā)生時,需要處理的事件。中斷函數的編寫請參見下一小節(jié)。

以外部中斷為例,當有中斷發(fā)生時,LED1狀態(tài)改變。

【示例4-7】中斷服務子程序

#pragmavector=P0INT_VECTOR

__interruptvoidP0_ISR(void)

{

//關端口P0.4、P0.5中斷

P0IEN&=~0x30;

//按鍵中斷

if(P0IFG>0)

{

//清中斷標志

P0IFG=0;

//LED1改變狀態(tài)

lED1=!lED1;

}

//開中斷

P0IEN|=0x30;

}

4.3.3中斷的使用

CC2530的中斷系統(tǒng)是為了讓CPU對內部或外部的突發(fā)事件及時地作出響應,并執(zhí)行相應的中斷程序。中斷由中斷源引起,中斷源由相應的寄存器來控制。當需要使用中斷時,需配置相應的中斷寄存器來開啟中斷,當中斷發(fā)生時將跳入中斷服務函數中執(zhí)行此中斷所需要處理的事件。本小節(jié)將介紹CC2530中斷的使用,包括中斷源、中斷向量、中斷優(yōu)先級以及中斷編程。

1.中斷源與中斷向量

CC2530有18個中斷源,每個中斷源都可以產生中斷請求,中斷請求可以通過設置中斷使能SFR寄存器的中斷使能位IEN0、IEN1或IEN2使能或禁止中斷(相關的中斷寄存器將在以下章節(jié)中詳細講解)。CC2530的中斷源如表4-3所示。

表4-3中斷概述

當相應的中斷源使能并發(fā)生時,中斷標志位將自動置1,然后程序跳往中斷服務程序的入口地址執(zhí)行中斷服務程序。待中斷服務程序處理完畢后,由硬件清除中斷標志位。

中斷服務程序的入口地址即中斷向量,CC2530的18個中斷源對應了18個中斷向量,中斷向量定義在頭文件“ioCC2530.h”中,其定義如下。

【代碼4-1】<ioCC2530.h>中斷向量的定義

/**************************************************

*InterruptVectors

**************************************************/

//RF內核錯誤中斷(RFTXRFIO下溢或RXFIFO溢出)

#defineRFERR_VECTOR VECT(0,0x03)

//ADC轉換結束

#defineADC_VECTOR VECT(1,0x0B)

//USART0RX完成

#defineURX0_VECTOR VECT(2,0x13)

//USART1RX完成

#defineURX1_VECTOR VECT(3,0x1B)

//AES加密解密完成

#defineENC_VECTOR VECT(4,0x23)

//睡眠定時器比較

#defineST_VECTOR VECT(5,0x2B)

//端口2中斷

#defineP2INT_VECTOR VECT(6,0x33)

//USART0TX完成

#defineUTX0_VECTOR VECT(7,0x3B)

//DMA傳輸完成

#defineDMA_VECTOR VECT(8,0x43)

//Timer1(16位)捕獲/比較/溢出

#defineT1_VECTOR VECT(9,0x4B)

//Timer2(MACTimer)

#defineT2_VECTOR VECT(10,0x53)

//Timer3(8位)捕獲/比較/溢出

#defineT3_VECTOR VECT(11,0x5B)

//Timer4(8位)捕獲/比較/溢出

#defineT4_VECTOR VECT(12,0x63)

//端口0中斷

#defineP0INT_VECTOR VECT(13,0x6B)

//USART1TX完成

#defineUTX1_VECTOR VECT(14,0x73)

//端口1中斷

#defineP1INT_VECTOR VECT(15,0x7B)

//RF通用中斷

#defineRF_VECTOR VECT(16,0x83)

//看門狗計時溢出

#defineWDT_VECTOR VECT(17,0x8B)

2.中斷優(yōu)先級

中斷優(yōu)先級將決定中斷響應的先后順序,在CC2530中分為六個中斷優(yōu)先組,即IPG0~IPG5,每一組中斷優(yōu)先組中有三個中斷源,中斷優(yōu)先組的劃分如表4-4所示。

表4-4中斷優(yōu)先組的劃分

中斷優(yōu)先組的優(yōu)先級設定由寄存器IP0和IP1來設置。CC2530的優(yōu)先級有4級,即0~3級,其中0級的優(yōu)先級最低,3級的優(yōu)先級最高。優(yōu)先級的設置如表4-5所示。

表4-5優(yōu)先級設置其中IP1_X和IP0_X的X取值為優(yōu)先級組IPG0~IPG5中的任意一個。例如設置優(yōu)先級組IPG0為最高優(yōu)先級組,則設置如示例4-8所示。

【示例4-8】優(yōu)先級別設置

//設置IPG0優(yōu)先級組為最高優(yōu)先級別

IP1_IPG0=1;

IP0_IPG0=1;

如果同時收到相同優(yōu)先級或同一優(yōu)先級組中的中斷請求時,將采用輪流檢測順序來判斷中斷優(yōu)先級別的響應。其中斷輪流檢測順序如表4-6所示。

表4-6輪流探測順序例如在中斷優(yōu)先級組IPG0中的中斷RFERR、RF和DMA的中斷優(yōu)先級是相同的,如果同時使用這三個中斷,就需要使用輪流探測順序來判斷哪一優(yōu)先級最高。由輪流探測順序表查得RFERR中斷優(yōu)先級最高,RF中斷次之,DMA中斷與其他兩個中斷相比中斷優(yōu)先級最低。

3.中斷處理過程

中斷發(fā)生時,CC2530硬件自動完成以下處理:

(1)中斷申請:中斷源向CPU發(fā)出中斷請求信號(中斷申請一般需要在程序初始化中配置相應的中斷寄存器開啟中斷);

(2)中斷響應:CPU檢測中斷申請,把主程序中斷的地址保存到堆棧,轉入中斷向量入口地址;

(3)中斷處理:按照中斷向量中設定好的地址,轉入相應的中斷服務程序;

(4)中斷返回:中斷服務程序執(zhí)行完畢后,CPU執(zhí)行中斷返回指令,把堆棧中保存的數據從堆棧彈出,返回原來程序。

4.中斷編程

中斷編程的一般過程如下:

(1)中斷設置:根據外設的不同,具體的設置是不同的,一般至少包含啟用中斷。

(2)中斷函數的編寫;這是中斷編程的主要工作,需要注意的是,中斷函數應盡可能地減少耗時或不進行耗時操作。

CC2530所使用的編譯器為IAR,在IAR編譯器中用關鍵字

__interrupt來定義一個中斷函數。使用

#progmavector來提供中斷函數的入口地址,并且中斷函數沒有返回值,沒有函數參數。中斷函數的一般格式如下:

#pragmavector=中斷向量

__interruptvoid函數名(void)

{

//中斷程序代碼

}在中斷函數的編寫中,當程序進入中斷服務程序之后,需要執(zhí)行以下幾個步驟:

(1)將對應的中斷關掉(不是必須的,需要根據具體情況來處理);

(2)其次如果需要判斷具體的中斷源,則根據中斷標志位進行判斷(例如所有I/O中斷共用1個中斷向量,需要通過中斷標志區(qū)分是哪個引腳引起的中斷);

(3)清中斷標志(不是必須的,CC2530中中斷發(fā)生后由硬件自動清中斷標志位);

(4)處理中斷事件,此過程要盡可能地少耗時;

(5)最后,如果在第一步中關閉了相應的中斷源,則需要在退出中斷服務程序之前打開對應的中斷。

一般情況下,中斷函數的編寫是根據實際項目中的需求來定的。以CC2530端口0的P0.4、P0.5外部中斷為例,中斷程序的編寫如示例4-9所示。

【示例4-9】中斷程序編寫

//中斷函數入口地址

#pragmavector=P0INT_VECTOR

//定義一個中斷函數

__interruptvoidP0_ISR(void)

{

//關端口P0.4、P0.5中斷

P0IEN&=~0x30;

//判斷中斷發(fā)生

if(P0IFG>0)

{

//清中斷標志

P0IFG=0;

/**中斷事件的處理**/

.........

.........

........

}

//開中斷

P0IEN|=0x30;

}

CC2530包括3個8位輸入/輸出(I/O)端口,分別是P0、P1和P2。其中P0和P1有8個引腳,P2有5個引腳,共21個數字I/O引腳。4.4I/O這些引腳都可以用作通用的I/O端口,同時通過獨立編程還可以作為特殊功能的I/O(例如串口、ADC等)或者外部中斷輸入,通過軟件設置可以改變引腳的輸入/輸出硬件狀態(tài)配置。

這21個I/O引腳具有以下功能:

通用I/O。

外設I/O。

外部中斷源輸入口。

弱上拉輸入或推拉輸出。

21個引腳都可以用作外部中斷源輸入口以產生中斷,外部中斷功能也可以喚醒睡眠模式。I/O引腳通過獨立編程能作為數字輸入或數字輸出,還可以通過軟件設置改變引腳的輸入/輸出硬件狀態(tài)配置和硬件功能配置。在使用I/O端口前需要通過不同的特殊功能寄存器對它進行配置。

4.4.1通用I/O

用作通用I/O時,引腳可以組成3個8位端口,端口0、端口1和端口2來表示P0、P1和P2。所有的端口均可以通過SFR寄存器P0、P1和P2進行位尋址和字節(jié)尋址。每個端口引腳都可以單獨設置為通用I/O或外部設備I/O。其中P1.0和P1.1具備20

mA的輸出驅動能力,其他所有的端口只具備4mA的輸出驅動能力。

1.配置寄存器PxSEL

寄存器PxSEL(其中x為端口的標號0~2)用來設置端口的每個引腳為通用I/O或者是外部設備I/O(復位之后,所有的數字輸入、輸出引腳都設置為通用輸入引腳)。P0SEL、P1SEL和P2SEL寄存器配置如表4-7、表4-8、表4-9所示。

表4-7P0SEL—端口0功能選擇寄存器

表4-8P1SEL—端口1功能選擇寄存器表4-9P2SEL—端口2功能選擇寄存器例如需要將P0.4和P0.5設置為普通的I/O口,其寄存器的配置如示例4-10所示。

【示例4-10】PxSEL寄存器的設置

//P0.4和P0.5設置為普通的I/O口

P0SEL&=~0x30;

2.配置寄存器PxDIR

如果需要改變端口引腳方向,則需要使用寄存器PxDIR來設置每個端口引腳的輸入和輸出(其中x為端口的標號0~2)。PxDIR寄存器的配置如表4-10、表4-11、表4-12所示。

表4-10P0DIRI/O方向選擇寄存器

表4-11P1DIRI/O方向選擇寄存器

表4-12P2DIRI/O方向選擇寄存器

例如需要將P0.4和P0.5設置為輸入,將P1.0和P1.1設置為輸出,并且將P1.0設置為輸出高電平和P1.1設置為輸出低電平,其寄存器的配置如示例4-11所示。

【示例4-11】PxDIR寄存器的設置

//P0.4和P0.5設為輸入

P0DIR&=~0x30;

//P1.0設置為輸出,p1.1輸出為低電平

P1DIR|=0x03;

//P1.0和P1.1設置為輸出高電平

P1_0=1;

P1_1=0;

3.配置寄存器PxINP

復位之后,所有的端口均設置為帶上拉的輸入。用作輸入時,通用I/O端口引腳可以設置為上拉、下拉或三態(tài)操作模式。其中P1.0和P1.1端口沒有上拉和下拉功能。上拉、下拉或三態(tài)操作模式寄存器由PxINP設置(其中x為端口的標號0~2)。PxINP寄存器如表4-13、表4-14、表4-15所示。

表4-13P0INP端口0輸入模式

表4-14P1INP端口2輸入模式

表4-15P2INP端口2輸入模式

【示例4-12】PxINP寄存器的設置

//P0.4和P0.5設置為三態(tài)

P0INP|=0x30;

下述內容用于實現(xiàn)任務描述4.D.1,通過掃描方式實現(xiàn)按鍵觸發(fā)LED亮滅。利用按鍵SW5和按鍵SW6控制LED1和LED2。當按下SW5時,LED1狀態(tài)改變;當按下SW6時,LED2狀態(tài)改變。解決問題的思路如下。

(1)原理圖分析:按鍵和LED的原理圖如圖4-5所示。由此可知,按鍵SW5由P0.4控制,按鍵SW6由P0.5控制;LED1和LED2分別由P1.0和P1.1控制。

(2)按鍵初始化:將P0.4和P0.5設為普通I/O口,并且設置為輸入狀態(tài)。

(3)

LED初始化:將P1.0和P1.1設置為輸出且將LED1和LED2關閉。

(4)采用按鍵檢測的方法來控制LED狀態(tài)的改變:當檢測到SW5按下時,LED1狀態(tài)改變;當檢測到SW6按下時,LED2狀態(tài)改變。

圖4-5按鍵和LED原理圖

【描述4.D.1】main.c

#include<ioCC2530.h>

//定義控制燈的端口

//定義LED1為P11口控制

#defineLED1P1_0

//定義LED2為P10口控制

#defineLED2P1_1

#defineSW6P0_4

#defineSW5P0_5

//函數聲明

//延時函數

voidDelay(uint);

//初始化P0口

voidInitial(void);

//初始化按鍵

voidInitKey(void);

//掃描按鍵,讀鍵值

ucharKeyScan(void);

/***********************************

*按鍵初始化函數

************************************/

voidInitKey(void)

{

//P0.4,P0.5設為普通輸出口

P0SEL&=~0x30;

//按鍵在P04,P05設為輸入

P0DIR&=~0x30;

//P0.4,P0.5為三態(tài)

P0INP|=0x30;

}

/**************************

*LED初始化

**************************/

voidInitial(void)

{

//P10、P11定義為輸出

P1DIR|=0x03;

//關LED1

LED1=OFF;

//關LED2

LED2=OFF;

}

/****************************

*延時1.5us

*****************************/

voidDelay(uintn)

{

uinttt;

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

}

/*****************************************

*按鍵掃描

*****************************************/

ucharKeyScan(void)

{

//檢測SW6是否為低電平,低電平有效

if(SW6==0)

{

Delay(100);

//檢測到按鍵

if(SW6==0)

{

//直到松開按鍵

while(!SW6);

//返回值為1

return(1);

}

}

//檢測SW5是否為低電平,低電平有效

if(SW5==0)

{

Delay(100);

//檢測到按鍵

if(SW5==0)

{

//檢測到按鍵

while(!SW5);

//返回值為2

return(2);

}

}

return(0);

}

/*********************************

*main()函數

*********************************/

voidmain(void)

{//按鍵標志位

ucharKeyvalue=0;

Delay(10);

//調用初始化函數

Initial();

InitKey();

while(1)

{//給按鍵標志位賦值

Keyvalue=KeyScan();

//如果按鍵為SW6

if(Keyvalue==1)

{

//LED切換狀態(tài)

LED1=!LED1;

//清除鍵值

Keyvalue=0;

}

//檢測按鍵為SW5

if(Keyvalue==2)

{

//LED2切換狀態(tài)

LED2=!LED2;

//清除鍵值

Keyvalue=0;

}

Delay(10);

}

}

實驗現(xiàn)象結果為:當按下SW5時,LED1燈的狀態(tài)改變;當按下SW6時,LED2燈的狀態(tài)改變。

4.4.2通用I/O中斷

在設置I/O口的中斷時必須要將其設置為輸入狀態(tài),通過外部信號的上升或下降沿觸發(fā)中斷。通用I/O的所有的外部中斷共用一個中斷向量,根據中斷標志位來判斷是哪個引腳發(fā)生中斷。

在使用通用I/O中斷時需要設置其寄存器,通用I/O中斷寄存器有三類:中斷使能寄存器、中斷狀態(tài)標志寄存器和中斷控制寄存器。中斷使能寄存器包括IENx和PxIEN(其中x代表0、1、2),其功能是使I/O口進行中斷使能。

中斷狀態(tài)標志寄存器包括PxIFG,其功能是當發(fā)生中斷時,I/O口所對應的中斷狀態(tài)標志將自動置1。

中斷控制寄存器為PICTL,其功能是控制I/O口的中斷觸發(fā)方式。

1.中斷使能寄存器IENx

IENx寄存器包括三個八位寄存器:IEN0、IEN1和IEN2。IENx中斷主要是配置總中斷和P0~2端口的使能。

IEN1.P0IE:P0端口中斷使能。

IEN2.P1IE:P1端口中斷使能。

IEN2.P2IE:P2端口中斷使能。

IEN0寄存器的第7位可以控制CC2530所有中斷的使能。IEN0的其他位控制定時器、串口、RF等外設功能中斷的詳細講解見本章后面小節(jié)的內容。IEN0寄存器如表4-16所示。

表4-16IEN0中斷使能

IEN1寄存器的第5位控制P0口的中斷,當設置IEN1.P0IE時,將設置P0端口所有引腳的中斷使能,即P0.0~P0.7引腳全部中斷使能。IEN1中斷寄存器如表4-17所示。

表4-17IEN1中斷使能

IEN2寄存器的第4位和第1位分別控制P1端口和P2端口的中斷,當設置IEN2.P1IE和IEN2.P2IE時,將設置P1端口和P2端口所有引腳的中斷使能,即P1.0~P1.7引腳和P2.0~P2.4引腳全部中斷使能。IEN2中斷寄存器如表4-18所示。

表4-18IEN2中斷使能例如,設置端口0中斷使能,其寄存器的配置如示例4-13所示。

【示例4-13】端口0中斷使能配置

//端口0中斷使能

IEN1|=0x20;

2.中斷使能寄存器PxIEN

PxIEN寄存器用來設置端口的某一個引腳的中斷使能,PxIEN有三個寄存器,即P0IEN、P1IEN和P2IEN,分別如表4-19、表4-20、表4-21所示。

表4-19P0IEN端口0中斷使能寄存器

表4-20P1IEN端口1中斷使能寄存器

表4-21P2IEN端口2中斷使能寄存器其中P0IEN控制端口0的P0.0~P0.7中斷使能;P1IEN控制端口1的P1.0~P1.7中斷使能;P2IEN寄存器的0~4控制端口2的P2.0~P2.4中斷使能。如果設置P0.4和P0.5中斷使能,其寄存器的設置如示例4-14所示。

【示例4-14】P0.4和P0.5中斷使能

//端口0中斷使能

P0IEN|=0x30;

3.中斷狀態(tài)標志寄存器PxIFG

PxIFG寄存器是中斷狀態(tài)標志寄存器,由于CC2530的外部中斷共用一個中斷向量,因此需要判斷是哪個引腳發(fā)生中斷,通過判斷PxIFG寄存中的中斷狀態(tài)標志位可以判斷哪個引腳發(fā)生中斷。PxIFG寄存器有三個,分別是P0IFG、P1IFG和P2IFG。其中P0IFG是判斷P0端口的P0.0~P0.7引腳的中斷狀態(tài)標志;P1IFG是判斷P1端口的P1.0~P1.7引腳的中斷狀態(tài)標志;P2IFG是判斷P0端口的P2.0~P2.4引腳的中斷狀態(tài)標志。這三種寄存器分別如表4-22、表4-23、表4-24所示。

表4-22P0IFG端口0中斷狀態(tài)標志寄存器

表4-23P1IFG端口1中斷狀態(tài)標志寄存器表4-24P2IFG端口2中斷狀態(tài)標志寄存器

如果有中斷發(fā)生則相應的寄存器位由硬件自動置1,例如要判斷端口0是否發(fā)生中斷,可以使用如示例4-15所示的代碼。

【示例4-15】端口0是否有中斷發(fā)生

//判斷中斷標志位

if(P0IFG>0)

{

...

}

4.中斷控制寄存器PICTL

I/O口發(fā)生中斷除了配置中斷使能之外,還需要配置中斷觸發(fā)方式。中斷觸發(fā)方式可由端口中斷控制寄存器PICTL設置。I/O中斷觸發(fā)方式分為輸入的上升沿觸發(fā)和輸入的下降沿觸發(fā)。PICTL寄存器如表4-25所示。

表4-25PICTL端口中斷控制寄存器續(xù)表

例如,要設置P0.4和P0.5為下降沿觸發(fā),其寄存器的配置如示例4-16所示。

【示例4-16】PICTL寄存器配置

//P0.4和P0.5為下降沿觸發(fā)中斷

PICTL|=0x01;

5.中斷配置

為了使能任一中斷功能,應當采取以下步驟:

(1)設置需要發(fā)生中斷的I/O口為輸入方式。

(2)清除中斷標志,即將需要設置中斷的引腳所對應的寄存器PxIFG狀態(tài)標志位置0。

(3)設置具體的I/O引腳中斷使能,即設置中斷的引腳所對應的寄存器PxIEN的中斷使能位為1。

(4)設置I/O口的中斷觸發(fā)方式。

(5)設置寄存器IEN1和IEN2中對應引腳的端口的中斷使能位為1。

(6)設置IEN0中的EA位為1使能全局中斷。

(7)編寫中斷服務程序。下述內容用于實現(xiàn)任務描述4.D.2,通過外部中斷改變LED1的亮滅。利用按鍵SW5和SW6觸發(fā)P0.4和P0.5下降沿發(fā)生中斷控制LED1的亮滅。即當按下SW5或者SW6時,LED1燈的狀態(tài)發(fā)生改變,解決問題的步驟如下所述。

(1)

LED初始化:關閉四個LED。

(2)外部中斷初始化:清空P0中斷標志位,開啟P0口中斷以及總中斷。

(3)中斷處理函數的編寫。

【描述4.D.2】main.c

#include<ioCC2530.h>

#defineuintunsignedint

#defineLED1P1_0

#defineLED2P1_1

#defineLED3P1_2

#defineLED4P1_3

/*****************************LED初始化

****************************/

voidInitLED(void)

{

//P1為普通I/O口

P1SEL=0x00;

//P1.0P1.1P1.2P1.3輸出

P1DIR=0x0F;

//關閉LED1

LED1=1;

//關閉LED2

LED2=1;

//關閉LED3

LED3=1;

//關閉LED4

LED4=1;

}

/***********************************

*io及外部中斷初始化

*****************************/

voidInitIO(void)

{

//P0中斷標志清0

P0IFG|=0x00;

//P0.4有上拉、下拉能力

P0INP&=~0X30;

//P0.4和P0.5中斷使能

P0IEN|=0x30;

//P0.4和P0.5,下降沿觸發(fā)

PICTL|=0X01;

//開中斷

EA=1;

//端口0中斷使能

IEN1|=0X20;

};

/**********************************

*延時子函數

***********************************/

voidDelay(uintn)

{

uinttt;

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

for(tt=0;tt<n;tt++);

}

/********************************

*main()函數

*********************************/

voidmain(void)

{

//LED初始化

InitLED();

//IO及外部中斷初始化

InitIO();

//等待中斷

Delay(100);

while(1);

}

/*******************************

*中斷服務子程序

********************************/

#pragmavector=P0INT_VECTOR

__interruptvoidP0_ISR(void)

{//關中斷

P0IEN&=~0x30;

//判斷按鍵中斷

if(P0IFG>0)

{//清中斷標志

P0IFG=0;

//LED1改變狀態(tài)

LED1=!LED1;

}

//開中斷

P0IEN|=0x30;

}

實驗現(xiàn)象:當按下按鍵SW5和SW6時,LED1的狀態(tài)發(fā)生改變。

4.4.3外設I/O

外設I/O是I/O的第二功能,當I/O配置為外設I/O時,可以通過軟件配置連接到ADC、串口、定時器和調試接口等。當設置為外設I/O時,需要將對應的寄存器位PxSEL置1,每個外設單元對應兩組可以選擇的I/O引腳,即“外設位置1”和“外設位置2”,如表4-26所示。例如USART在SPI模式下,“外設位置1”為P0.2~P0.5,“外設位置2”為P1.2~P1.5。

表4-26外設I/O引腳映射

外設I/O位置的選擇使用寄存器PERCFG來控制,PERCFG是外設控制寄存器,用來選擇外設使用哪一個I/O端口,如表4-27所示。

表4-27PERCFG外設控制寄存器

【示例4-17】PERCFG寄存器設置

//設置USART0為外設位置1

PERCFG|=0x00;

如果I/O映射有沖突,可以在有沖突的組合之間設置優(yōu)先級。優(yōu)先級的設置是通過寄存器P2SEL和P2DIR來設置,如表4-28、表4-29所示。

表4-28P2SEL端口1外設優(yōu)先級控制寄存器表4-29P2DIR端口0外設優(yōu)先級控制寄存器其中P2DIR的PRIP0位負責優(yōu)先級的選擇,當外設使用同一引腳而引起沖突時,由P2DIR.PRIP0位來決定先使用哪一個外設。

各外設使用情況簡單介紹如下,具體使用詳見本章以下章節(jié)。

1.

ADC

整個P0口可作為ADC使用,因此可以使用多達8個ADC輸入引腳。此時P0引腳必須配置為ADC輸入。APCFG寄存器(ADC模擬外設I/O配置寄存器)可以配置P0的某個引腳為一個ADC輸入,且相應的位必須設置為1。這個寄存器的默認值選擇端口0引腳為非ADC輸入,即數字輸入/輸出,如表4-30所示。

表4-30APCFG模擬外設I/O配置寄存器

APCFG寄存器的設置將覆蓋P0SEL的設置。但是ADC可以配置為使用I/O引腳P2.0作為內部觸發(fā)器來啟動裝換。當用作ADC內部觸發(fā)器時,P2.0必須在輸入模式下配置為通用I/O。

2.串口

USART0和USART1均有兩種模式,分別是異步UART模式或同步SPI模式,并且每種模式下所對應的外設引腳有兩種,即外設位置1和外設位置2。其中SFR寄存器位PERCFG.U0CFG用于設置USART0是使用外設位置1還是外設位置2;PERCFG.U1CFG

用于設置USART1是使用外設位置1還是外設位置2。

P2DIR.PRIP0為端口0指派一些外設的優(yōu)先順序。當設置為00時,USART0優(yōu)先。如果選擇了UART模式,且硬件流量控制禁用,UART1或定時器1將優(yōu)先使用端口P0.4和P0.5。

P2SEL.PRI3P1和P2SEL.PRI0P1為端口1指派外設優(yōu)先順序,當兩者都設置為0時,USART0優(yōu)先。

3.定時器1

PERCFG.T1CFG用于設置定時器1是使用外設位置1還是外設位置2,定時器1的外設信息對應如下:

0:通道0捕獲/比較引腳。

1:通道1捕獲/比較引腳。

2:通道2捕獲/比較引腳。

3:通道3捕獲/比較引腳。

4:通道4捕獲/比較引腳。

P2DIR.PRIP0用于為端口0指派外設的優(yōu)先順序。當設置為10時,定時器通道0-1優(yōu)先,當設置為11時,定時器通道2-3優(yōu)先。

P2SEL.PRI1P1和P2SEL.PRI0P1為端口1指派外設的優(yōu)先順序。當P2SEL.PRI1P1設置為低電平,P2SEL.PRI0P1設置為高電平時,定時器1通道優(yōu)先。

4.定時器3

PERCFG.T3CFG用于設置定時器3是使用外設位置1還是外設位置2。

定時器3信號顯示如下:

0:通道0比較引腳。

1:通道1比較引腳。

P2SEL.PRI2P1和P2SEL.PRI3P1為端口1選擇一些外設的優(yōu)先順序。當P2SEL.PRI2P1和P2SEL.PRI3P1都設置為高電平時,定時器3通道優(yōu)先。如果P2SEL.PRI2PI設置為低電平時,定時器3通道優(yōu)先于USART1,但是USART0優(yōu)先于定時器3通道以及USART1。

5.定時器4

PERCFG.T4CFG用于設置定時器4是使用外設位置1還是外設位置2。

定時器3信號顯示如下:

0:通道0比較引腳。

1:通道1比較引腳。

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

6.調試接口

端口P2.1和P2.2分別用于調試數據和時鐘信號,即DD調試數據和DC調試時鐘。當處于調試模式時,調試接口控制這些引腳的方向,并且在這些引腳上禁用上拉和下拉。

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論