#include <c8051f310.h>
#include <stdio.h>
#include <math.h>
#include <Intrins.h>
#include <absacc.h>
#define uint unsigned int
#define uchar unsigned char
#define BUSY SPI0CFG&0x80//SPI接口檢測
code uchar PaTabel[]={0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60};//配置功率
uchar send_buf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
//要發送的有效數據,其中第一個為數據的長度
uchar rx_buf[8]={0}; //接收的數據緩存
//引腳定義*********************************************************************************
#define CSN_HIGH CSN=1
#define CSN_LOW CSN=0
sbit GDO0 =P0^6;
sbit CSN =P0^3;
sbit MISO =P0^1; //為了檢測是否穩定
sbit c=P0^7;
//*****************************************************************************************
#define WRITE_BURST 0x40 //連續寫入多個字節,即為突發訪問
#define READ_SINGLE 0x80 //讀一個字節
#define READ_BURST 0xC0 //連續讀多個字節
#define BYTES_IN_RXFIFO 0x7F //接收緩沖區的有效字節數
#define CRC_OK 0x80 //CRC校驗通過位標志
//*****************************************************************************************
//RF1100SE寄存器地址
#define IOCFG2 0x00
#define IOCFG1 0x01
#define IOCFG0 0x02
#define FIFOTHR 0x03
#define SYNC1 0x04
#define SYNC0 0x05
#define PKTLEN 0x06
#define PKTCTRL1 0x07
#define PKTCTRL0 0x08
#define ADDR 0x09
#define CHANNR 0x0a
#define FSCTRL1 0x0b
#define FSCTRL0 0x0c
#define FREQ2 0x0d
#define FREQ1 0x0e
#define FREQ0 0x0f
//配置寄存器
#define MDMCFG4 0x10
#define MDMCFG3 0x11
#define MDMCFG2 0x12
#define MDMCFG1 0x13
#define MDMCFG0 0x14
#define DEVIATN 0x15
#define MCSM2 0x16
#define MCSM1 0x17
#define MCSM0 0x18
#define FOCCFG 0x19
#define BSCFG 0x1a
#define AGCTRL2 0x1b
#define AGCTRL1 0x1c
#define AGCTRL0 0x1d
#define WOREVT1 0x1e
#define WOREVT0 0x1f
#define WORCTRL 0x20
#define FREND1 0x21
#define FREND0 0x22
#define FSCAL3 0x23
#define FSCAL2 0x24
#define FSCAL1 0x25
#define FSCAL0 0x26
#define RCCTRL1 0x27
#define RCCTRL0 0x28
#define FSTEST 0x29
#define PTEST 0x2a
#define AGCTEST 0x2b
#define TEST2 0x2c
#define TEST1 0x2d
#define TEST0 0x2e
//狀態寄存器
#define PARTNUM 0x30
#define VERSION 0x31
#define FREQEST 0x32
#define LQI 0x33
#define RSSI 0x34
#define MARCSTATE 0x35
#define WORTIME1 0x36
#define WORTIME0 0x37
#define PKTSTATUS 0x38
#define VCOVCDAC 0x39
#define TXBYTES 0x3a
#define RXBYTES 0x3b
#define PATABLE 0x3e
#define TX_FIFO 0x3f
#define RX_FIFO 0x3f
//控制命令寄存器
#define SRES 0x30//重啟芯片
#define SFSTXON 0x31//開啟和校準頻率合成器
#define SXOFF 0x32//關閉晶體振蕩器
#define SCAL 0x33//校準頻率合成器并關斷
#define SRX 0x34//啟用RX
#define STX 0x35//空閑狀態時啟用TX
#define SIDLE 0x36//離開RX/TX關斷頻率合成器并離開電磁波激活模式
#define SAFC 0x37//運行頻率合成器的AFC調節
#define SWOR 0x38//運行自動RX選舉序列
#define SPWD 0x39//當CSn為高時進入功率降低模式
#define SFRX 0x3a//沖洗RX_FIFO緩沖
#define SFTX 0x3b//沖洗TX_FIFO緩沖
#define SWORRST 0x3c//重新設置真實時間時鐘
#define SNOP 0x3d//附加:軟件擴充為兩個字節
//函數聲明*********************************************************************************
void sysclk(void);
void pio(void);
void SPI(void);
void Interrupt_int(void);
void delay(uint i);
void dat_int(void);
//*****************************************************************************************
uchar SPI_RW(uchar byte); //用SPI讀寫一字節的數據
void SPI_WR_Strobe(uchar strobe); //寫入濾波命令
void POWER_UP_RESET_CC1100(void); //上電復位
uchar SPI_RW_Reg(uchar reg,uchar value); //向寄存器寫一字節的數據,同時返回狀態字
uchar SPI_Read_Reg(uchar reg); //從寄存器讀一字節的數據
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes); //從reg連續讀出bytes字節的數據
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes); //向reg連續寫入bytes字節的數據
uchar RF1100CE_RxPacket(uchar *rx_buf,uchar *length); //接收函數
void RF1100CE_TxPacket(uchar *tx_buf,uchar size); //發送函數
void RF1100CE_Config(void); //RF1100CE的配置函數
//*****************************************************************************************
void main(void) //主程序
{uchar sta=0;
PCA0MD &= ~0x40;// 關閉看門狗
pio();
sysclk();
dat_int();
SPI(); //SPI0DAT是SPI的數據寄存器
Interrupt_int();
EA=0;
POWER_UP_RESET_CC1100();
RF1100CE_Config(); //RF1100CE的配置函數
SPI_RW_Buf(PATABLE,PaTabel,8); //對設備進行功率配置
delay(6000);
while(1)
{
RF1100CE_TxPacket(send_buf,8); //發送函數
c=1;
delay(100);
if(sta&0xff)
{
CSN_LOW;
SPI_RW(SFTX); //清除發送寄存器的值
CSN_HIGH;
}
}
}
void dat_int(void)
{
CSN_LOW;
_nop_();
CSN_HIGH;
c=0;
}
void sysclk(void) //內部晶振
{
OSCICL=0xb3; // 0xb3
OSCICN=0xc2; //二分頻
CLKSEL=0x00;
}
//延時子函數10us
void delay(uint i)
{
while(i--);
}
uchar SPI_RW(uchar byte) //用SPI讀寫一字節的數據
{
uchar rbyte;
SPI0DAT=byte;
while(!SPIF);
rbyte=SPI0DAT;
SPIF=0;
return rbyte;
}
void SPI_WR_Strobe(uchar strobe) //寫入濾波命令
{
CSN_LOW;
while (MISO);
SPI_RW(strobe);
while(MISO);
CSN_HIGH;
}
void POWER_UP_RESET_CC1100(void) //上電復位
{
CSN = 1;
delay(10);
CSN = 0;
delay(10);
CSN = 1;
delay(500);
SPI_WR_Strobe(SRES); //復位CC1100
}
uchar SPI_RW_Reg(uchar reg,uchar value) //向寄存器寫一字節的數據,同時返回狀態字
{
uchar status;
CSN_LOW;
while(MISO);
SPI0DAT=reg;
while(!SPIF);
status=SPI0DAT;
SPIF=0;
SPI0DAT=value;
while(!SPIF);
SPIF=0;
CSN_HIGH;
return(status);
}
uchar SPI_Read_Reg(uchar reg) //從寄存器讀出一字節的數據
{
uchar byte;
CSN_LOW;
while (MISO);
SPI0DAT=reg|READ_SINGLE ;
while(!SPIF);
SPIF=0;
SPI0DAT=0x00;
while(!SPIF);
byte=SPI0DAT;
SPIF=0;
CSN_HIGH;
return byte;
}
uchar SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes) //從reg讀出bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
while (MISO);
status=SPI_RW(reg|READ_BURST);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr]=SPI_RW(0);
CSN_HIGH;
return status;
}
uchar SPI_RW_Buf(uchar reg,uchar *pBuf,uchar bytes) //向reg寫入bytes字節的數據
{
uchar status,byte_ctr;
CSN_LOW;
while (MISO);
status=SPI_RW(reg|WRITE_BURST);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
SPI_RW(pBuf[byte_ctr]);
CSN_HIGH;
return status;
}
//接收函數,接收返回1表示有數據收到
uchar RF1100CE_RxPacket(uchar *rx_buf,uchar *length)
{
uchar status[2];
uchar packetLength;
uchar i=(*length)*4; // 具體多少要根據datarate和length來決定
SPI_WR_Strobe(SRX); //進入接收模式指令
delay(10);
while (GDO0)
{
delay(10);
--i;
if(i<1)
return 0;
}
if(SPI_Read_Reg(RXBYTES+READ_BURST) & BYTES_IN_RXFIFO) //如果接的字節數不為0
{
packetLength = SPI_Read_Reg(RX_FIFO);//讀出第一個字節,此字節為該幀數據長度
if (packetLength <= *length) //如果所要的有效數據長度小于等于接收到的數據包的長度
{
SPI_Read_Buf(RX_FIFO, rx_buf, packetLength); //讀出所有接收到的數據
*length = packetLength; //把接收數據長度的修改為當前數據的長度
SPI_Read_Buf(RX_FIFO, status, 2); //讀出CRC校驗位
SPI_WR_Strobe(SFRX); //清洗接收緩沖區
return (status[1] & CRC_OK); //如果校驗成功返回接收成功
}
else
{
*length = packetLength;
SPI_WR_Strobe(SFRX); //清洗接收緩沖區
return 0;
}
}
else
return 0;
}
//發送函數
void RF1100CE_TxPacket(uchar *tx_buf,uchar size)
{
SPI_RW_Reg(TX_FIFO, size);
SPI_RW_Buf(TX_FIFO, tx_buf, size); //寫入要發送的數據
SPI_WR_Strobe(STX); //進入發送模式發送數據
while (!GDO0);
while (GDO0);
SPI_WR_Strobe(SFTX); //清除發送緩沖寄存器
SPI_WR_Strobe(SIDLE);//進入休眠模式
}
void RF1100CE_Config(void) //RF1100CE的配置函數
{
CSN_HIGH;//SPI復位
SPI_RW_Reg(FSCTRL1, 0x08);//頻率合成器控制
SPI_RW_Reg(FSCTRL0, 0x00);
SPI_RW_Reg(FREQ2, 0x10);//頻率控制詞匯
SPI_RW_Reg(FREQ1, 0xa7);
SPI_RW_Reg(FREQ0, 0x62);
SPI_RW_Reg(MDMCFG4, 0x5b);//調制器配置
SPI_RW_Reg(MDMCFG3, 0xf8);
SPI_RW_Reg(MDMCFG2, 0x03);
SPI_RW_Reg(MDMCFG1, 0x22);
SPI_RW_Reg(MDMCFG0, 0xf8);
SPI_RW_Reg(CHANNR, 0x00);//信道數
SPI_RW_Reg(DEVIATN, 0x47);
SPI_RW_Reg(FREND1, 0xb6);
SPI_RW_Reg(FREND0, 0x10);
SPI_RW_Reg(MCSM0, 0x18);
SPI_RW_Reg(FOCCFG, 0x1d);
SPI_RW_Reg(BSCFG, 0x1c);
SPI_RW_Reg(AGCTRL2, 0xc7);
SPI_RW_Reg(AGCTRL1, 0x00);
SPI_RW_Reg(AGCTRL0, 0xb2);
SPI_RW_Reg(FSCAL3, 0xea);//頻率合成器校準
SPI_RW_Reg(FSCAL2, 0x2a);
SPI_RW_Reg(FSCAL1, 0x00);
SPI_RW_Reg(FSCAL0, 0x11);
SPI_RW_Reg(FSTEST, 0x59);//產品測試
SPI_RW_Reg(TEST2, 0x81);//不同的測試設置
SPI_RW_Reg(TEST1, 0x35);
SPI_RW_Reg(TEST0, 0x09);
SPI_RW_Reg(IOCFG2, 0x0b);
SPI_RW_Reg(IOCFG0, 0x06);//GDO輸出腳配置
SPI_RW_Reg(PKTCTRL1, 0x04);//數據包自動控制,無地址檢測,包含兩個狀態字節
SPI_RW_Reg(PKTCTRL0, 0x05);//開啟CC2400支持,采用可變長度數據包
SPI_RW_Reg(ADDR, 0x00);//設置地址
SPI_RW_Reg(PKTLEN, 0x10);//有效允許最大數據包長度16個字節
SPI_WR_Strobe(SFRX);
SPI_WR_Strobe(SFTX);
SPI_WR_Strobe(SIDLE);
}
void SPI(void) //SPI初始化
{
SPI0CFG=0x40; //時鐘極性為低,即剛開始時鐘要為低電平
SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三線主方式
SPI0CKR=0x2f; //SPI 時鐘頻率設置為150kHz 0x6f 0x2f
}
void Interrupt_int(void) //中斷設定
{
IE=0x40; //允許SPI中斷請求
IP=0x00; //SPI為低優先級
}
void pio(void) // 端口配置
{
P0MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P0MDOUT=0xff; //0為開漏,1為推挽(ff)
P0SKIP=0x00;
P1MDIN=0xff;
P1MDOUT=0xff; //低四位用于138
P2MDIN=0xff; //禁止模擬輸入,0為模擬,1為數字
P2MDOUT=0xff; //0為開漏,1為推挽(ff)
P3MDIN=0xff;
P3MDOUT=0xff; //低四位用于138
XBR0=0x02;
XBR1=0x40;
}
|