|
#include <STC15W204S.h>
#include <Intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit MISO=P3^3; //主收从发
sbit MOSI=P3^6; //主发从收
sbit SCK=P3^7; //串行时钟信号
sbit CE=P1^1; //芯片使能
sbit CSN=P1^0; //片选信号
sbit IRQ=P3^2; //中断查询
sbit ss=P1^2;
sbit xx=P1^3;
sbit cc=P1^4;
//sbit a=P1^4;
//sbit b=P1^5;
/*************************************************************/
//uchar seg[10]={~0x3f,~0x06,~0x5b,~0x4f,~0x66};
bit TxBufEndFlg = 1; //数据发送完成标志
uchar checkack();
uchar TxBuf[20]={0};
uchar RxBuf[20]={0};
uchar SPI_RW(uchar uchars);
uchar SPI_Read(uchar reg);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar KeyScanPrg();
uchar KeyState;
/************************************************************/
#define TX_ADR_WIDTH 5 //发送地址长度为5个字节
#define RX_ADR_WIDTH 5 //接收地址长度为5个字节
#define TX_PLOAD_WIDTH 20 //发送数据长度为20个字节
#define RX_PLOAD_WIDTH 20 //接收数据长度为20个字节
uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar code RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//SPI命令
#define READ_REG 0x00 //读第0个寄存器
#define WRITE_REG 0x20 //写第0个寄存器
#define RD_RX_PLOAD 0x61 //在接收模式下使用,读有效数据
#define WR_TX_PLOAD 0xA0 //在发送模式下使用,写有效数据
#define FLUSH_TX 0xE1 //在发送模式下使用,清TX FIFO寄存器
#define FLUSH_RX 0xE2 //在接收模式下使用,清RX FIFO寄存器
#define REUSE_TX_PL 0xE3 //发送方使用,重复发送最后的数据
#define NOP 0xFF //空操作,用于读状态寄存器STATUS的值
//NRF24L01寄存器地址
#define CONFIG 0x00 //配置寄存器,8bit
#define EN_AA 0x01 //自动应答设置寄存器,8bit
#define EN_RXADDR 0x02 //接收地址设置寄存器,8bit
#define SETUP_AW 0x03 //地址宽度设置寄存器,8bit
#define SETUP_RETR 0x04 //自动重复发送设置寄存器,8bit
#define RF_CH 0x05 // RF通道寄存器,8bit(工作频率设置)
#define RF_SETUP 0x06 //RF设置寄存器,8bit(发射速率、功耗功能设置)
#define STATUS 0x07 //状态寄存器,8bit
#define OBSERVE_TX 0x08 //发送检测寄存器,8bit
#define CD 0x09 //载波检测寄存器,8bit
#define RX_ADDR_P0 0x0A //接收地址数据通道0,40bit
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10 //发送地址,发送方使用,40bit
#define RX_PW_P0 0x11 //通道0接收的有效数据字节长度(1-32字节),8bit
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17 //FIFO栈入栈出状态寄存器,8bit
//*********************************************************************************
void Delay(uint s);
void delayms(uchar z);
void inerDelay_us(uchar n);
void init_NRF24L01();
void nRF24L01_TxPacket(uchar * tx_buf);
void KeyDealPrg(uchar KeyState);
//**********************************************************************************
void inerDelay_us(uchar n)
{
for(;n>0;n--)
_nop_();
}
//************************************************************************************
uchar bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
//***************************checkack函数********************************************
uchar checkack()
{
sta=SPI_Read(STATUS); // 返回状态寄存器
if(TX_DS || MAX_RT) // 发送完毕中断
{
if(MAX_RT)
init_NRF24L01();
TxBufEndFlg = 1; //接收完成
SPI_RW_Reg(WRITE_REG+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志
CSN=0;
SPI_RW(FLUSH_TX); //在接收模式下,清空RX FIFO寄存器。在传输应答信号时不应执行此操作,否则不能传输完整的应答信号
CSN=1;
return(1);
}
else
return(0);
}
//***************************NRF24L01初始化********************************************
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; //芯片启动
CSN=1; //终止SPI读写
SCK=0; //低电平为空闲时刻
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); //写接收端地址
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x4a); //自动延时1250us,自动重发10次
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //ENAA_P0=1,数据通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // EN_RXADDR=1,接收地址允许
SPI_RW_Reg(WRITE_REG + RF_CH, 00); //设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为20字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x06); //设置发射速率为250kbps,发射功率为0dBm,低噪声放大器增益
}
//***************************************SPI操作***********************************************
uchar SPI_RW(uchar uchars)//写一个字节到NRF24L01,并返回此时NRF24L01的状态及数据
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) //先写字节的高位,再写低位
{
MOSI = (uchars & 0x80); //MOSI取uhcars最高位
uchars = (uchars << 1); //uchars左移一位
SCK = 1; //SCK从高到低时开始写入
uchars |= MISO; // 获取MISO位,从MOSI写命令的同时,MISO返回NRF24L01的状态及数据
SCK = 0;
}
return(uchars);
}
uchar SPI_Read(uchar reg)//读寄存器reg状态字
{
uchar reg_val;
CSN = 0; //CSN为0时,才能进行SPI读写
SPI_RW(reg); //选择寄存器reg
reg_val = SPI_RW(0); //写0,什么操作也不进行,仅仅为了读寄存器状态
CSN = 1; //终止SPI读写
return(reg_val);
}
uchar SPI_RW_Reg(uchar reg, uchar value)//将字节value写入寄存器reg
{
uchar status;
CSN = 0; //CSN为0时,才能进行SPI读写
status = SPI_RW(reg); //选择寄存器reg
SPI_RW(value); //写字节value到该寄存器.
CSN = 1; //终止SPI读写
return(status);
}
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//将数据写入寄存器,如TX数据,RX/TX地址等
{
uchar status,uchar_ctr;
CSN = 0; // CSN为0时,才能进行SPI读写
status = SPI_RW(reg); //选择寄存器reg并返回其状态字
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)
SPI_RW(*pBuf++); //写数据到寄存器
CSN = 1; //终止SPI读写
return(status); //返回状态值
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
if(TxBufEndFlg)
{
CE=0; //待机模式I
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); //装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); //CRC使能,CRC校验值为2字节,上电,设置为发射模式
CE=1; //置高CE,激发数据发送
TxBufEndFlg = 0; //标志位清0
inerDelay_us(1000);
}
}
/*****************************************************************************/
/*函数:
/*功能:按键采集扫描
/*****************************************************************************/
uchar KeyScanPrg(void)
{
uchar KeyStateRAM=0x00;
KeyState=0x00;
KeyStateRAM|=ss;
KeyStateRAM<<=1;
KeyStateRAM|=xx;
KeyStateRAM<<=1;
KeyStateRAM|=cc;
KeyState=KeyStateRAM;
return(KeyState);
}
/*****************************************************************************/
/*函数:
/*功能:按键处理
/*****************************************************************************/
void KeyDealPrg(uchar KeyStat)
{
switch(KeyStat)
{ // ss xx cc
case 0x03:TxBuf[1]=0;TxBuf[2]=1;TxBuf[3]=0;TxBuf[4]=0;break;
case 0x05:TxBuf[1]=0;TxBuf[2]=0;TxBuf[3]=1;TxBuf[4]=0;break;
case 0x06:TxBuf[1]=0;TxBuf[2]=0;TxBuf[3]=0;TxBuf[4]=1;break;
case 0x02:TxBuf[1]=0;TxBuf[2]=1;TxBuf[3]=0;TxBuf[4]=1;break;
case 0x04:TxBuf[1]=0;TxBuf[2]=0;TxBuf[3]=1;TxBuf[4]=1;break;
case 0x01:TxBuf[1]=0;TxBuf[2]=1;TxBuf[3]=1;TxBuf[4]=0;break;
case 0x00:TxBuf[1]=0;TxBuf[2]=1;TxBuf[3]=1;TxBuf[4]=1;break;
case 0x07:TxBuf[1]=1;TxBuf[2]=0;TxBuf[3]=0;TxBuf[4]=0;break;
}
nRF24L01_TxPacket(TxBuf);
checkack();
}
/*****************************************************************************/
/*函数:
/*功能:主函数
/*****************************************************************************/
void main(void)
{ ss=1;xx=1;cc=1;
init_NRF24L01();
while(1)
{
KeyDealPrg(KeyScanPrg());
}
}
|
评分
-
查看全部评分
|