2023年12月30日发(作者:)

12 CC2420内部寄存器初始化

1.实验目的

掌握CC2420内部寄存器的设置。

2.实验设备

硬件:PC机(一台)

教学开发平台(一套)

软件:Keil

串口调试助手

3.实验内容

对CC2420寄存器进行初始化,设置CC2420寄存器数值,并读取设置的寄存器的数值。本实验以CC2420中的MDMCTRL0为例,进行设置,并读取其设置的数值在串口工具上显示出来。

4.实验预习要求

仔细阅读CC2420器件手册中关于寄存器以及CC2420寄存器列表部分,思考如何设置寄存器初值。寄存器的读写请仔细阅读CC2420GetReg()和CC2420SetReg().

5.实验步骤

(1)启动Keil µVision3,建立一个工程;

(2)编写程序代码;

(3)编译程序并生成可执行文件;

(4)下载程序,将开发平台和计算机通过串口线连接起来;

(5)运行程序;

(6)打开串口调试工具来观察结果。观察时采用字符显示,观察到的结果示例:

The value of CC2420_MDMCTRL0 is 02E2

(1)~(5)步骤的详细过程请参考第一、二小节进行操作。

6.实验参考程序

(1)main.h参考程序

#ifndef MAIN_H

#define MAIN_H

#define REG_BIT_DEF sbit

#define GLOBAL_ISR_DISABLE() (EA = 0)

#define GLOBAL_ISR_ENABLE() (EA = 1)

#define EXT_DATA xdata

#define LED P2

#define UART0_BR_1152 243 //243 + 13(13.292) 117788(实测 117647 bit/8.5us)

#define ISR_PRIORITY_HIGH 1

#define ISR_PRIORITY_LOW 0

typedef bit BOOL;

typedef unsigned char BYTE; //8 bit

typedef unsigned int WORD; //16 bit

typedef unsigned long DWORD; //32 bit

typedef unsigned char Bool;

REG_BIT_DEF LED1 = 0xA0; // P2^0;

#define SET_LED(x) (LED##x = 0)

#define CLR_LED(x) (LED##x = 1)

REG_BIT_DEF CCRESET = 0x96; // P1^6;

REG_BIT_DEF CCVREGEN = 0x97; // P1^7;

REG_BIT_DEF FIFOP = 0x92; // P1^2;

REG_BIT_DEF FIFO = 0x94; // P1^4;

REG_BIT_DEF SFD = 0x90; // P1^0;

REG_BIT_DEF CCA = 0x95; // P1^5;

#define SFD_IS_ACTIVE() SFD

#define FIFO_IS_ACTIVE() FIFO

#define CCA_IS_ACTIVE()

#define FIFOP_IS_ACTIVE() !FIFOP

// Command strobes

#define CC2420_SNOP 0x00

#define CC2420_SXOSCON 0x01

#define CC2420_STXCAL 0x02

#define CC2420_SRXON 0x03

#define CC2420_STXON 0x04

#define CC2420_STXONCCA 0x05

#define CC2420_SRFOFF 0x06

#define CC2420_SXOSCOFF 0x07

#define CC2420_SFLUSHRX 0x08

#define CC2420_SFLUSHTX 0x09

#define CC2420_SACK 0x0A

#define CC2420_SACKPEND 0x0B

// Registers

#define CC2420_MAIN 0x10

#define CC2420_MDMCTRL0 0x11

#define CC2420_MDMCTRL1 0x12

#define CC2420_RSSI 0x13

#define CC2420_SYNCWORD 0x14

#define CC2420_TXCTRL 0x15

#define CC2420_RXCTRL0 0x16

#define CC2420_RXCTRL1 0x17

#define CC2420_FSCTRL 0x18

#define CC2420_SECCTRL0 0x19

#define CC2420_SECCTRL1 0x1A

#define CC2420_BATTMON 0x1B

#define CC2420_IOCFG0 0x1C

#define CC2420_IOCFG1 0x1D

#define CC2420_MANFIDL 0x1E

#define CC2420_MANFIDH 0x1F

#define CC2420_FSMTC 0x20

//

//

CCA

SFD bit is set

FIFO bit is set

// CCA bit is set

#define CC2420_MANAND 0x21

#define CC2420_MANOR 0x22

#define CC2420_AGCCTRL 0x23

#define CC2420_AGCTST0 0x24

#define CC2420_AGCTST1 0x25

#define CC2420_AGCTST2 0x26

#define CC2420_FSTST0 0x27

#define CC2420_FSTST1 0x28

#define CC2420_FSTST2 0x29

#define CC2420_FSTST3 0x2A

#define CC2420_RXBPFTST 0x2B

#define CC2420_FSMSTATE 0x2C

#define CC2420_ADCTST 0x2D

#define CC2420_DACTST 0x2E

#define CC2420_TOPTST 0x2F

#define CC2420_RESERVED 0x30

// FIFOs

#define CC2420_TXFIFO 0x3E

#define CC2420_RXFIFO 0x3F

// Memory

// Sizes

#define CC2420_RAM_SIZE 368

#define CC2420_FIFO_SIZE 128

// Addresses

#define CC2420_RAM_TXFIFO 0x000

#define CC2420_RAM_RXFIFO 0x080

#define CC2420_RAM_IEEEADDR 0x160

#define CC2420_RAM_PANID 0x168

#define CC2420_RAM_SHORTADDR 0x16A

#define CC2420_CRC_OK 0x80

#define GLOBAL_ISR_CTRL_REG() (EA)

#define NSS_LOW() (NSSMD0=0)

