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

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

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

掌握I/O的使用。

理解存儲(chǔ)器與映射的關(guān)系。

掌握ADC的使用方法。

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

掌握定時(shí)器的使用。

【描述4.D.】

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

【描述4.D.2】

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

【描述4.D.3】

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

【描述4.D.4】

串口發(fā)送數(shù)據(jù)。

【描述4.D.5】

串口接收數(shù)據(jù)控制LED亮滅。

【描述4.D.6】

將字符數(shù)組sourceString的內(nèi)容通過DMA傳輸?shù)阶址麛?shù)組destString中,通過串口在PC機(jī)顯示結(jié)果。

【描述4.D.7】

將AVDD(3.3V)AD轉(zhuǎn)換,通過串口在PC機(jī)顯示結(jié)果。

【描述4.D.8】

定時(shí)器1溢出標(biāo)志控制LED亮滅。

【描述4.D.9】

定時(shí)器2中斷控制LED亮滅。

【描述4.D.10】

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

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

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

KB/64

KB/128

KB/256

KB的內(nèi)置閃存。CC2530F256結(jié)合了TI業(yè)界領(lǐng)先的Zigbee協(xié)議棧(Zstack),提供了一個(gè)強(qiáng)大的完整的Zigbee解決方案。另外,CC2530F64還提供了一個(gè)強(qiáng)大的和完整的ZigbeeRF4CE(消費(fèi)電子射頻通信標(biāo)準(zhǔn))遠(yuǎn)程控制解決方案。

CC2530芯片的特點(diǎn)如下:

高性能、低功耗的8051微控制器內(nèi)核。

適應(yīng)2.4

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

32

KB/64

KB/128

KB/256

KB閃存。

8

KBSRAM,具備各種供電方式下的數(shù)據(jù)保持能力。

強(qiáng)大的DMA功能。

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

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

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

mA;

主動(dòng)模式TX在1

dB(CPU空閑):29

mA;

供電模式1(4

μs喚醒):0.2

mA;供電模式2(睡眠定時(shí)器運(yùn)行):1

μA;

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

μA;

寬電源電壓范圍為2~3.6

V。

硬件支持CSMA/CA。

支持?jǐn)?shù)字化的接收信號(hào)強(qiáng)度指示器/鏈路質(zhì)量指示(RSSI/LQI)。

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

高級(jí)加密標(biāo)準(zhǔn)AES協(xié)處理器。具有看門狗和2個(gè)支持多種串行通信協(xié)議的USART。

1個(gè)通用的16位定時(shí)器和2個(gè)8位定時(shí)器,1個(gè)IEEE802.15.4MAC定時(shí)器。

21個(gè)通用I/O引腳。

本章將重點(diǎn)介紹CC2530芯片的基礎(chǔ)開發(fā),主要講解CC2530的結(jié)構(gòu)框架、CC2530的I/O引腳的使用、串口的使用、DAM的使用和定時(shí)器的使用,無線收發(fā)將在第5章中詳細(xì)講解。

圖4-1所示為CC2530的內(nèi)部結(jié)構(gòu)框圖。CC2530內(nèi)部模塊大致可以分為三種類型:CPU和內(nèi)存相關(guān)的模塊;外設(shè)、時(shí)鐘和電源管理模塊;射頻相關(guān)模塊。

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

圖4-1CC2530的內(nèi)部結(jié)構(gòu)框圖

4.2.1CC2530CPU

CC2530包含一個(gè)“增強(qiáng)型”工業(yè)標(biāo)準(zhǔn)的8位8051微控制器內(nèi)核,運(yùn)行時(shí)鐘32

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

內(nèi)核代碼:CC2530的“增強(qiáng)型8051”內(nèi)核的“目標(biāo)代碼”兼容“標(biāo)準(zhǔn)8051”內(nèi)核的“目標(biāo)代碼”,即CC2530的8051內(nèi)核的“目標(biāo)代碼”可以使用“標(biāo)準(zhǔn)8051”的編譯器或匯編器進(jìn)行編譯。微控制器:由于CC2530的“增強(qiáng)型8051”內(nèi)核使用了不同于“標(biāo)準(zhǔn)8051”的指令時(shí)鐘,因此“增強(qiáng)型8051”在編譯時(shí)與“標(biāo)準(zhǔn)8051”代碼編譯時(shí)略有不同,例如“標(biāo)準(zhǔn)8051”的微控制器包含的“外設(shè)單元寄存器”的指令代碼在CC2530的“增強(qiáng)型8051”上不能正確運(yùn)行。

4.2.2CC2530存儲(chǔ)器以及映射

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

1.物理存儲(chǔ)器

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

SRAM:上電時(shí),SRAM的內(nèi)容是未定義的,SRAM內(nèi)容在所有的供電模式下都保留。

