- 积分
- 3
贡献25
飞刀2 FD
注册时间2019-1-9
在线时间0 小时
扫一扫,手机访问本帖
|
用无线模块nrf24l01给最多六个单片机发送信息,可实现无线控制单片机,加上QT应用程序后,实现了触屏控制窗帘开关,插排通断,室内电灯开关通断
arm6410部分:
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-a.h>
#include <mach/gpio-bank-b.h>
#include <mach/gpio-bank-c.h>
#include <mach/gpio-bank-d.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-f.h>
#include <mach/gpio-bank-g.h>
#include <mach/gpio-bank-h.h>
#include <mach/gpio-bank-i.h>
#include <mach/gpio-bank-j.h>
#include <mach/gpio-bank-k.h>
#include <mach/gpio-bank-m.h>
#include <mach/gpio-bank-n.h>
#include <mach/gpio-bank-o.h>
#include <mach/gpio-bank-p.h>
#include <mach/gpio-bank-q.h>
#define DEVICE_NAME "nrf24l01"
#define CE_H gpio_direction_output(S3C64XX_GPC(1), 1) //工作模式选择
#define CE_L gpio_direction_output(S3C64XX_GPC(1), 0)
#define CE_OUT s3c_gpio_cfgpin(S3C64XX_GPC(1),S3C_GPIO_OUTPUT)
#define SCK_H gpio_direction_output(S3C64XX_GPC(2), 1)
#define SCK_L gpio_direction_output(S3C64XX_GPC(2), 0) //时钟源
#define SCK_OUT s3c_gpio_cfgpin(S3C64XX_GPC(2),S3C_GPIO_OUTPUT)
#define MISO_UP s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP)
#define MISO_IN s3c_gpio_cfgpin(S3C64XX_GPC(4),S3C_GPIO_INPUT) //(主入从出) 方向设为输入
#define MISO_GET gpio_get_value(S3C64XX_GPC(4))
#define CSN_H gpio_direction_output(S3C64XX_GPC(5), 1) //SPI片选使能,低电平使能
#define CSN_L gpio_direction_output(S3C64XX_GPC(5), 0)
#define CSN_OUT s3c_gpio_cfgpin(S3C64XX_GPC(5),S3C_GPIO_OUTPUT)
#define MOSI_H gpio_direction_output(S3C64XX_GPC(6), 1) //输入(主出从入)
#define MOSI_L gpio_direction_output(S3C64XX_GPC(6), 0)
#define MOSI_OUT s3c_gpio_cfgpin(S3C64XX_GPC(6),S3C_GPIO_OUTPUT)
#define IRQ_IN s3c_gpio_cfgpin(S3C64XX_GPC(7),S3C_GPIO_INPUT) //中断输出 方向设为输入
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 这是某寄存器地址吧,写0完成冲洗功能设置
#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 // 收发地址宽度设置
#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栈入栈出状态寄存器设置
//****************************************************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH 5 // 32 uints TX payload
#define RX_PLOAD_WIDTH 5 //32 uints TX payload
#define RX_DR (sta&0x40) //接受数据中断 //bit6 0x40 0100 0000
#define TX_DS (sta&0x20) //数据发送完成中断
#define MAX_RT (sta&0x10) //重发次数溢出中断0001 0000
char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
char NRF_Tx_Buff[TX_PLOAD_WIDTH]={0};//发送数据
char NRF_Rx_Buff[RX_PLOAD_WIDTH]={0};//接数据
char sta=0;
struct timer_list timer_list_nrf;
//写指令函数,同时读回状态字节 同时进行发送和回读
char SPI_RW(char byte)
{
char bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
if(byte&0x80) //数据最高位若为高则 1000 0000
MOSI_H;
else
MOSI_L;
byte=(byte<<1);//次高位成为最高位
SCK_H; //模拟时钟变化,进行数据传送 高电平读入 低电平输出
if(MISO_GET)
{
byte+=1; //这是循环的一个变量byte由高位发送,从低位接收ok
}
else
{ //nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
byte+=0;
}
ndelay(60);
SCK_L;
}
return(byte);
}
// 向寄存器REG写一个字节,同时返回状态字节 先写寄存器,就是先寻址后写要写入寄存器的值
char SPI_RW_Reg(char reg,char value)
{
char status;
CSN_L; //SPI片选使能
ndelay(60);
status=SPI_RW(reg); //发送寄存器号
SPI_RW(value); //写入寄存器的值
CSN_H; //SPI片选使能关闭
ndelay(60);
return(status);
}
//从某寄存器读一字节
char SPI_Read_Reg (char reg)
{
char reg_val;
CSN_L; //使能SPI传输
ndelay(60);
SPI_RW(reg); //写寄存器地址 (发送寄存器号)
reg_val=SPI_RW(READ_REG); //写入读寄存器指令就是0
CSN_H;
ndelay(60);
return(reg_val);
}
//SPI写入寄存器多个数据:reg为寄存器地址,pBuff:为待写入数据首地址,bytes写入数据的个数
char SPI_Write_Buff(char reg, char *pBuff, char bytes)
{
char status,byte_ctr;
CSN_L; // 开始SPI数据传送
ndelay(60);
status = SPI_RW(reg); // 写入并回读某寄存器
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) //其实就是往某个寄存器写入多个数据
{
SPI_RW(*pBuff++);
ndelay(20);
}
CSN_H;
ndelay(60);
return(status);
}
/*******************************发*****送*****模*****式*****代*****码*************************************/
void TX_Mode(void)
{
CE_L; //模式选择
ndelay(60);
SPI_RW_Reg(FLUSH_TX,0x00); //清除 tx FIFO寄存器 应用于发射模式
SPI_Write_Buff(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //向发送地址寄存器中写入本机的地址5个
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 频道0接收寄存器的地址设为与发送端一样
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 自动应答寄存器设为1 开启自动应答默认就是开启的
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 可用信道设置,打开了0通道是的
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x14); // 500us + 86us, 10 retrans...1a 自动重发次数设置 0001 0100 500+86us 重发4次
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 工作频率设置??????????
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 发射速度,功耗设置0000 0111 2mbsp 0dbm
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); //设置接收数据长度接收频道0
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电
CE_H;
udelay(20);
}
void NRF24L01_TxPacket(char *tx_buf)
{
CE_L; //StandBy I模式
ndelay(60);
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_RW_Reg(FLUSH_TX,0x00); //清除 tx FIFO寄存器 应用于发射模式
SPI_Write_Buff(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); // 装载数据 WR_TX_PLOAD写待发送数据指令
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE_H; //置高CE,激发数据发送
udelay(20);//150ms>10us
}
// 用于读数据 reg 寄存器地址 pBuff待读数据地址(读取数据存放变量)uchars数据个数 返回状态
char SPI_Read_Buff(char reg, char *pBuff, char bytes)
{
char status;
unsigned char uchar_ctr;
CSN_L; // 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++)
pBuff[uchar_ctr] = SPI_RW(0);
CSN_H;
return(status);
}
//数据读取后放如rx_buff接收缓冲区中
char NRF24L01_RxPacket(char *rx_buff)
{
char revale=0;
sta=SPI_Read_Reg(STATUS); // 读取状态寄存存到sta中
if(RX_DR) // RX_DR接收到数据后置1
{
SPI_Read_Buff(RD_RX_PLOAD,rx_buff,RX_PLOAD_WIDTH); // 1位数据RD_RX_PLOAD读取接收数句指令
revale =1; //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT 都置高为1,通过写1来清楚中断标志
return revale;
}
//数据接收模块
void RX_Mode(void)
{
CE_L;
SPI_RW_Reg(FLUSH_RX,0x00);
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能通道1
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 选择通讯频率
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //通道0有效数据宽度
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x14); // 高四位:自动重发延时 0: 250+86us 1 2 3 4。。。。。只一报数据发送完毕后发送下一包数据的时间间隔
//低四位:自动重发次数 1 0,2:一次。。。ff 1
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2mbsp
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); // CRC使能,16位CRC校验,上电
CE_H; //接收模式ce必须为高电平
}
//NRF 初始化
void NRF24L01_Init()
{
MISO_UP;
CE_OUT;
SCK_OUT;
CSN_OUT ;
MOSI_OUT;
IRQ_IN;
MISO_IN;
udelay(500); //100ms
CE_L; //待机模式
ndelay(60);
CSN_H; //SPI关闭
ndelay(60);
SCK_L; //时钟拉低
ndelay(60);
TX_Mode();
mdelay(1000);
}
void Nrf_Interupt()
{
mod_timer(&timer_list_nrf,jiffies+3*HZ);
NRF24L01_TxPacket(NRF_Tx_Buff);
mdelay(100);
sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
if(TX_DS)
{
SPI_RW_Reg(WRITE_REG + STATUS,sta);
printk(KERN_NOTICE "Translating is ok:The data is %d\n",NRF_Tx_Buff[0]);
}
if(MAX_RT) //如果是发送超时
{
printk(KERN_NOTICE "Translate error!\n");
SPI_RW_Reg(WRITE_REG + STATUS,sta);
}
printk(KERN_NOTICE "INTO nrf_timer! TX_DS:%d MAX_RT:%d,buff is:%d\n",TX_DS,MAX_RT,NRF_Tx_Buff[0]);
}
//cmd:暂定为10种不同的数据
//arg: reserved
static long NRF_Control(struct file *filp, unsigned int cmd, unsigned long arg)
{
init_timer(&timer_list_nrf);//初始化定时器
timer_list_nrf.function=Nrf_Interupt;//设置定时器处理函数
timer_list_nrf.expires=jiffies+3*HZ;//处理函数1s后运行
add_timer(&timer_list_nrf);//添加定时器
unsigned char i=0;
for(i=0;i<5;i++)
{
NRF_Tx_Buff[i]=cmd;
}
NRF24L01_Init(); //每打开一次初始化一次
return 0;
}
static int NRF_release()
{
printk(KERN_NOTICE "NRF_24L01 is close.\n");
//CE_L; //进入待机1模式,寄存器内容是不变的 低功耗
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = NRF_Control,
.release =NRF_release,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret1=0;
int ret=0;
ret1 = misc_register(&misc);
if(ret<0)
{printk(KERN_NOTICE "Register NRF24L01 failed!\n");
return ret;
}
printk (KERN_NOTICE " NRF24L01 driver is ok! \n");
return ret1;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jack Sun");
MODULE_DESCRIPTION("NRF34L01 Driver");
单片机部分
#define MODE 0 //mode 为1时发送 为0时接收
#if MODE
#include <msp430f149.h>
#include "无线键盘.c"
unsigned int count;
#else
#include <msp430g2553.h>
#include "无线电机驱动.c"
#endif
#if MODE
//============IO 口设置=================
#define CE_H P4OUT|=BIT0 //工作模式选择
#define CE_L P4OUT&=~BIT0
#define SCK_H P4OUT|=BIT1
#define SCK_L P4OUT&=~BIT1 //时钟源
#define MISO_H (P4IN&BIT2) //(主入从出) 方向设为输入
#define CSN_H P4OUT|=BIT3 //SPI片选使能,低电平使能
#define CSN_L P4OUT&=~BIT3
#define MOSI_H P4OUT|=BIT4 //输入(主出从入)
#define MOSI_L P4OUT&=~BIT4
#define IRQ_H (P4IN&BIT5) //中断输出 方向设为输入
#else
#define CE_H P1OUT|=BIT1 //工作模式选择
#define CE_L P1OUT&=~BIT1
#define SCK_H P1OUT|=BIT2
#define SCK_L P1OUT&=~BIT2 //时钟源
#define MISO_H (P1IN&BIT3) //(主入从出) 方向设为输入
#define CSN_H P1OUT|=BIT4 //SPI片选使能,低电平使能
#define CSN_L P1OUT&=~BIT4
#define MOSI_H P1OUT|=BIT5 //输入(主出从入)
#define MOSI_L P1OUT&=~BIT5
#define IRQ_H (P2IN&BIT0) //中断输出 方向设为输入
#endif
//***************************************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 // 收发地址宽度设置
#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栈入栈出状态寄存器设置
//****************************************************************
#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
//===================================================================
char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
char Tx_Buff[5]={0};//发送数据
char Rx_Buff[5]={0};//接收数据
char Key_Get=0;
unsigned char temp=0;
unsigned char enter=0;
//*******************************************************************
char sta; //状态标志
#define RX_DR (sta&BIT6) //接受数据中断 //bit6 0x40
#define TX_DS (sta&BIT5) //数据发送完成中断
#define MAX_RT (sta&BIT4) //重发次数溢出中断
//*********************************************************************
/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间为 0.5ms*x。这是通过软件延时,有一定误差。
* 输入 : t
* 输出 : 无
***********************************************************************/
void Delay_ms(unsigned int x)
{
unsigned int i,j;
i=0;
for(i=0;i<x;i++)
{
j=108;
while(j--);
}
}
void Delay(unsigned int Timer)
{
unsigned int i,j;
for(i=0;i<100;i++)
for(j=0;j<Timer;j++);
}
//短延时
extern void delay_ms(unsigned int x)
{
unsigned int i,j;
i=0;
for(i=0;i<x;i++)
{
j=108;
while(j--);
}
}
//写指令函数,同时读回状态字节
char SPI_RW(char byte)
{
char bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
if(byte&0x80)
MOSI_H;
else
MOSI_L;
byte=(byte<<1);
SCK_H;
if(MISO_H) //MISO输入高电平 byte|=MISO;
{
byte+=1;
}
else
{ //nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
byte+=0;
}
_NOP();
_NOP();
SCK_L;
}
return(byte);
}
// 向寄存器REG写一个字节,同时返回状态字节
char SPI_RW_Reg (char reg,char value)
{
char status;
CSN_L; //SPI片选使能
status=SPI_RW(reg); //发送寄存器号
SPI_RW(value); //写入寄存器的值
CSN_H; //SPI片选使能关闭
return(status);
}
//读指令函数 (向寄存器读一字节)
char SPI_Read_Reg (char reg)
{
char reg_val;
CSN_L; //使能SPI传输
SPI_RW(reg); //写寄存器地址 (发送寄存器号)
reg_val=SPI_RW(0); //写入读寄存器指令
CSN_H;
return(reg_val);
}
//SPI写入TXFIFO寄存器的值:reg 为寄存器地址,pBuff:为待写入数据地址,bytes写入数据的个数
char SPI_Write_Buff(char reg, char *pBuff, char bytes)
{
char status,byte_ctr;
CSN_L; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status byte
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)
{
SPI_RW(*pBuff++);
}
CSN_H; // Set CSN high again
return(status); // return nRF24L01 status byte
}
#if MODE
/*******************************发*****送*****模*****式*****代*****码*************************************/
void TX_Mode(void)
{
CE_L;
SPI_RW_Reg(FLUSH_TX,0x00); //清除 tx FIFO寄存器 应用于发射模式
SPI_Write_Buff(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x14); // 500us + 86us, 10 retrans...1a
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + RX_PW_P0, 5); //设置接收数据长度,本次设置为2字节
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校验,上电
CE_H;
delay_ms(10);
}
void nRF24L01_TxPacket( char * tx_buf)
{
CE_L; //StandBy I模式
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_RW_Reg(FLUSH_TX,0x00); //清除 tx FIFO寄存器 应用于发射模式
SPI_Write_Buff(WR_TX_PLOAD,tx_buf,5); // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
CE_H; //置高CE,激发数据发送
delay_ms(150);
}
#else
// 用于读数据 reg 寄存器地址 pBuff待读数据地址(读取数据存放变量)uchars数据个数 返回状态
char SPI_Read_Buff(char reg, char *pBuff, char uchars)
{
char status,uchar_ctr;
CSN_L; // 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<uchars;uchar_ctr++)
pBuff[uchar_ctr] = SPI_RW(0);
CSN_H;
return(status); // return nRF24L01 status uchar
}
//数据读取后放如rx_buff接收缓冲区中
char nRF24L01_RxPacket(char *rx_buff)
{
char revale=0;
sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
SPI_Read_Buff(RD_RX_PLOAD,rx_buff,5); // 1位数据
revale =1;
SPI_RW_Reg(WRITE_REG+STATUS,sta);
}
return revale;
}
//数据接收模块
void RX_Mode(void)
{
CE_L;
SPI_RW_Reg(FLUSH_RX,0x00);
SPI_Write_Buff(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 高四位:自动重发延时 0: 250+86us 1 2 3 4。。。。。只一报数据发送完毕后发送下一包数据的时间间隔
//低四位:自动重发次数 1 0,2:一次。。。ff 15次
SPI_RW_Reg(WRITE_REG + RF_CH,0); // Select RF channel 50
SPI_RW_Reg(WRITE_REG + RX_PW_P0,5); //设置接收数据长度,本次设置为1字节
SPI_RW_Reg(WRITE_REG + RF_SETUP,0x07); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR ??????
SPI_RW_Reg(WRITE_REG + CONFIG,0x0F); // CRC使能,16位CRC校验,上电
CE_H;
delay_ms(120);
}
#endif
//io口初始化
void IO_RX_Init()
{ P1DIR|=BIT0+BIT6;
P1DIR|=BIT1+BIT2+BIT4+BIT5;
P1DIR&=~BIT3;
P2DIR&=~BIT0;
P3DIR = 0XFF;
}
//NRF 初始化
void NRF_Init()
{delay_ms(100);
CE_L;
SCK_L;
CSN_H;
}
void main()
{
WDTCTL=WDTPW+WDTHOLD;
NRF_Init();
IO_RX_Init();
RX_Mode();
Rx_Buff[0]=0;
P1OUT&=~(BIT0+BIT6);
while(1)
{
if(nRF24L01_RxPacket(Rx_Buff))
{
switch(Rx_Buff[0])
{
case 1:P1OUT|=BIT0;break;
case 10:P1OUT&=~BIT0;break;
case 3:P1OUT|=BIT0;break;
case 4:P1OUT&=~BIT0;break;
case 5:P1OUT|=BIT6;break;
case 6:P1OUT&=~BIT6;break;
default:break;
}
}
}
} |
|