#define PHY_24G_CHANNEL_MAX 26 // MAX channel number for 2.4G channel

#define PHY_24G_CHANNEL_MIN 11 // MIN channel number for 2.4G channel

#define PHY_24G_CHANNEL_PAGE 0

#define MAX_CHAN_NUM (PHY_24G_CHANNEL_MAX-PHY_24G_CHANNEL_MIN+1)

#define PHY_POWER_LEV_MAX 31 // MAX power level

#define PHY_POWER_LEV_MIN 3 // MIN power level

#define SYSTEM_CLK 24500000

#define SPI0_CLK 5000000

#define SPI0CKR_VALUE (SYSTEM_CLK /2 /SPI0_CLK -1)

#define NSS_LOW() (NSSMD0=0)

#define NSS_HIGH() (NSSMD0=1)

#define APP_TO_MAC_BUF_MAX_NUM 2

#define APP_TO_MAC_BUF_MAX_SIZE 198

#define MAC_TO_APP_BUF_MAX_NUM 2

#define MAC_TO_APP_BUF_MAX_SIZE 128

#define PHY_TO_MAC_BUF_MAX_NUM 1

#define PHY_TO_MAC_BUF_MAX_SIZE 128

#define UART0_TIMEOUT_1152 140 //us

#define TIMER0_RELOAD(x) (65536 - (SYSTEM_CLK /12) *(x) /1000000)

#define UART0_TIMEOUT(BR) TIMER0_RELOAD((115200 /BR) *UART0_TIMEOUT_1152)

#define aMaxPHYPacketSize 127 // The maximum PSDU size (in octets) t

#define aMinPHYPacketSize 5 // The minimal PSDU size (in octets)

typedef struct tag_PHY_PIB{

BYTE phyCurrentChannel; // The RF channel number. 0 ~ 26

DWORD phyChannelsSupported;

BYTE phyTransmitPower; // 0x00 ~ 0xbf represent 31 ~ -32dBm

BYTE phyCCAMode; // 1 ~ 3

BYTE phyCurrentPage; // 0 ~ 31

WORD phyMaxFrameDuration; // The maximum number of symbols in a frame.

BYTE phySHRDuration;

BYTE phySymbolsPerOctet;

BYTE SelfUartBaudrate;

}tPhyPib;

typedef enum{

DEVICE_IDLE = 0,

DATA_IN_TRANSMIT,

DATA_TRANSMIT_COMPLETE,

ERR_DATA_IN_TRANSMIT

}eUartState;

typedef struct tag_UAR_TRX_MANAGE_MESSAGE{

BYTE TxLen;

eUartState TxStatus;

BYTE TxIndex;

BYTE *TxDataFirstAddr;

BYTE RxLen;

BYTE *RxDataFirstAddr;

}tUartTRxManaMsg;

typedef enum{

BUF_EMPTY = 0,

BUF_FULL,

BUF_NORMAL

}eBufState;

typedef struct tag_BUF_MANAGE_MESSAGE{

BYTE EXT_DATA *Buf;

BYTE EXT_DATA *Len;

BYTE MaxSize;

BYTE MaxNum;

BYTE WriteIndex;

BYTE ReadIndex;

eBufState Status;

}tBufManaMsg;

typedef enum tag_UART_BAUDRATE{

BR_115200 = 0x01,

BR_57600,

BR_38400,

BR_19200,

BR_9600

}eUartBaudRate;

typedef struct tag_MAC_TX_BUF{

BYTE Buf[aMaxPHYPacketSize];

BYTE Length;

}tMacTxBuf;

static BYTE EXT_DATA

gPhyToMacBuf[PHY_TO_MAC_BUF_MAX_NUM][PHY_TO_MAC_BUF_MAX_SIZE];

static BYTE EXT_DATA gPhyToMacSonBufDataLen[PHY_TO_MAC_BUF_MAX_NUM];

tBufManaMsg EXT_DATA gPhyToMacBufMana;

tPhyPib EXT_DATA gPhyPib; // phy PIB data

static BYTE EXT_DATA

gAppToMacBuf[APP_TO_MAC_BUF_MAX_NUM][APP_TO_MAC_BUF_MAX_SIZE];

static BYTE EXT_DATA gAppToMacSonBufDataLen[APP_TO_MAC_BUF_MAX_NUM];

static BYTE EXT_DATA

gMacToAppBuf[MAC_TO_APP_BUF_MAX_NUM][MAC_TO_APP_BUF_MAX_SIZE];

static BYTE EXT_DATA gMacToAppSonBufDataLen[MAC_TO_APP_BUF_MAX_NUM];

static tBufManaMsg EXT_DATA gAppToMacBufMana;

static tBufManaMsg EXT_DATA gMacToAppBufMana;

static tUartTRxManaMsg EXT_DATA gUartTRxManaMsg;

tMacTxBuf EXT_DATA gMacTxBuf;

#ifndef TRUE

#define TRUE 1

#endif

#ifndef FALSE

#define FALSE 0

#endif

#ifndef NULL

#define NULL ((void*)0)

#endif

#endif

(1) main.c参考程序

#include

#include

#include "main.h"

//////////////////////////////////////////////////////////////////////////

//名称:WTDDisable()

//功能:关闭看门狗

//////////////////////////////////////////////////////////////////////////

void WTDDisable(void){

GLOBAL_ISR_DISABLE(); //writing to 0xDE and 0xAD must be finished in 4 clock cycles

WDTCN = 0xDE;

WDTCN = 0xAD;

GLOBAL_ISR_ENABLE();

}

//////////////////////////////////////////////////////////////////////////