FLASH:片上閃存存儲(chǔ)器,主要是為了保存程序和常量數(shù)據(jù)。FLASH由一組2

KB的頁面組成。CC2530的FLASH有以下幾個(gè)特點(diǎn)。

頁面大?。?

KB。

閃存頁面擦除時(shí)間:20

ms。

閃存芯片批量擦除時(shí)間:20

ms。

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

μs。

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

編程/擦出次數(shù):20

000次。

信息頁面是一個(gè)2

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

SFR寄存器:特殊功能的寄存器(SFR)。目的是控制8051CPU內(nèi)核或外設(shè)的一些功能。大部分8051CPU內(nèi)核的SFR和標(biāo)準(zhǔn)的8051SFR相同。

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

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

2.存儲(chǔ)空間

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

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

KB。

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

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

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

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

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

3.映射

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

1)

CODE存儲(chǔ)器映射

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

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

64

KB,而對(duì)于CC2530F256設(shè)備來說FLASH的存儲(chǔ)空間為256

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

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

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

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

KB的存儲(chǔ)空間。

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

=

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

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

+

SRAM_SIZE

-

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

圖4-2CODE存儲(chǔ)空間

圖4-3SRAM映射到CODE存儲(chǔ)空間

2)

XDATA存儲(chǔ)器映射

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

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

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

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

-

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

-

256到SRAM_SIZE

-

1。

XREG區(qū)域映射到1

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

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

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

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

XBANK為CODE存儲(chǔ)空間的bank0~7區(qū)域的映射,其地址仍然是0x8000~0xFFFF??梢耘渲么鎯?chǔ)器控制寄存器MEMCTR.XBANK[2:0](詳見存儲(chǔ)器仲裁)決定選擇映射bank0~bank7之間的哪個(gè)區(qū)域,比如MEMCTR.XBANK

=

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

4.存儲(chǔ)器仲裁

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

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

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

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

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

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

4.3.1寄存器和匯編指令

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

CC2530的CPU指令與標(biāo)準(zhǔn)的8051的指令集相同,因此本小節(jié)不再詳細(xì)介紹CC2530的寄存器以及匯編指令,詳細(xì)內(nèi)容請(qǐng)查閱有關(guān)8051的書籍。

4.3.2編程基礎(chǔ)

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

1.頭文件

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

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

【示例4-1】CC2530頭文件

#include<ioCC2530.h>

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

【示例4-2】CC2530頭文件

#include<LED.h>

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

【示例4-3】LED.h

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

*函數(shù)原型及相關(guān)變量

*相關(guān)文件:LED.H

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

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

#ifndefLED_H_

#defineLED_H_

#include<ioCC2530.h>

#defineuintunsignedint

#defineucharunsignedchar

//定義LED的端口

#definelED1P1_0

#definelED2P1_1

//函數(shù)聲明

voidDelay(uint);

voidinitLED(void);

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

2.初始化函數(shù)

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

【示例4-4】InitialLED()

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

*函數(shù)功能:LED初始化程序

*函數(shù)參數(shù):無

*函數(shù)返回值:無

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

voidInitLED(void)

{

//P10、P11定義為輸出

P1DIR|=0x03;

//關(guān)LED1

LED1=OFF;

//關(guān)LED2

LED2=OFF;

}

3.主函數(shù)

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

【示例4-5】main()

voidmain(void)

{

ucharKeyvalue;

Delay(10);

//調(diào)用初始化函數(shù)

InitLED();

InitKey();

while(1)

{

//給按鍵標(biāo)志位賦值

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);

}

}

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

4.其他子函數(shù)

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

【示例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.中斷函數(shù)

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

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

【示例4-7】中斷服務(wù)子程序

#pragmavector=P0INT_VECTOR

__interruptvoidP0_ISR(void)

{

//關(guān)端口P0.4、P0.5中斷

P0IEN&=~0x30;

//按鍵中斷

if(P0IFG>0)

{

//清中斷標(biāo)志

P0IFG=0;

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

lED1=!lED1;

}

//開中斷

P0IEN|=0x30;

}

4.3.3中斷的使用

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

1.中斷源與中斷向量

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

表4-3中斷概述

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

中斷服務(wù)程序的入口地址即中斷向量,CC2530的18個(gè)中斷源對(duì)應(yīng)了18個(gè)中斷向量,中斷向量定義在頭文件“ioCC2530.h”中,其定義如下。

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

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

*InterruptVectors

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

//RF內(nèi)核錯(cuò)誤中斷(RFTXRFIO下溢或RXFIFO溢出)

#defineRFERR_VECTOR VECT(0,0x03)

//ADC轉(zhuǎn)換結(jié)束

#defineADC_VECTOR VECT(1,0x0B)

