/******************************************/
//
// 该程序工作的主频是12MHz,单片机使用STC12C5A60S2
//
/******************************************/
#include "STC12C5A60S2.H"
#define uchar unsigned char
#define uint unsigned int
/********** NRF24L01寄存器操作命令 ***********/
#define READ_REG 0x00 //读配置寄存器,低5位为寄存器地址
#define WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节
#define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP 0xFF //空操作,可以用来读状态寄存器
/********** NRF24L01寄存器地址 *************/
#define CONFIG 0x00 //配置寄存器地址
#define EN_AA 0x01 //使能自动应答功能
#define EN_RXADDR 0x02 //接收地址允许
#define SETUP_AW 0x03 //设置地址宽度(所有数据通道)
#define SETUP_RETR 0x04 //建立自动重发
#define RF_CH 0x05 //RF通道
#define RF_SETUP 0x06 //RF寄存器
#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有效数据宽度(1~32字节)
#define RX_PW_P1 0x12 // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2 0x13 // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3 0x14 // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4 0x15 // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5 0x16 // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS 0x17 // FIFO状态寄存器
/*————————————————————————————————————————————————————————————————————*/
/****** STATUS寄存器bit位定义 *******/
#define MAX_TX 0x10 //达到最大发送次数中断
#define TX_OK 0x20 //TX发送完成中断
#define RX_OK 0x40 //接收到数据中断
/*——————————————————————————————————————————————————*/
/********* 24L01发送接收数据宽度定义 ***********/
#define TX_ADR_WIDTH 5 //5字节地址宽度
#define RX_ADR_WIDTH 5 //5字节地址宽度
#define TX_PLOAD_WIDTH 32 //32字节有效数据宽度
#define RX_PLOAD_WIDTH 32 //32字节有效数据宽度
const uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};
const uchar RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};
sbit NRF_CE = P1^2;
sbit NRF_CSN = P1^3;
sbit NRF_MISO = P1^6;
sbit NRF_MOSI = P1^5;
sbit NRF_SCK = P1^7;
sbit NRF_IRQ = P1^4;
sbit LED1=P1^0; //状态指示灯
sbit LED2=P1^1; //接收时的被控对象
unsigned char send_buf[TX_PLOAD_WIDTH]="qwertyuiopasdfghjklzxcvbnm123456"; //26+6
unsigned char recv_buf[RX_PLOAD_WIDTH];
/* 延时函数 */
/***************/
void delay_ms(unsigned char ms)
{
unsigned int i;
do {
i = 1701;
while(--i) ; //14T per loop
} while(--ms);
}
/**********************/
/* 初始化硬件SPI口 */
/**********************/
void SPI_Init(void)
{
NRF_CE=0;
NRF_CSN=1;
NRF_SCK=0;
NRF_IRQ=1;
//SPSTAT |= 0XC0;
//SPCTL = 0XD0;
}
/**********************/
/* SPI数据收发函数 */
/**********************/
//uchar SPI_RW(uchar tr_data)
//{
// uchar i=0;
//
// SPSTAT |= 0Xc0; // 清高两位,
// SPDAT=tr_data;
// while(((SPSTAT&0X80)!=0X80)&&(i<20))
// {
// i++;
// delay_ms(1);
// }
// return SPDAT;
//}
// 下面是“模拟SPI”
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 输出8位
{
NRF_MOSI=(byte&0x80); // MSB TO MOSI
byte=(byte<<1); // shift next bit to MSB
NRF_SCK=1;
byte|=NRF_MISO; // capture current MISO bit
NRF_SCK=0;
}
return byte;
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* value 给寄存器写的值 */
/* 出口参数:status 状态值 */
/*********************************************/
uchar NRF24L01_Write_Reg(uchar reg,uchar value)
{
uchar status;
NRF_CSN=0; //CSN=0;
status = SPI_RW(reg);//发送寄存器地址,并读取状态值
SPI_RW(value);
NRF_CSN=1; //CSN=1;
return status;
}
/*************************************************/
/* 函数功能:读24L01的寄存器值 (一个字节) */
/* 入口参数:reg 要读的寄存器地址 */
/* 出口参数:value 读出寄存器的值 */
/*************************************************/
uchar NRF24L01_Read_Reg(uchar reg)
{
uchar value;
NRF_CSN=0; //CSN=0;
SPI_RW(reg);//发送寄存器值(位置),并读取状态值
value = SPI_RW(NOP);
NRF_CSN=1; //CSN=1;
return value;
}
/*********************************************/
/* 函数功能:读24L01的寄存器值(多个字节) */
/* 入口参数:reg 寄存器地址 */
/* *pBuf 读出寄存器值的存放数组 */
/* len 数组字节长度 */
/* 出口参数:status 状态值 */
/*********************************************/
uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len)
{
uchar status,u8_ctr;
NRF_CSN=0; //CSN=0
status=SPI_RW(reg);//发送寄存器地址,并读取状态值
for(u8_ctr=0; u8_ctr NRF_CSN=1; //CSN=1 return status; //返回读到的状态值 } /**********************************************/ /* 函数功能:给24L01的寄存器写值(多个字节) */ /* 入口参数:reg 要写的寄存器地址 */ /* *pBuf 值的存放数组 */ /* len 数组字节长度 */ /**********************************************/ uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len) { uchar status,u8_ctr; NRF_CSN=0; status = SPI_RW(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0; u8_ctr NRF_CSN=1; return status; //返回读到的状态值 } /*********************************************/ /* 函数功能:24L01接收数据 */ /* 入口参数:rxbuf 接收数据数组 */ /* 返回值: 0 成功收到数据 */ /* 1 没有收到数据 */ /*********************************************/ uchar NRF24L01_RxPacket(uchar *rxbuf) { uchar state; state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志 if(state&RX_OK)//接收到数据 { NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//没收到任何数据 } /**********************************************/ /* 函数功能:设置24L01为发送模式 */ /* 入口参数:txbuf 发送数据数组 */ /* 返回值; 0x10 达到最大重发次数,发送失败*/ /* 0x20 成功发送完成 */ /* 0xff 发送失败 */ /**********************************************/ uchar NRF24L01_TxPacket(uchar *txbuf) { uchar state; // uchar i; NRF_CE=0;//CE拉低,使能24L01配置 NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节 NRF_CE=1;//CE置高,使能发送
设计资源 培训 开发板 精华推荐
- 有奖直播:TI 低功耗 MCU 产品和 Zigbee 无线解决方案
- Arrow&allegro有奖直播:下一代磁感应解决方案:XtremeSense™ TMR 技术如何促进高效应用
- 有奖直播:联咏安防监控方案及未来技术方向 报名开始啦!
- 注册有礼 | 施耐德电器邀请您参加EP23上海国际电力电工展线上云逛展
- 发帖赢好礼 | MPS 工程师为您解决DC-DC设计难题
- 泰克“无忧计划”买与租的自由转换!赏漫画、填问卷 参与活动好礼送!
- 安森美半导体——FOD83xx/T系列来袭! 答题赢好礼,更可免费申请样片
- 更好的你我,更好的EEWorld!2020年终庆典
- 《瑞萨电子低功耗MCU实战手册》来了,快去下载赢取好礼!