//名称:SystemClkInit()

//功能:系统时钟初始化

//////////////////////////////////////////////////////////////////////////

void SystemClkInit(void){

WORD EXT_DATA tmp;

SFRPAGE = CONFIG_PAGE;

OSCXCN = 0x67; // enable ext osc 10-30MHz range

for (tmp=24500; tmp!=0; tmp--) // Wait 1ms for initialization

{

;

}

while ((OSCXCN & 0x80) == 0)

{

;

}

OSCICN = 0x83; // Enable 24.5 MHz internal osc

for (tmp=24500; tmp!=0; tmp--) // Wait 1ms for initialization

{

;

}

while ((OSCICN & 0x40) == 0)

{

;

}

CLKSEL = 0x00; // Select internal clock source

}

//////////////////////////////////////////////////////////////////////////

//名称:SfrAutoSwithDis()

//功能:SFR自动页切换关闭

//////////////////////////////////////////////////////////////////////////

void SfrAutoSwitchDis(void){

SFRPAGE = CONFIG_PAGE;

SFRPGCN = 0x00;

}

//////////////////////////////////////////////////////////////////////////

//名称:PortInit()

//功能:端口初始化

//////////////////////////////////////////////////////////////////////////

void PortInit(void){

SFRPAGE = CONFIG_PAGE; // SFR page switching

XBR0 |= 0x04; // enable UART

P0MDOUT |= 0x01; // enable TX as a push-pull output

XBR0 |= 0x02; // Enable SPI

P0MDOUT |= 0x34; // SCK,MOSI,NSS push-pull output

XBR0 |= 0x01; // enable smbus (skip 2 pins)

XBR0 |= 0x10; // enable CEX0 = P1.0,CEX1 = P1.1

XBR1 |= 0x04; // enable /int0 = P1.2

P1MDOUT |= 0xC0; // RESET VRGEN push-pull output

XBR2 |= 0x40; // Enable Crossbar

}

//////////////////////////////////////////////////////////////////////////

//名称:Uart0Init()

//功能:UART0初始化

//入口参数:优先级

//////////////////////////////////////////////////////////////////////////

void Uart0Init(BOOL pri){

ES0 = 1;

if(pri){

IP |= 0x10;

}

else{

IP &= 0xEF;

}

SFRPAGE = UART0_PAGE; //Config UART0 register

SCON0 = 0x50; //Mode1(8 bit data),No check stop bit,Enable receive

SSTA0 = 0x10; //Baud rate doubler enable,T1溢出率为TX和RX的时钟源

SFRPAGE = TIMER01_PAGE; //Config timer1 register

TCON = 0x00;

TMOD = 0x20; //T1 timer mode uses 8 bit overload

CKCON = 0x10; //T1 timer is used for system clock

TR1 = 0;

}

//////////////////////////////////////////////////////////////////////////

//名称:Uart0TimeOutTimerInit()

//功能:This function initializes the UART timer (Timer0).

//入口参数:优先级

//////////////////////////////////////////////////////////////////////////

void Uart0TimeOutTimerInit(BOOL pri){

PT0 = pri; //定时器0中断优先级控制

SFRPAGE = TIMER01_PAGE;

TMOD |= 0x01; //16 bit

TF0 = 0;

TR0 = 0; //Turn off timer0

}

void Uart0TimeOutTimerTurnOff(void){

BYTE saveSfr = SFRPAGE;

SFRPAGE = TIMER01_PAGE;

TR0 = 0; // stop timer count

TF0 = 0; // clear isr flag

ET0 = 0; // Turn off isr

TH0 = 0; //

TL0 = 0;

SFRPAGE = saveSfr;

}

//////////////////////////////////////////////////////////////////////////

//名称:Spi0Init()

//功能:SPI设置

//////////////////////////////////////////////////////////////////////////

void Spi0Init(void){

SFRPAGE = SPI0_PAGE; // SFR page switching

SPI0CFG = 0x40; // master mode, + clock, 1st edge

SPI0CN = 0x0C; // 4 wire NSS high

SPI0CKR = SPI0CKR_VALUE; // init SPI clock

SPI0CN |= 0x01; // enable SPI

SFRPAGE = 0x0F; // disable spi interrupt

EIE1 &=0xF6;

}

//////////////////////////////////////////////////////////////////////////

//名称:ExternalISRInit()

//功能:外部中断设置

//////////////////////////////////////////////////////////////////////////