//USART0RX完成

#defineURX0_VECTOR VECT(2,0x13)

//USART1RX完成

#defineURX1_VECTOR VECT(3,0x1B)

//AES加密解密完成

#defineENC_VECTOR VECT(4,0x23)

//睡眠定時(shí)器比較

#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)

//看門狗計(jì)時(shí)溢出

#defineWDT_VECTOR VECT(17,0x8B)

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

中斷優(yōu)先級(jí)將決定中斷響應(yīng)的先后順序,在CC2530中分為六個(gè)中斷優(yōu)先組,即IPG0~I(xiàn)PG5,每一組中斷優(yōu)先組中有三個(gè)中斷源,中斷優(yōu)先組的劃分如表4-4所示。

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

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

表4-5優(yōu)先級(jí)設(shè)置其中IP1_X和IP0_X的X取值為優(yōu)先級(jí)組IPG0~I(xiàn)PG5中的任意一個(gè)。例如設(shè)置優(yōu)先級(jí)組IPG0為最高優(yōu)先級(jí)組,則設(shè)置如示例4-8所示。

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

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

IP1_IPG0=1;

IP0_IPG0=1;

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

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

3.中斷處理過程

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

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

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

(3)中斷處理:按照中斷向量中設(shè)定好的地址,轉(zhuǎn)入相應(yīng)的中斷服務(wù)程序;

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

4.中斷編程

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

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

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

CC2530所使用的編譯器為IAR,在IAR編譯器中用關(guān)鍵字

__interrupt來定義一個(gè)中斷函數(shù)。使用

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

#pragmavector=中斷向量

__interruptvoid函數(shù)名(void)

{

//中斷程序代碼

}在中斷函數(shù)的編寫中,當(dāng)程序進(jìn)入中斷服務(wù)程序之后,需要執(zhí)行以下幾個(gè)步驟:

(1)將對(duì)應(yīng)的中斷關(guān)掉(不是必須的,需要根據(jù)具體情況來處理);

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

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

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

(5)最后,如果在第一步中關(guān)閉了相應(yīng)的中斷源,則需要在退出中斷服務(wù)程序之前打開對(duì)應(yīng)的中斷。

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

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

//中斷函數(shù)入口地址

#pragmavector=P0INT_VECTOR

//定義一個(gè)中斷函數(shù)

__interruptvoidP0_ISR(void)

{

//關(guān)端口P0.4、P0.5中斷

P0IEN&=~0x30;

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

if(P0IFG>0)

{

//清中斷標(biāo)志

P0IFG=0;

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

.........

.........

........

}

//開中斷

P0IEN|=0x30;

}

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

這21個(gè)I/O引腳具有以下功能:

通用I/O。

外設(shè)I/O。

外部中斷源輸入口。

弱上拉輸入或推拉輸出。

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

4.4.1通用I/O

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

mA的輸出驅(qū)動(dòng)能力,其他所有的端口只具備4mA的輸出驅(qū)動(dòng)能力。

1.配置寄存器PxSEL

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

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

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

【示例4-10】PxSEL寄存器的設(shè)置

//P0.4和P0.5設(shè)置為普通的I/O口

P0SEL&=~0x30;

2.配置寄存器PxDIR

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

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

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

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

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

【示例4-11】PxDIR寄存器的設(shè)置

//P0.4和P0.5設(shè)為輸入

P0DIR&=~0x30;

//P1.0設(shè)置為輸出,p1.1輸出為低電平

P1DIR|=0x03;

//P1.0和P1.1設(shè)置為輸出高電平

P1_0=1;

P1_1=0;

3.配置寄存器PxINP

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

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

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

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

【示例4-12】PxINP寄存器的設(shè)置

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

P0INP|=0x30;

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

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

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

(3)

LED初始化:將P1.0和P1.1設(shè)置為輸出且將LED1和LED2關(guān)閉。

(4)采用按鍵檢測的方法來控制LED狀態(tài)的改變:當(dāng)檢測到SW5按下時(shí),LED1狀態(tài)改變;當(dāng)檢測到SW6按下時(shí),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

//函數(shù)聲明

//延時(shí)函數(shù)

voidDelay(uint);

//初始化P0口

voidInitial(void);

//初始化按鍵

voidInitKey(void);

//掃描按鍵,讀鍵值

ucharKeyScan(void);

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

*按鍵初始化函數(shù)

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

voidInitKey(void)

{

//P0.4,P0.5設(shè)為普通輸出口

P0SEL&=~0x30;

//按鍵在P04,P05設(shè)為輸入

P0DIR&=~0x30;

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

P0INP|=0x30;

}

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

*LED初始化

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

voidInitial(void)

