#include <msp430.h>
//==============================================================================
#define uchar unsigned char
#define uint unsigned int
#define uclong unsigned long
//==================TXEN,TRX_CE,PWR_0 為收發模式控制端口======================
#define TXEN_0 P2OUT &=~BIT0 //輸出0
#define TXEN_1 P2OUT |= BIT0 //輸出1
//==============================================================================
#define TRX_CE_0 P2OUT &=~BIT1
#define TRX_CE_1 P2OUT |= BIT1
//==============================================================================
#define PWR_0 P2OUT &=~BIT2
#define PWR_1 P2OUT |= BIT2
//===================================主入從出===================================
#define MISO_0 P1OUT &=~BIT2
#define MISO_1 P1OUT |= BIT2
//==================================主出從入====================================
#define MOSI_0 P1OUT &=~BIT1
#define MOSI_1 P1OUT |= BIT1
//===================================SPI時鐘端口================================
#define SCK_0 P1OUT &=~BIT4
#define SCK_1 P1OUT |= BIT4
//===================================SPI使能端口=================================
#define CSN_0 P1OUT &=~BIT5
#define CSN_1 P1OUT |= BIT5
//==================================以下為狀態端口==============================
//===========================AM 地址匹配=======================================
#define AM_0 P2OUT &=~BIT5
#define AM_1 P2OUT |= BIT5
//=================================DR 數據接收狀態==============================
#define DR_0 P2OUT &=~BIT4
#define DR_1 P2OUT |= BIT4
//=====================================CD 載波偵聽狀態==========================
#define CD_0 P2OUT &=~BIT3
#define CD_1 P2OUT |= BIT3
//==============================================================================
#define LED1_0 P1OUT &=~BIT0 //輸出0
#define LED1_1 P1OUT |= BIT0 //輸出1
//===========================NRF905:SPI指令=====================================
#define WC 0x00
#define RC 0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
//==========================32字節發送數據收發緩沖區============================
#define TxRxBuf_Len 4
char TxBuf[TxRxBuf_Len];
char RxBuf[TxRxBuf_Len];
//==========================NRF905:10寄存器配置================================
unsigned char RFConf[11]=
{
WC, //SPI寫操作命令
0x4c, //CH_NO,配置頻段在430MHZ
0x0C, //輸出功率為10db,不重發,節電為正常模式
0x44, //地址寬度設置,為4字節
0x20,0x20, //接收發送有效數據長度為4字節
0xCC,0xCC,0xCC,0xCC, //接收地址
0x58, //CRC充許,8位CRC校驗,外部時鐘信號不使能,16M晶振
};
uchar TxAddress[4]={0xcc,0xcc,0xcc,0xcc};
uchar DATA_BUF;
/*****************************************************************************
系統初始化
******************************************************************************/
void InitSys()
{
unsigned int iq0;
_DINT();
BCSCTL1 &=~XT2OFF;
do
{
IFG1 &= ~OFIFG; // 清除振蕩器失效標志
for (iq0 = 0xFF; iq0 > 0; iq0--); // 延時,等待XT2起振
}
while ((IFG1 & OFIFG) != 0); // 判斷XT2是否起振
BCSCTL2 =SELM1+SELS; //MCLK,SMCLK時鐘為XT2
//???USART0
}
//==============================================================================
void LED_IO_set(void)
{
P1DIR |= 0x01;
}
//==============================================================================
void KEY_IO_set(void)
{
P1REN|=BIT3;
P1DIR &=~BIT3;
}
//==========================延時================================================
void Delay(uchar n)
{
uint i;
while(n--)
for(i=0;i<80;i++);
}
//=========================NRF905 SPI讀函數(IO模擬SPI時序)==================
unsigned char SpiRead(void)
{
unsigned char i;
for (i=0;i<8;i++)
{
DATA_BUF=DATA_BUF<<1;
SCK_1;
if ((P1IN&0x04)) //讀取最高位,保存至最末尾,通過左移位完成整個字節
{
DATA_BUF|=0x01;
}
else
{
DATA_BUF&=~(0x01);
}
SCK_0;
}
return DATA_BUF;
}
//=========================NRF905 SPI讀寫函數(IO模擬SPI時序)==================
void SpiWrite(unsigned char send)
{
unsigned char i;
DATA_BUF=send;
for (i=0;i<8;i++)
{
if (((DATA_BUF&0x80) != 0)) //總是發送最高位
{
MOSI_1;
}
else
{
MOSI_0;
}
SCK_1;
DATA_BUF=DATA_BUF<<1;
SCK_0;
}
}
//===========================初始化nRF905=======================================
void nRF905_IO_set(void)
{
P2DIR |= 0x07; P2DIR &= 0xC7; P2SEL&=0x84;
P1DIR |= 0xC0; P1DIR |= 0xFB; P1SEL&=0xE0;
CD_0;
AM_1;
DR_1;
CSN_1; // Spi disable
SCK_0; // Spi clock line init low
PWR_1; // nRF905 power on
TRX_CE_0; // Set nRF905 in standby mode
TXEN_0; // set radio in Rx mode
}
//==================================初始化NRF905================================
void Config905(void)
{
uchar i;
CSN_0; // Spi enable for write a spi command
for (i=0;i<11;i++) // Write configration words 寫放配置字
{
SpiWrite(RFConf[i]);
}
CSN_1; //關閉SPI
}
//=========================NRF905裝載地址+數據打包+數據發送=====================
void TxPacket(char *data_Bufer)
{
uchar i;
CSN_0;
SpiWrite(WTP); // 待發數據裝載命令
for (i=0;i<10;i++)
{
SpiWrite(data_Bufer[i]);
}
CSN_1; // 關閉SPI
Delay(1);
CSN_0; // 打開SPI
SpiWrite(WTA); // 寫入地址要和接收方地址一樣
for (i=0;i<4;i++) // 4字節地址
{
SpiWrite(TxAddress[i]);
}
CSN_1; //關閉SPI
TRX_CE_1; // Set TRX_CE high,start Tx data transmission
Delay(500); // while (DR!=1); 延時時間不能太短
TRX_CE_0; // Set TRX_CE low
}
//==================================發送模式初始化-=============================
void SetTxMode(void)
{
TRX_CE_0;
TXEN_1;
Delay(1); // Delay for mode change(>=650us)
}
//=========DR檢測,當 收到數據后DR置1,當把數據讀出來后DR清0=====================
unsigned char CheckDR(void) //檢查是否有新數據傳入 Data Ready
{
if ((P2IN&0x10))
{
return 1;
}
else
{
return 0;
}
}
//==============================================================================
void SetRxMode(void)
{
TXEN_0;
TRX_CE_1;
Delay(1); // delay for mode change(>=650us)
}
//=================================數據接收=====================================
void RxPacket(void)
{
char i;
Delay(1);
Delay(100);
TRX_CE_0;
CSN_0; // SPI使能(Spi enable for write a spi command)
Delay(1);
SpiWrite(RRP); // 讀SPI數據命令(Read payload command)
for (i = 0 ;i <4 ;i++)
{
RxBuf[i]=SpiRead(); // Read data and save to buffer
}
CSN_1;
Delay(100);
TRX_CE_1;
}
//==========================NRF905數據接收流程================================
void RX(void)
{
SetRxMode(); // Set nRF905 in Rx mode
// while (CheckDR()==0);
Delay(10);
RxPacket(); // Recive data by nRF905
Delay(100);
//=============================================================================
if(RxBuf[0]==0x29)
{
P1OUT^=BIT0;
}
RxBuf[0]=0x00;
}
//==================================主函數=====================================
void main(void)
{
char tf;
WDTCTL = WDTPW + WDTHOLD;
InitSys();
nRF905_IO_set();
Delay(100);
LED_IO_set();
KEY_IO_set(); //KEY端口設置
Config905();
while(1)
{
RX();//接收數據
//==================================================
if((P1IN&0x08)) //檢測按鍵
{
TxBuf[0]=0x29;tf = 1 ; LED1_1;
}
if(tf==1) //有按鍵后發送數據
{
SetTxMode(); TxPacket(TxBuf);
tf = 0;
TxBuf[0]=0x00;
}
}
}
|