void ExternalISRInit(BOOL pri){

SFRPAGE = TIMER01_PAGE;

TCON |= 0x01; // low level triggered

TCON &= ~0x02; // clear IE0 flag

IE |= 0x01; // Enable INT0

if(pri){

IP |= 0x01;

}

else{

IP &= 0xFE;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:Uart0SetBaudrate()

//功能:UART0波特率设置

//入口参数:波特率

//////////////////////////////////////////////////////////////////////////

void Uart0SetBaudrate(BYTE baudrate){

SFRPAGE = TIMER01_PAGE;

TR1 = 0; //Turn off T1

TH1 = baudrate;

TL1 = baudrate;

TR1 = 1; //Turn on T1

}

//////////////////////////////////////////////////////////////////////////

//名称:XdataMemset()

//功能:This function sets the first length bytes in buffer to value

//入口参数:

// p: buffer point to set.

// value: byte value to set

// len: buffer length to set

//////////////////////////////////////////////////////////////////////////

void XdataMemset(void EXT_DATA *p, BYTE value, WORD EXT_DATA len) reentrant{

BYTE EXT_DATA *byteP;

if(len == 0){

return;

}

byteP = (BYTE EXT_DATA *)p;

while(len--){

*byteP++ = value;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:UartTRxManaMsgInit()

//功能:Initialize Uart0 trx data control structure

//////////////////////////////////////////////////////////////////////////

void UartTRxManaMsgInit(void){

XdataMemset(&gUartTRxManaMsg, 0, sizeof(gUartTRxManaMsg));

FirstAddr = NULL;

FirstAddr = NULL;

}

//////////////////////////////////////////////////////////////////////////

//名称:BufBetweenAppAndMacInit()

//功能:This function initialize the buffer information between App and Mac

//////////////////////////////////////////////////////////////////////////

void BufBetweenAppAndMacInit(void){

XdataMemset(&gAppToMacBuf, 0, sizeof(gAppToMacBuf));

XdataMemset(&gAppToMacSonBufDataLen, 0, sizeof(gAppToMacSonBufDataLen));

XdataMemset(&gMacToAppBuf, 0, sizeof(gMacToAppBuf));

XdataMemset(&gMacToAppSonBufDataLen, 0, sizeof(gMacToAppSonBufDataLen));

= &gAppToMacBuf[0][0];

= gAppToMacSonBufDataLen;

e = APP_TO_MAC_BUF_MAX_SIZE;

= APP_TO_MAC_BUF_MAX_NUM;

ndex = 0;

dex = 0;

= BUF_EMPTY;

= &gMacToAppBuf[0][0];

= gMacToAppSonBufDataLen;

e = MAC_TO_APP_BUF_MAX_SIZE;

= MAC_TO_APP_BUF_MAX_NUM;

ndex = 0;

dex = 0;

= BUF_EMPTY;

}

//////////////////////////////////////////////////////////////////////////

//名称:PhyPibInit()

//功能:This procedure will do a initialization on globle PHY PIB database

//////////////////////////////////////////////////////////////////////////

void PhyPibInit(void)

{

rentChannel = 11; // channel 11

rentPage = PHY_24G_CHANNEL_PAGE; // current page is 0

nnelsSupported = 0x07FFF800; // page 0 supported, 16 valid channels

nsmitPower = 31; // 0x00 ~ 0xbf represent 31 ~ -32dBm

Mode = 2; // carrier sense only

FrameDuration = 266; // the maximum number of symbols

Duration = 10; // the duration of the sync header is 3, 7, 10, 40

bolsPerOctet = 2; // the number of symbols per octet

rtBaudrate = BR_115200; //BR_38400;

}

//////////////////////////////////////////////////////////////////////////

//名称:Delay1us()

//功能:延时1us

//入口参数:延时的时间

//////////////////////////////////////////////////////////////////////////

void Delay1us(WORD EXT_DATA time)

{

while(time--)

{

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

_nop_(); _nop_(); _nop_(); _nop_();

}

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420Strobe()

//功能:This function sends a strobe command byte out of the SPI to the CC2420

//入口参数:CC2420 command

//出口参数:CC2420 status register value

//////////////////////////////////////////////////////////////////////////

BYTE CC2420Strobe(BYTE strobe){

BYTE EaSave;

if(strobe > 0x0F){

strobe = CC2420_SNOP;

}

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW(); // force NSS low,start cc2420 spi

SPIF = 0; // clear SPI0 interrupt tag

SPI0DAT = strobe;

while(!SPIF){ ;} // Wait until finished

strobe = SPI0DAT; // read Recv'd data.

SPIF = 0; // clear interrupt flag

NSS_HIGH(); // force NSS high,stop cc2420 spi

GLOBAL_ISR_CTRL_REG() = EaSave;

return strobe;

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420StatusRead()

//功能:This function sends a NOP command and returns the CC2420's status value

//出口参数:CC2420 status register value

//////////////////////////////////////////////////////////////////////////

BYTE CC2420StatusRead(void){

BYTE value;

BYTE EaSave;

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW(); // force NSS low,Csn=0,cc2420 spi work

SPIF = 0;

SPI0DAT = CC2420_SNOP;

while(!SPIF){ ;} // Wait until finished

value = SPI0DAT; // read Recv'd data.

SPIF = 0; // clear interrupt flag

NSS_HIGH(); // force NSS high

GLOBAL_ISR_CTRL_REG() = EaSave;

return value;

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420SetReg()

//功能:This function is used to set the value of the CC2420 registers

//入口参数:add:CC2420 register address;value: register value to set

//////////////////////////////////////////////////////////////////////////

void CC2420SetReg(BYTE add,WORD value){

BYTE EaSave;

if((add > 0x0F) && (add < 0x30)){

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW(); // force NSS low,start cc2420 spi

SPIF = 0; // clear SPI0 interrupt tag

SPI0DAT = add; // Send address

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

SPI0DAT = (BYTE)(value >> 8); // Send value high 8 bits

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

SPI0DAT = (BYTE)value; // Send value low 8 bits

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

NSS_HIGH(); // force NSS high,stop cc2420 spi

GLOBAL_ISR_CTRL_REG() = EaSave;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420GetReg()

//功能:This function is used to read the value of the CC2420 registers

//入口参数:add: CC2420 register address

//出口参数:the CC2420 register value

//////////////////////////////////////////////////////////////////////////

WORD CC2420GetReg(BYTE add){

BYTE EaSave;

WORD value;

if((add > 0x0F) && (add < 0x30)){

add |= 0x40; // set bit 6

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW();

SPIF = 0;

SPI0DAT = add; // Send address

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

SPI0DAT = 0x00; // Get register high 8 bits

while(!SPIF){ ;}

value = SPI0DAT << 8;

SPIF = 0;

SPI0DAT = (BYTE)value; // Get register low 8 bits

while(!SPIF){ ;}

value += SPI0DAT;

SPIF = 0;

NSS_HIGH();

GLOBAL_ISR_CTRL_REG() = EaSave;

return value;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:PhySetTxPower()

//功能:This procedure will set current transmit power to a new specified level

//入口参数:chan: channel number;txPower: transmit power

//出口参数:state: To report the result of setting a new transmit power

//////////////////////////////////////////////////////////////////////////

BYTE PhySetTxPower(BYTE phyPower){

BYTE i;

WORD EXT_DATA rRegVal, wRegVal;

if (phyPower > PHY_POWER_LEV_MAX || phyPower < PHY_POWER_LEV_MIN){

i = 0;

return i;

}

rRegVal = CC2420GetReg(CC2420_TXCTRL);

wRegVal = (rRegVal & 0xFFE0) + phyPower;

CC2420SetReg(CC2420_TXCTRL, wRegVal);

i = 1;

return i;

}

//////////////////////////////////////////////////////////////////////////

//名称:PhySetCurrentChannel()

//功能:This procedure will set current channel to a new specified channel

//入口参数:phyChannel: The new channel number

//出口参数:state: To report the result of setting a new channel

//////////////////////////////////////////////////////////////////////////

BYTE PhySetCurrentChannel(BYTE phyChannel){

BYTE i;

WORD EXT_DATA rRegVal, wRegVal;

if(phyChannel < PHY_24G_CHANNEL_MIN || phyChannel > PHY_24G_CHANNEL_MAX){

i = 0;

return i;

}

// read current channel's register value

rRegVal = CC2420GetReg(CC2420_FSCTRL);

// calculate the new channel's register value, lock_thr number use 1

wRegVal = 357 + 5*(phyChannel - 11) + 0x40000;

// check if the current channel is the channel we want to set

if((rRegVal & 0x3FF) == (wRegVal & 0x3FF)){

i = 1;

return i;

}

wRegVal = wRegVal + (rRegVal & 0xFC00); // save the old register value

CC2420Strobe(CC2420_SRFOFF); // turn off the RF

CC2420SetReg(CC2420_FSCTRL, wRegVal); // set the new channel's register value

CC2420Strobe(CC2420_SRXON); // turn on the RF and set to RX_ON

i = 1;

return i;

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420Init()

//功能:This is the 2420 initialization procedure

//入口参数:chan: channel number;txPower: transmit power

//////////////////////////////////////////////////////////////////////////

void CC2420Init(BYTE chan, BYTE txPower){

CCRESET = 0; // reset CC2420

CCVREGEN = 1; // enable regulator

Delay1us(64700); // delay for stablization

CCRESET = 1; // reset

CC2420Strobe(CC2420_SXOSCON); // turn on CC2420 Osc

Delay1us(4700); // delay 4.7ms

while ((CC2420StatusRead() & 0x40) == 0){ // wait for osc stable bit

;

}

CC2420Strobe(CC2420_SFLUSHRX); // flush cc2420's rx fifo

CC2420Strobe(CC2420_SFLUSHTX); // flush cc2420's tx fifo

CC2420SetReg(CC2420_IOCFG0,0x027F); //Setting FIFOP to 127 bytes active low

CC2420SetReg(CC2420_TXCTRL,0x80FF); //Set the wait time after STXON:is 8 symbols

PhySetTxPower(txPower); //Change Send Power

PhySetCurrentChannel(chan); //set current channel

// set CC2420,crc en,cca mode is 3,autoack disable,addr recognition disable

CC2420SetReg(CC2420_MDMCTRL0,0x02E2);

CC2420SetReg(CC2420_RSSI,0xEC80); //-20 (0xEA80 -22)

CC2420SetReg(CC2420_MDMCTRL1, 0x0500);

CC2420Strobe(CC2420_SRXON);

}

//////////////////////////////////////////////////////////////////////////

//名称:PhyToMacBufInit()

//功能:This function initialize the buffer information of Phy to Mac

//////////////////////////////////////////////////////////////////////////

void PhyToMacBufInit(void){

XdataMemset(&gPhyToMacBuf, 0, sizeof(gPhyToMacBuf));

XdataMemset(&gPhyToMacSonBufDataLen, 0, sizeof(gPhyToMacSonBufDataLen));

= &gPhyToMacBuf[0][0];

= gPhyToMacSonBufDataLen;

e = PHY_TO_MAC_BUF_MAX_SIZE;

= PHY_TO_MAC_BUF_MAX_NUM;

ndex = 0;

dex = 0;

= BUF_EMPTY;

}

//////////////////////////////////////////////////////////////////////////

//名称:ReadGetBufData()

//功能:This function is used to retrive the data address of RX buffer

//入口参数:bufManaMsg and len

//////////////////////////////////////////////////////////////////////////

BYTE *ReadGetBufData(tBufManaMsg * bufManaMsg, BYTE *len){

if(bufManaMsg->Status != BUF_EMPTY){

if(len != NULL){

*len = bufManaMsg->Len[bufManaMsg->ReadIndex];

}

return (&bufManaMsg->Buf[bufManaMsg->ReadIndex * bufManaMsg->MaxSize]);

}

else{

return NULL;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:SonBufWriteRelease()

//功能:This function releases a son data buffer

//入口参数:bufManaMsg

//////////////////////////////////////////////////////////////////////////

void SonBufWriteRelease(tBufManaMsg * bufManaMsg){

bufManaMsg->WriteIndex++;

if(bufManaMsg->WriteIndex == bufManaMsg->MaxNum){

bufManaMsg->WriteIndex = 0;

}

if(bufManaMsg->WriteIndex == bufManaMsg->ReadIndex){

bufManaMsg->Status = BUF_FULL;

}

else{

bufManaMsg->Status = BUF_NORMAL;

bufManaMsg->Len[bufManaMsg->WriteIndex] = 0;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:SonBufReadRelease()

//功能:This function releases a son data buffer

//入口参数:bufManaMsg

//////////////////////////////////////////////////////////////////////////

void SonBufReadRelease(tBufManaMsg * bufManaMsg){

bufManaMsg->Len[bufManaMsg->ReadIndex] = 0;

bufManaMsg->ReadIndex++;

if(bufManaMsg->ReadIndex == bufManaMsg->MaxNum){

bufManaMsg->ReadIndex = 0;

}

if(bufManaMsg->ReadIndex == bufManaMsg->WriteIndex){

bufManaMsg->Status = BUF_EMPTY;

}

else{

bufManaMsg->Status = BUF_NORMAL;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:XdataToXdataMemcpy()

//功能:This function copys length(len) bytes from source(src) buffer to destination(dest) buffer

//入口参数:dest: destination buffer point

// src: source buffer point

// len: maximum bytes to copy

//////////////////////////////////////////////////////////////////////////

void XdataToXdataMemcpy(void EXT_DATA *dest, void EXT_DATA *src, WORD EXT_DATA

len) reentrant{

BYTE EXT_DATA *destP;

BYTE EXT_DATA *srcP;

if(len == 0){

return;

}

destP = (BYTE EXT_DATA *)dest;

srcP = (BYTE EXT_DATA *)src;

while(len--){

*destP++ = *srcP++;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:GetBufStatus()

//功能:This function is used to get status

//入口参数:bufManaMsg

//出口参数:status

//////////////////////////////////////////////////////////////////////////

eBufState GetBufStatus(tBufManaMsg * bufManaMsg){

return (bufManaMsg->Status);

}

//////////////////////////////////////////////////////////////////////////

//名称:WriteGetBufLenAddr()

//功能:This function is used to get buffer length address

//入口参数:bufManaMsg

//出口参数:len

//////////////////////////////////////////////////////////////////////////

BYTE *WriteGetBufLenAddr(tBufManaMsg * bufManaMsg){

return(&bufManaMsg->Len[bufManaMsg->WriteIndex]);

}

//////////////////////////////////////////////////////////////////////////

//名称:UartTxByte()

//功能:This function is used to send one byte data

//入口参数:value:one byte data

//////////////////////////////////////////////////////////////////////////

void UartTxByte(BYTE value){

BYTE SfrSave = SFRPAGE;

SFRPAGE = UART0_PAGE;

SBUF0 = value;

SFRPAGE = SfrSave;

}

//////////////////////////////////////////////////////////////////////////

//名称:MacToAppDataProc()

//功能:This function send data to higher layer through UART

//////////////////////////////////////////////////////////////////////////

void MacToAppDataProc(void){

switch(us){

case DATA_IN_TRANSMIT:

break;

case DEVICE_IDLE:

if(GetBufStatus(&gMacToAppBufMana) != BUF_EMPTY){

FirstAddr = ReadGetBufData(&gMacToAppBufMana,

&); x = 1;

UartTxByte(FirstAddr[0]);

us = DATA_IN_TRANSMIT;

}

break;

case DATA_TRANSMIT_COMPLETE:

SonBufReadRelease(&gMacToAppBufMana);

= 0;

x = 0;

FirstAddr = NULL;

us = DEVICE_IDLE;

break;

default:

break;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420ReadFIFO()

//功能:This function reads a specified number of bytes from the FIFO

//入口参数:*point: Rx buffer point; len : data length to read

//////////////////////////////////////////////////////////////////////////

BYTE CC2420ReadFIFO(BYTE EXT_DATA *pData, BYTE len){

BYTE EaSave;

if(len == 0 || len > 127 || FIFO == 0){

return FALSE;

}

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE(); // disable global intterupt

SFRPAGE = SPI0_PAGE;

NSS_LOW(); // force NSS low

SPIF = 0; // clear interrupt flag

SPI0DAT = CC2420_RXFIFO | 0x40; // RXFIFO command

while(!SPIF){ ;}

ACC = SPI0DAT;

while(len--){

GLOBAL_ISR_DISABLE();

SPIF = 0;

SPI0DAT = 0x00;

while(!SPIF){ ;}

*pData++ = SPI0DAT;

if(!FIFO){

break;

}

GLOBAL_ISR_ENABLE();

}

SPIF = 0;

NSS_HIGH(); // force NSS high

GLOBAL_ISR_CTRL_REG() = EaSave;

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420BrushFIFOBytes()

//功能:This function brush specified number of FIFO bytes

//入口参数:len: number of bytes

//////////////////////////////////////////////////////////////////////////

BYTE CC2420BrushFIFOBytes(BYTE len){

BYTE EaSave;

if(len > 127 || FIFO == 0){

return FALSE;

}

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW(); // force NSS low

SPIF = 0; // clear interrupt flag

SPI0DAT = CC2420_RXFIFO | 0x40; // RXFIFO command

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

while(len--){

GLOBAL_ISR_DISABLE();

SPI0DAT = 0x00;

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0;

if(!FIFO){

break;

}

GLOBAL_ISR_ENABLE();

}

NSS_HIGH(); // force NSS high

GLOBAL_ISR_CTRL_REG() = EaSave;

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

//名称:SaveByteToBuf()

//功能:This function is called to receive one byte data from UART

//入口参数:value: one byte data

//////////////////////////////////////////////////////////////////////////

BOOL SaveByteToBuf(tBufManaMsg * bufManaMsg, BYTE value)

{

BYTE dataIndex, dataLen;

BYTE bufMaxSize, bufMaxNum;

if(bufManaMsg->Status == BUF_FULL){ // Check if the buf is full

return FALSE;

}

dataIndex = bufManaMsg->WriteIndex;

dataLen = bufManaMsg->Len[dataIndex];

bufMaxSize = bufManaMsg->MaxSize;

bufMaxNum = bufManaMsg->MaxNum;

bufManaMsg->Buf[dataIndex * bufMaxSize + dataLen] = value;

dataLen++;

bufManaMsg->Len[dataIndex] = dataLen;

if(dataLen == bufMaxSize){

bufManaMsg->WriteIndex++;

if(bufManaMsg->WriteIndex >= bufMaxNum){

bufManaMsg->WriteIndex = 0;

}

if(bufManaMsg->WriteIndex == bufManaMsg->ReadIndex){

bufManaMsg->Status = BUF_FULL;

}

else{

bufManaMsg->Status = BUF_NORMAL;

bufManaMsg->Len[bufManaMsg->WriteIndex] = 0;

}

}

return TRUE;

}

//////////////////////////////////////////////////////////////////////////

//名称:WriteGetBufDataUartIsr()

//功能:This function is used to retrive the data address of buffer

//入口参数:bufManaMsg and len

//////////////////////////////////////////////////////////////////////////

BYTE *WriteGetBufDataUartIsr(tBufManaMsg * bufManaMsg, BYTE *len){

if(bufManaMsg->Status != BUF_FULL){

*len = bufManaMsg->Len[bufManaMsg->WriteIndex];

return (&bufManaMsg->Buf[bufManaMsg->WriteIndex * bufManaMsg->MaxSize]);

}

else{

return NULL;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:Uart0TimeOutTimerSetTime()

//功能:This function sets the UART timeout time (Baudrate)

//入口参数:br: baudrate

//////////////////////////////////////////////////////////////////////////

void Uart0TimeOutTimerSetTime(eUartBaudRate br){

BYTE saveSfr;

WORD outTime;

switch(br){

case BR_115200:

outTime = UART0_TIMEOUT(115200);

break;

case BR_57600:

outTime = UART0_TIMEOUT(57600);

break;

case BR_38400:

outTime = UART0_TIMEOUT(38400);

break;

case BR_19200:

outTime = UART0_TIMEOUT(19200);

break;

case BR_9600:

outTime = UART0_TIMEOUT(9600);

break;

default:

outTime = UART0_TIMEOUT(9600);

break;

}

saveSfr = SFRPAGE;

SFRPAGE = TIMER01_PAGE;

TR0 = 0;

ET0 = 1; //Enable timer0 interrupt

TH0 = (BYTE)(outTime >> 8);

TL0 = (BYTE)outTime;

TR0 = 1;

SFRPAGE = saveSfr;

}

//////////////////////////////////////////////////////////////////////////

//名称:WriteGetBufDataAddr()

//功能:This function is used to retrive the data address of buffer

//入口参数:bufManaMsg

//////////////////////////////////////////////////////////////////////////

BYTE *WriteGetBufDataAddr(tBufManaMsg * bufManaMsg){

if(bufManaMsg->Status != BUF_FULL){

return (&bufManaMsg->Buf[bufManaMsg->WriteIndex * bufManaMsg->MaxSize]);

}

else{

return NULL;

}

}

//////////////////////////////////////////////////////////////////////////

//名称:UartIsrRx()

//功能:This function is called to receive one byte data from UART

//入口参数:value: one byte data

//////////////////////////////////////////////////////////////////////////

static void UartIsrRx(BYTE value)

{

Uart0TimeOutTimerTurnOff();

if(SaveByteToBuf(&gAppToMacBufMana, value) == FALSE){

return;

}

FirstAddr = WriteGetBufDataUartIsr(&gAppToMacBufMana,

&);

if( > 1){

if( == FirstAddr[0] + 1)

{

SonBufWriteRelease(&gAppToMacBufMana);

FirstAddr = NULL;

= 0;

return;

}

}

Uart0TimeOutTimerSetTime(rtBaudrate);

}

//////////////////////////////////////////////////////////////////////////

//名称:UartIsrTx()

//功能:This function is called to send one byte data from UART

//入口参数:value: one byte data

//////////////////////////////////////////////////////////////////////////

static void UartIsrTx(void){

if(us == DATA_IN_TRANSMIT){

if(x >= ()){

us = DATA_TRANSMIT_COMPLETE;

}

else{

UartTxByte(FirstAddr[x]);

x++;

}

}

}

//////////////////////////////////////////////////////////////////////////

//名称:CC2420ReadFIFOByte()

//功能:This function reads a byte from the FIFO

//出口参数:a byte RF FIFO data

//////////////////////////////////////////////////////////////////////////

BYTE CC2420ReadFIFOByte(void){

BYTE EaSave;

BYTE temp;

if(!FIFO){

return FALSE;

}

EaSave = GLOBAL_ISR_CTRL_REG();

GLOBAL_ISR_DISABLE();

SFRPAGE = SPI0_PAGE;

NSS_LOW();

SPIF = 0; // clear interrupt flag

SPI0DAT = CC2420_RXFIFO | 0x40; // RXFIFO command

while(!SPIF){ ;}

ACC = SPI0DAT;

SPIF = 0; // clear interrupt flag

SPI0DAT = 0x00;

while(!SPIF){ ;}

temp = SPI0DAT;

SPIF = 0;

NSS_HIGH(); // force NSS high

GLOBAL_ISR_CTRL_REG() = EaSave;

return temp;

}

//////////////////////////////////////////////////////////////////////////

//名称:ExtIsrRF()

//功能:This is the external receive interrupt handle procedure

//////////////////////////////////////////////////////////////////////////

void ExtIsrRF(void) interrupt 0

{

BYTE SfrSave;

BYTE frmLen;

BYTE *pData;

SfrSave = SFRPAGE;

SFRPAGE = TIMER01_PAGE;

if((FIFOP_IS_ACTIVE() == TRUE) && (FIFO_IS_ACTIVE() == FALSE))

{

CC2420Strobe(CC2420_SFLUSHRX);

CC2420Strobe(CC2420_SFLUSHRX);

SFRPAGE = SfrSave;

return;

}

// read the frame length from FIFO

frmLen = CC2420ReadFIFOByte();

// if length is incorrect, flush the RX FIFO

if(frmLen < aMinPHYPacketSize || frmLen > aMaxPHYPacketSize )

{

CC2420Strobe(CC2420_SFLUSHRX);

SFRPAGE = SfrSave;

return;

}

// if MAC rx buf is full, return

if(GetBufStatus(&gPhyToMacBufMana) == BUF_FULL)

{

CC2420BrushFIFOBytes(frmLen);

SFRPAGE = SfrSave;

return;

}

pData = WriteGetBufDataAddr(&gPhyToMacBufMana);

*pData++ = frmLen;

CC2420ReadFIFO(pData, frmLen);

*WriteGetBufLenAddr(&gPhyToMacBufMana) = frmLen + 1;

SonBufWriteRelease(&gPhyToMacBufMana);

SFRPAGE = SfrSave;

}

//////////////////////////////////////////////////////////////////////////

//名称:UartRxDataTimeoutProc()

//功能:This function is timer0 interrupt service routine

//////////////////////////////////////////////////////////////////////////

void UartRxDataTimeoutProc(void) interrupt 1{

BYTE SfrSave = SFRPAGE;

SFRPAGE = TIMER01_PAGE;

if(TF0){

TF0 = 0;

TR0 = 0; //turn off timer0

SonBufWriteRelease(&gAppToMacBufMana);

FirstAddr = NULL;

= 0;

}

SFRPAGE = SfrSave;

}

//////////////////////////////////////////////////////////////////////////

//名称:UartTRxISR()

//功能:This function is UART0 TRX interrupt service routine

//////////////////////////////////////////////////////////////////////////

void UartTRxISR(void) interrupt 4{

BYTE SfrSave = SFRPAGE;

SFRPAGE = UART0_PAGE;

if(RI0){

RI0 = 0;

UartIsrRx(SBUF0);

}

if(TI0){

TI0 = 0;

UartIsrTx();

}

SFRPAGE = SfrSave;

}

//////////////////////////////////////////////////////////////////////////

//名称:TestCase12()

//功能:This function is used to output the init information

//////////////////////////////////////////////////////////////////////////

void TestCase12(void){

BYTE EXT_DATA a[]={'T','h','e',' ','v','a','l','u','e',' ','o','f',' ','C','C','2','4','2','0',

'_','M','D','M','C','T','R','L','0',' ','i','s',' ',0,0,0,0};

BYTE EXT_DATA n = sizeof(a);

BYTE EXT_DATA i = CC2420GetReg(CC2420_MDMCTRL0) >> 8;

//得到CC2420_MDMCTRL0寄存器高8位的值

a[n-4] = ((i>>4)>9)? (i>>4)+55:(i>>4)+48;

//将得到的寄存器高8位值的高4位转换为相应的字符ASCII码

a[n-3] = ((i&0x0F)>9)? (i&0x0F)+55:(i&0x0F)+48;

//将得到的寄存器高8位值的低4位转换为相应的字符ASCII码

i =CC2420GetReg(CC2420_MDMCTRL0);

//得到CC2420_MDMCTRL0寄存器低8位的值

a[n-2] = ((i>>4)>9)? (i>>4)+55:(i>>4)+48;

//将得到的寄存器低8位值的高4位转换为相应的字符ASCII码

a[n-1] = ((i&0x0F)>9)? (i&0x0F)+55:(i&0x0F)+48;

//将得到的寄存器低8位值的低4位转换为相应的字符ASCII码

XdataToXdataMemcpy(,a,sizeof(a));

*WriteGetBufLenAddr(&gMacToAppBufMana) = sizeof(a);

SonBufWriteRelease(&gMacToAppBufMana);

}

void main(void){

WTDDisable();

GLOBAL_ISR_DISABLE();

SystemClkInit();

SfrAutoSwitchDis();

PortInit();

Uart0Init(ISR_PRIORITY_HIGH);

Uart0TimeOutTimerInit(ISR_PRIORITY_LOW);

Spi0Init();

ExternalISRInit(ISR_PRIORITY_LOW);

UartTRxManaMsgInit();

BufBetweenAppAndMacInit();

PhyPibInit();

//Initialize the CC2420 related settings

CC2420Init(rentChannel, nsmitPower);

Uart0SetBaudrate(UART0_BR_1152);

PhyToMacBufInit();

GLOBAL_ISR_ENABLE();

TestCase12();

while(1){

MacToAppDataProc();

}

}

7.思考题

(1)如何对其他寄存器进行设置并显示?

(2)如何读取RAM的值并显示?