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的值并显示?


发布评论