|
|
楼主 |
发表于 2017-5-29 00:20:25
|
显示全部楼层
下面两个是调试通过能正常运行的程序 硬件是基于
6通道接收机
//发射
#include <STC15W408AS.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned short
/********** 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 //重新使用上一包数据,P_24L01_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状态寄存器
/********* 24L01发送接收数据宽度定义 ***********/
#define ADR_WIDTH 5 //5字节地址宽度
#define DATA_WIDTH 32 //32字节有效数据宽度
#define NRF24L01_Tx_Mode 0x0e //发送模式
#define NRF24L01_Rx_Mode 0x0f //接收模式
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
/******NRF24L01引脚定义*******/
sbit NRF24L01_CSN =P1^2;
sbit NRF24L01_CE =P5^5;
sbit NRF24L01_SCK =P5^4;
sbit NRF24L01_MOSI=P1^3;
sbit NRF24L01_MISO=P1^5;
sbit NRF24L01_IRQ =P1^4;
/****PWM输出LED引脚定义******/
sbit PWM_OUTR=P1^0;
uchar PWM_Write_Byte_R=1;
uchar PWM_Write_Byte_G=1;
uchar PWM_Write_Byte_B=1;
uchar code TX_ADDRESS[5]= {0x34,0x43,0x10,0x10,0x01};
//收发地址设置
//uchar code RX_ADDRESS[5]={0x34,0x43,0x10,0x10,0x01};
//接或收都必须一致
uchar NRF24L01_Rx_Buffer[32]; //收到的数据最大32字节
uchar NRF24L01_Tx_Buffer[32]; //待发送的数据,32字节
uchar RGB_PWM=0,RGB_Mode=0;
//R_PWM决定亮度,RGB_Mode决定状态和颜色
/***SPI初始化函数****/
uchar NRF24L01_SPI(uchar byte)
{
uchar k;
for(k=0;k<8;k++)// 输出8位 //每字节操作8次
{
NRF24L01_MISO=1;//默认为1
NRF24L01_MOSI = (byte & 0x80); //发送最高位
byte = (byte << 1);//传过来的数据左移 //字节左移
NRF24L01_SCK = 1;//时钟拉高 //时钟上升沿
byte |= NRF24L01_MISO;//读出的值给字节的最低位 //读出的位赋值给字节最低位
NRF24L01_SCK = 0; //时钟拉低 //时钟下降沿
}
return(byte); //读出的值返回
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* value 给寄存器写的值 */
/*********************************************/
void NRF24L01_Write_Read_Reg(uchar reg,uchar value)
{
NRF24L01_CSN=0; // 拉低 //CSN=0;
NRF24L01_SPI(reg); //写寄存器地址 //写寄存器地址
NRF24L01_SPI(value);//给寄存器写命 //紧接着写入寄存器的命令码
NRF24L01_CSN=1;//写完后拉高 //CSN=1;
}
/*********************************************/
/* 函数功能:写24L01的寄存器值(多个字节) */
/* 入口参数:reg 寄存器地址命令 */
/* *pBuf 指向数组的地址 */
/* len 数组字节长度 */
/*********************************************/
void NRF24L01_Write_Buffer(uchar reg, uchar *pBuf, uchar len)
{
uchar k;
NRF24L01_CSN=0; //芯片的SPI功能选通
NRF24L01_SPI(reg);//写命令 //写寄存器地址
for(k=0; k<len; k++)// 输出8位
{
NRF24L01_SPI(*pBuf++);//把指针给SPI就OK //写入数据
}
NRF24L01_CSN=1; //写完后拉高 //芯片关闭SPI功能
}
/*NRF24L01初始化过程*********/
void NRF24L01_Init(uchar Mode)
{
/*1 CE=0进入待机模式*********/
NRF24L01_CE=0; //1,CE=0进入待机模式
NRF24L01_CSN=1;
NRF24L01_SCK=0;
NRF24L01_CE=0;
/*2配置发射地址,字节长度和地址码值要与接收方一致**/
NRF24L01_Write_Buffer(0x20+TX_ADDR, TX_ADDRESS, ADR_WIDTH); // 发送地址和收方地址一致
/*3配置接收应答地址,默认通道0做应答.字节长度码值与发射一致*********/
NRF24L01_Write_Buffer(0x20+RX_ADDR_P0, TX_ADDRESS, ADR_WIDTH);// 选通道0作自动应答接收,地址、发送地址和收方地址一致
/*4配置接收通道默认0的数据接收长度,或者写入数据到发射缓冲区*********/
NRF24L01_Write_Read_Reg(0x20+RX_PW_P0, DATA_WIDTH);// 接收数据通道0有效数据宽度
/*5发射端 选择通道0作为自动应答.接收端选择通道0接收数据包*********/
NRF24L01_Write_Read_Reg(0x20+EN_AA, 0x01);//使能通道0的自动应答
NRF24L01_Write_Read_Reg(0x20+EN_RXADDR, 0x01);//使能通道0的接收地址
/*6配置发射频率:总共126个频段,不同系统建议频段间隔大一点*********/
NRF24L01_Write_Read_Reg(0x20+RF_CH, 40);//用频段40
/*7设置无线波特率1M/2M/250K.设置天线增益:0db发射距离最远*********/
NRF24L01_Write_Read_Reg(0x20+RF_SETUP, 0x0f);// 0db增益 2Mbps
/*8设置自动重发延时和重发次数,重发超过次数,IRQ中断输出低电平***/
NRF24L01_Write_Read_Reg(0x20+SETUP_RETR, 0x12);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
/*9使能CRC校验,选择校验长度设置发送或者接受模式*********/
NRF24L01_Write_Read_Reg(0x20+CONFIG, Mode);
/*10,CE=1:进入发射空闲或者接收模式*********/
//NRF_CE =1;
}
/**********定时器初始化函数***********/
void Init(void) //52微秒
{
TMOD|=0x01;
TH0=0xff; //设置定时初值
TL0=0x98;
ET0=1;
TR0=1; //定时器0开始计时
EA=1;
PWM_OUTR=1; //PWM输出脚置0
NRF24L01_Init(NRF24L01_Tx_Mode);//Rx_Mode=0X0F设置为接收模式 //2.4G模块初始化 发射
}
void RGB()
{
uchar i;
switch(RGB_Mode)
{
case 0: //红色渐亮
{
RGB_PWM+=1;
if(RGB_PWM==255)
{
RGB_Mode+=1;
}
for(i=0;i<24;)
{
NRF24L01_Tx_Buffer[i+1]=RGB_PWM;
i+=1;
}
break;
}
default : RGB_Mode=0;break;
//如果上述条件都不成立,状态清0,退出。
}
}
void LED_PWM_Timer0() interrupt 1
{
static uchar pwm_t=0; //局部变量,不丢失数据
TH0=0xff;
TL0=0x98;
if(pwm_t<NRF24L01_Tx_Buffer[1])
{
PWM_OUTR=1;
}
else PWM_OUTR=0;
pwm_t++;
if(pwm_t>=255)
{
pwm_t=0;
}
}
void main()
{
uint k;
Init(); //定时器初始化 //初始化
while(1)
{
RGB();
k=3000;
while(k--);// 延时待系统稳定
NRF24L01_CE=0;//1,CE=0进入待机模式
NRF24L01_IRQ=1;//清除中断信号
/**写RX有效数据,1~32字节 设置地址宽度**/
NRF24L01_Write_Buffer(WR_TX_PLOAD, NRF24L01_Tx_Buffer, DATA_WIDTH); // 写入数据到发送缓冲器
NRF24L01_CE=1;//写完之后准备接受拉高CE
k=10;
while(k--);
/**然后清除STATUS 里面的中断各种杂七杂八的**/
NRF24L01_Write_Read_Reg(0x20+STATUS,0xff);
//清除状态寄存器的所有中断
NRF24L01_SPI(FLUSH_TX);
}
}
/**********************************************/
//接收
#include <STC15W408AS.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned short
/********** 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 //重新使用上一包数据,P_24L01_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状态寄存器
/********* 24L01发送接收数据宽度定义 ***********/
#define ADR_WIDTH 5 //5字节地址宽度
#define DATA_WIDTH 32 //32字节有效数据宽度
#define NRF24L01_Tx_Mode 0x0e //发送模式
#define NRF24L01_Rx_Mode 0x0f //接收模式
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
/******NRF24L01引脚定义*******/
sbit NRF24L01_CSN =P1^2;
sbit NRF24L01_CE =P5^5;
sbit NRF24L01_SCK =P5^4;
sbit NRF24L01_MOSI=P1^3;
sbit NRF24L01_MISO=P1^5;
sbit NRF24L01_IRQ =P1^4;
/****PWM输出LED引脚定义******/
sbit PWM_OUTR=P1^0;
uchar PWM_Write_Byte_R=1;
uchar code TX_ADDRESS[ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; //收发地址设置
uchar NRF24L01_Rx_Buffer[DATA_WIDTH]; //收到的数据最大32字节
uchar NRF24L01_Tx_Buffer[DATA_WIDTH]; //待发送的数据,32字节
uchar NRF24L01_SPI(uchar byte)
{
uchar k;
for(k=0;k<8;k++) //每字节操作8次
{
NRF24L01_MISO=1;
NRF24L01_MOSI = (byte & 0x80); //发送最高位
byte = (byte << 1); //字节左移
NRF24L01_SCK = 1; //时钟上升沿
byte |= NRF24L01_MISO; //读出的位赋值给字节最低位
NRF24L01_SCK = 0; //时钟下降沿
}
return(byte); //读出的值返回
}
void NRF24L01_Write_Read_Reg(uchar reg,uchar value)
{
NRF24L01_CSN=0; //CSN=0;
NRF24L01_SPI(reg); //写寄存器地址
NRF24L01_SPI(value); //紧接着写入寄存器的命令码
NRF24L01_CSN=1; //CSN=1;
}
void NRF24L01_Read_Buffer(uchar reg,uchar *pBuf,uchar len)
{
uchar k;
NRF24L01_CSN=0; //CSN=0
NRF24L01_SPI(reg); //写寄存器地址
for(k=0;k<len;k++)
{
pBuf[k]=NRF24L01_SPI(0XFF); //读出数据
}
NRF24L01_CSN=1; //CSN=1
}
void NRF24L01_Write_Buffer(uchar reg, uchar *pBuf, uchar len)
{
uchar k;
NRF24L01_CSN=0; //芯片的SPI功能选通
NRF24L01_SPI(reg); //写寄存器地址
for(k=0; k<len; k++)
{
NRF24L01_SPI(*pBuf++); //写入数据
}
NRF24L01_CSN=1; //芯片关闭SPI功能
}
void NRF24L01_Init(uchar Mode)
{
NRF24L01_CE=0;
NRF24L01_CSN=1;
NRF24L01_SCK=0;
NRF24L01_CE=0;
NRF24L01_Write_Buffer(0x20+TX_ADDR, TX_ADDRESS, ADR_WIDTH); // 发送地址和收方地址一致
NRF24L01_Write_Buffer(0x20+RX_ADDR_P0, TX_ADDRESS, ADR_WIDTH);// 选通道0作自动应答接收,地址、发送地址和收方地址一致
NRF24L01_Write_Read_Reg(0x20+RX_PW_P0, DATA_WIDTH); // 接收数据通道0有效数据宽度
NRF24L01_Write_Read_Reg(0x20+EN_AA, 0x01); //使能通道0的自动应答
NRF24L01_Write_Read_Reg(0x20+EN_RXADDR, 0x01); //使能通道0的接收地址
NRF24L01_Write_Read_Reg(0x20+RF_CH, 40); //设置RF通道为125
NRF24L01_Write_Read_Reg(0x20+RF_SETUP, 0x0f); // 0db增益 2Mbps
NRF24L01_Write_Read_Reg(0x20+SETUP_RETR, 0x12); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
NRF24L01_Write_Read_Reg(0x20+CONFIG, Mode);
}
void Init(void)
{
TMOD|=0x01;
TH0=0xff;
TL0=0x98;
ET0=1;
TR0=1;
EA=1;
PWM_OUTR=1; //PWM输出脚置0
NRF24L01_Init(NRF24L01_Rx_Mode); //2.4G模块初始化 发射
}
void LED_PWM_Timer0() interrupt 1
{
static uchar pwm_t=0; //局部变量,不丢失数据
TH0=0xff;
TL0=0x98;
if(pwm_t<NRF24L01_Rx_Buffer[1])
{
PWM_OUTR=1;
}
else PWM_OUTR=0;
pwm_t++;
if(pwm_t>=255)
{
pwm_t=0;
}
}
void main()
{
uint k;
Init(); //初始化
while(1)
{
k=10000;
while(k--);
NRF24L01_CE=0;
NRF24L01_IRQ=1;
NRF24L01_Read_Buffer(RD_RX_PLOAD,NRF24L01_Rx_Buffer,DATA_WIDTH);
NRF24L01_CE=1;
NRF24L01_Write_Read_Reg(0x20+STATUS,0xff); //清除状态寄存器的所有中断
NRF24L01_SPI(FLUSH_RX); //清除RX FIFO寄存器.接收模式下用
}
}
|
| |