{

//P10、P11定義為輸出

P1DIR|=0x03;

//關(guān)LED1

LED1=OFF;

//關(guān)LED2

LED2=OFF;

}

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

*延時(shí)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()函數(shù)

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

voidmain(void)

{//按鍵標(biāo)志位

ucharKeyvalue=0;

Delay(10);

//調(diào)用初始化函數(shù)

Initial();

InitKey();

while(1)

{//給按鍵標(biāo)志位賦值

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);

}

}

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

4.4.2通用I/O中斷

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

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

中斷狀態(tài)標(biāo)志寄存器包括PxIFG,其功能是當(dāng)發(fā)生中斷時(shí),I/O口所對(duì)應(yīng)的中斷狀態(tài)標(biāo)志將自動(dòng)置1。

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

1.中斷使能寄存器IENx

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

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

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

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

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

表4-16IEN0中斷使能

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

表4-17IEN1中斷使能

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

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

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

//端口0中斷使能

IEN1|=0x20;

2.中斷使能寄存器PxIEN

PxIEN寄存器用來設(shè)置端口的某一個(gè)引腳的中斷使能,PxIEN有三個(gè)寄存器,即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中斷使能。如果設(shè)置P0.4和P0.5中斷使能,其寄存器的設(shè)置如示例4-14所示。

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

//端口0中斷使能

P0IEN|=0x30;

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

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

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

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

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

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

//判斷中斷標(biāo)志位

if(P0IFG>0)

{

...

}

4.中斷控制寄存器PICTL

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

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

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

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

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

PICTL|=0x01;

5.中斷配置

為了使能任一中斷功能,應(yīng)當(dāng)采取以下步驟:

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

(2)清除中斷標(biāo)志,即將需要設(shè)置中斷的引腳所對(duì)應(yīng)的寄存器PxIFG狀態(tài)標(biāo)志位置0。

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

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

(5)設(shè)置寄存器IEN1和IEN2中對(duì)應(yīng)引腳的端口的中斷使能位為1。

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

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

(1)

LED初始化:關(guān)閉四個(gè)LED。

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

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

【描述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;

//關(guān)閉LED1

LED1=1;

//關(guān)閉LED2

LED2=1;

//關(guān)閉LED3

LED3=1;

//關(guān)閉LED4

LED4=1;

}

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

*io及外部中斷初始化

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

voidInitIO(void)

{

//P0中斷標(biāo)志清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;

};

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

*延時(shí)子函數(shù)

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

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()函數(shù)

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

voidmain(void)

{

//LED初始化

InitLED();

//IO及外部中斷初始化

InitIO();

//等待中斷

Delay(100);

while(1);

}

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

*中斷服務(wù)子程序

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

#pragmavector=P0INT_VECTOR

__interruptvoidP0_ISR(void)

{//關(guān)中斷

P0IEN&=~0x30;

//判斷按鍵中斷

if(P0IFG>0)

{//清中斷標(biāo)志

P0IFG=0;

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

LED1=!LED1;

}

//開中斷

P0IEN|=0x30;

}

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

4.4.3外設(shè)I/O

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

表4-26外設(shè)I/O引腳映射

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

表4-27PERCFG外設(shè)控制寄存器

【示例4-17】PERCFG寄存器設(shè)置

//設(shè)置USART0為外設(shè)位置1

PERCFG|=0x00;

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

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

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

1.

ADC

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

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

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

2.串口

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

用于設(shè)置USART1是使用外設(shè)位置1還是外設(shè)位置2。

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

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

3.定時(shí)器1

PERCFG.T1CFG用于設(shè)置定時(shí)器1是使用外設(shè)位置1還是外設(shè)位置2,定時(shí)器1的外設(shè)信息對(duì)應(yīng)如下:

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

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

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

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

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

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

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

4.定時(shí)器3

PERCFG.T3CFG用于設(shè)置定時(shí)器3是使用外設(shè)位置1還是外設(shè)位置2。

定時(shí)器3信號(hào)顯示如下:

0:通道0比較引腳。

1:通道1比較引腳。

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

5.定時(shí)器4

PERCFG.T4CFG用于設(shè)置定時(shí)器4是使用外設(shè)位置1還是外設(shè)位置2。

定時(shí)器3信號(hào)顯示如下:

0:通道0比較引腳。

1:通道1比較引腳。

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

6.調(diào)試接口

端口P2.1和P2.2分別用于調(diào)試數(shù)據(jù)和時(shí)鐘信號(hào),即DD調(diào)試數(shù)據(jù)和DC調(diào)試時(shí)鐘。當(dāng)處于調(diào)試模式時(shí),調(diào)試接口控制這些引腳的方向,并且在這些引腳上禁用上拉和下拉。

溫馨提示

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

評(píng)論

0/150

提交評(píng)論