|
楼主 |
发表于 2010-5-27 16:17:46
|
显示全部楼层
/***以下为接收***/
#include <REGX52.H>
#include <INTRINS.H> //for funtion _NOP_
#include <STDIO.H>
/***自定义数据类型声明***/
typedef unsigned char uchar;
typedef unsigned int uint;
/***宏定义***/
#define TRANSMIT_LED 1
#define RECEIVE_LED 0
#define LEDDATA P0
#define SCAN_CYCLE 500 //数码管动态扫描间隔
#define TIMER1 0xe6 //256-(110592/(12*32*96))
#define TIMER0H (65535-SCAN_CYCLE)/256
#define TIMER0L (65535-SCAN_CYCLE)%256 //定时3MSVR3*FOSC/12/1000
/***I/O口定义***/
sbit MISO =P1^6;
sbit MOSI =P1^5;
sbit SCK =P1^7;
sbit CE =P1^3;
sbit CSN =P1^4;
sbit IRQ =P3^2;
sbit LED0 =P2^0;
sbit LED1 =P2^1;
/***显示及接收数据数组***/
code uchar TxBuf[32]=
{
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
code uchar RxBuf[32]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar CheckBuf[32]=
{
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
uchar dis_buf[2]={0x00,0x00}; //显示数组
code uchar LED7Code[]={
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // B
0xC6, // C
0xA1, // D
0x86, // E
0x8E, // F
0xFF, //熄灭
};
/***NRF24L01***/
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH 32 // 32 uints TX payload
#define RX_PLOAD_WIDTH 32 // 32 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
/***NRF24L01寄存器指令***/
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
/***SPI(nRF24L01)寄存器地址***/
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置 11 0x03 5bytes
#define SETUP_RETR 0x04 // 自动重发功能设置
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define CD 0x09 // 地址检测
#define RX_ADDR_P0 0x0A // 频道0接收数据地址
#define RX_ADDR_P1 0x0B // 频道1接收数据地址
#define RX_ADDR_P2 0x0C // 频道2接收数据地址
#define RX_ADDR_P3 0x0D // 频道3接收数据地址
#define RX_ADDR_P4 0x0E // 频道4接收数据地址
#define RX_ADDR_P5 0x0F // 频道5接收数据地址
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 接收频道0接收数据长度
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
/***NRF24L01状态标志***/
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
uchar flag;
/***函数声明***/
void Delayms(uint s);
void Delayus(uchar n);
void InitTimer(void);
void InitUART(void);
void InitNRF24L01(void);
void SetRXMode(void);
uchar SPI_RW(uchar); //NRF24L01的SPI写时序;写一个字节到24l01,同时读出一个字节
uchar SPI_Read(uchar reg); //NRF24L01的SPI读时序
uchar SPI_Read_Reg(uchar reg);//从寄存器reg读一个字节
uchar SPI_RW_Reg(uchar reg, uchar value);//向寄存器reg写一个字节,同时返回状态字节
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes); //从寄存器reg读出bytes个字节,通常用来读取接收通道数据或发送地址
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);//把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
uchar nRF24L01_RxPacket(uchar *rx_buf); //接收函数,返回1收到,
void nRF24L01_TxPacket(uchar *tx_buf); //发送函数
/**********************************************************************
函数:void Delay(uint s)
描述:
**********************************************************************/
void Delayms(uint s)
{
unsigned int i,j;
for(i=0; i<s; i++);
for(j=0; j<12; j++);
}
/**********************************************************************
函数:void Delayus(uchar n)
描述:短延时函数,延时9n+4 us
**********************************************************************/
void Delayus(uchar n)
{
for(;n>0;n--)
_nop_();
}
/*****************************************************************************************
函数:void InitTimer(void)
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1
TH0 = TIMER0H; //设定T0每隔SCAN_CYCLE us中断一次
TL0 = TIMER0L;
IE=0x82; //|EA|-|ET2|ES|ET1|EX1|ET0|EX0|
//ET0 = 1; //定时器0中断允许
//EA = 1; //开全局中断
TF0 = 0; //中断标志重置
TR0 = 1; //启动定时器0
}
/*****************************************************************************************
函数:void InitUART(void)
描述:串口初始化程序
*****************************************************************************************/
void InitUART(void) //波特率9600
{
SCON = 0x50; //串口方式1,允许接收
// TI=1;
TH1 = TIMER1;
TL1 = TIMER1;
PCON = 0x00;
TR1 = 1; //启动定时器1
}
/****************************************************************************************
函数:void InitNRF24L01(void)
描述:NRF24L01初始化
****************************************************************************************/
void InitNRF24L01(void)
{
Delayus(100);
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
}
/**************************************************
函数:SetRXMode()
描述:设置nRF24L01为接收模式,等待接收发送设备的数据包
**************************************************/
void SetRXMode(void)
{
CE = 0; //Standby-1
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 接收设备接收通道0使用和发送设备相同的发送地址
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + RF_CH, 0x00); // 选择射频通道0x00
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式
CE = 1; // 拉高CE启动接收设备
Delayus(130); // Standby-1 to RXMode need 130us
}
/******************************************************************************************************
函数:uchar nRF24L01_RxPacket(uchar *rx_buf)
描述:数据读取后放入rx_buf接收缓冲区中
******************************************************************************************************/
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
uchar revale=0;
sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //Stand by
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清除中断标志
return revale;
}
/****************************************************************************************************
函数:uint SPI_RW(uint uchar)
描述:NRF24L01的SPI写时序
/****************************************************************************************************/
uchar SPI_RW(uchar uch)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (uch & 0x80); // output 'uchar', MSB to MOSI
uch = (uch << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uch |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(uch); // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI读时序
/****************************************************************************************************/
uchar SPI_Read_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
/****************************************************************************************************
函数:uint SPI_RW_Reg(uchar reg, uchar value)
描述:NRF24L01读写寄存器函数
****************************************************************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************
函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,bytes:读出数据的个数
****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uint status,uchar_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar
for(uchar_ctr=0;uchar_ctr<bytes;uchar_ctr++)
pBuf[uchar_ctr] = SPI_RW(0); //
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*****************************************************************************************************
函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,bytes:写入数据的个数
*****************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<bytes; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status); //
}
/************************************************************************
函数:void ScanSeg7()
描述:数码管扫描显示
************************************************************************/
void ScanSeg7() //数码管扫描显示,一次扫描一位数码管
{
static uchar scanCounter=0;
LED1=1;
LED0=1;
if(scanCounter==RECEIVE_LED)
{
LEDDATA=dis_buf[RECEIVE_LED];
LED0=0;
scanCounter=TRANSMIT_LED;
}
else //scanCounter=TRANSMIT_LED
{
LEDDATA=dis_buf[TRANSMIT_LED];
LED1=0;
scanCounter=RECEIVE_LED;
}
}
/************************************************************************
函数:void Timer0_OverFlow() interrupt 1
描述:Timer0溢出中断,用于数码管动态扫描定时
************************************************************************/
void Timer0_OverFlow() interrupt 1 //500us中断一次
{
ScanSeg7(); //扫描数码管
TH0=(65536-SCAN_CYCLE)/256; //设定Timer0每隔SCAN_CYCLE us中断一次
TL0=(65536-SCAN_CYCLE)%256;
TF0=0; //定时器0中断标志位清零
}
/*****************************************************
函数:bit ErrorCheck(void)
描述:错误校验程序,检查收到的数据包是否正确
*****************************************************/
uchar ErrorCheck(void)
{
uchar i;
for(i=0;i<32;i++)
{
if(RxBuf!=TxBuf)
return 1;
}
return 0;
}
/************************************************************************
函数:void R_S_Byte(uchar R_Byte)
描述:通过串口将接收到数据发送给PC端
************************************************************************/
void R_S_Byte(uchar R_Byte)
{
SBUF = R_Byte;
while( TI == 0 ); //查询法
TI = 0;
}
/************************************************************************
函数:void main(void)
描述:主函数
************************************************************************/
void main(void)
{
int i;
uchar rabuf[5]={0};
uchar tabuf[5]={0};
InitTimer(); //Timer初始化
InitUART(); //串口初始化
InitNRF24L01(); //24l01初始化
LED0=1;
LED1=1;
//dis_buf[0]=LED7Code[13];
//dis_buf[1]=LED7Code[13];
//while(1);
SetRXMode(); //进入接收模式
/* TI=1;
printf("CONFIG=0x%x\n",(int)SPI_Read_Reg(CONFIG));
printf("EN_AA=0x%x\n",(int)SPI_Read_Reg(EN_AA));
printf("EN_RXADDR=0x%x\n",(int)SPI_Read_Reg(EN_RXADDR));
printf("SETUP_AW=0x%x\n",(int)SPI_Read_Reg(SETUP_AW));
printf("SETUP_RETR=0x%x\n",(int)SPI_Read_Reg(SETUP_RETR));
printf("RF_CH=0x%x\n",(int)SPI_Read_Reg(RF_CH));
printf("RF_SETUP=0x%x\n",(int)SPI_Read_Reg(RF_SETUP));
printf("STATUS=0x%x\n",(int)SPI_Read_Reg(STATUS));
printf("OBSERVE_TX=0x%x\n",(int)SPI_Read_Reg(OBSERVE_TX));
printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
SPI_Read_Buf(TX_ADDR,tabuf,5);
for(i=0;i<5;i++)
printf("tabuf[%d]=0x%x\n",i,(int)tabuf);
SPI_Read_Buf(RX_ADDR_P0,rabuf,5);
for(i=0;i<5;i++)
printf("rabuf[%d]=0x%x\n",i,(int)rabuf);
SPI_RW(FLUSH_RX);
SPI_RW(FLUSH_TX);
Delayus(2);
*/
do
{
//if(RX_DR)
//printf("%s\n","rs");
nRF24L01_RxPacket(RxBuf);
//SPI_Read_Buf(RD_RX_PLOAD,RxBuf,TX_PLOAD_WIDTH);
// if(nRF24L01_RxPacket(RxBuf))
// printf("DataReceived\n");
// printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
for(i=0;i<32;i++)
printf("RxBuf[%d]=0x%x\n",i,(int)RxBuf);
if(ErrorCheck())
{
dis_buf[0]=LED7Code[15];
dis_buf[1]=LED7Code[15];
}
else
{
dis_buf[0]=LED7Code[10];
dis_buf[1]=LED7Code[10];
}
}
while(IRQ == 0);
//dis_buf[0]=LED7Code[14];
//dis_buf[1]=LED7Code[14];
// while(IRQ==0) //发送完毕,
// R_S_Byte(&RxBuf[0]);
// while(1)
// printf("CD=0x%x",(int)SPI_Read_Reg(CD));
}
/* if(nRF24L01_RxPacket(RxBuf))
{
for(i=0;i<32;i++)
{
R_S_Byte(RxBuf);
Delayms(600);
}
}
*/
/*
while(1)
{
sta = SPI_Read(STATUS); // 读状态寄存器
if(RX_DR) // 判断是否接受到数据
{
SPI_Read_Buf(RD_RX_PLOAD, RxBuf, TX_PLOAD_WIDTH); // 从RX FIFO读出数据
flag = 1;
}
SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除RX_DS中断标志
if(flag) // 接受完成
{
flag = 0; // 清标志
LED = RxBuf[0]; // 数据送到LED显示
Delayms(250);
Delayms(250);
LED = 0xff; // 关闭LED
}
}
*/
/* if(nRF24L01_RxPacket(RxBuf))
{
temp++;
for(i=0;i<32;i++)
{
R_S_Byte(RxBuf);
Delay(600);
}
}
*/ |
|