jackbella 发表于 2013-10-25 15:54:30

无线模块NRF24L01驱动,发送任意数据到单片机!用6410无线控制单片机MSP430G2553

用无线模块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_OUTs3c_gpio_cfgpin(S3C64XX_GPC(1),S3C_GPIO_OUTPUT)
#define SCK_Hgpio_direction_output(S3C64XX_GPC(2), 1)
#define SCK_Lgpio_direction_output(S3C64XX_GPC(2), 0)    //时钟源
#define SCK_OUTs3c_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_GETgpio_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_OUTs3c_gpio_cfgpin(S3C64XX_GPC(5),S3C_GPIO_OUTPUT)
#define MOSI_Hgpio_direction_output(S3C64XX_GPC(6), 1)//输入(主出从入)
#define MOSI_Lgpio_direction_output(S3C64XX_GPC(6), 0)
#define MOSI_OUTs3c_gpio_cfgpin(S3C64XX_GPC(6),S3C_GPIO_OUTPUT)

#define IRQ_INs3c_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_WIDTH5      // 32 uints TX payload
#define RX_PLOAD_WIDTH5       //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= {0x34,0x43,0x10,0x10,0x01}; //本地地址
char RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //接收地址
char NRF_Tx_Buff={0};//发送数据
char NRF_Rx_Buff={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 (charreg)
{
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 自动重发次数设置00010100500+86us重发4次
SPI_RW_Reg(WRITE_REG + RF_CH, 0);      // 工作频率设置??????????
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   //   发射速度,功耗设置0000 01112mbsp 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 = 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   12 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);
    }
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);


}

//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=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 " NRF24L01driver 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");
单片机部分
#defineMODE 0 //mode 为1时发送为0时接收
#if MODE
#include <msp430f149.h>
#include "无线键盘.c"
unsigned int count;
#else
#include <msp430g2553.h>
#include "无线电机驱动.c"
#endif
#ifMODE
//============IO 口设置=================
#define CE_HP4OUT|=BIT0      //工作模式选择
#define CE_LP4OUT&=~BIT0
#define SCK_HP4OUT|=BIT1
#define SCK_LP4OUT&=~BIT1   //时钟源
#define MISO_H    (P4IN&BIT2)   //(主入从出) 方向设为输入
#define CSN_HP4OUT|=BIT3   //SPI片选使能,低电平使能
#define CSN_LP4OUT&=~BIT3
#define MOSI_H P4OUT|=BIT4   //输入(主出从入)
#define MOSI_L P4OUT&=~BIT4
#define IRQ_H(P4IN&BIT5)      //中断输出 方向设为输入
#else
#define CE_HP1OUT|=BIT1      //工作模式选择
#define CE_LP1OUT&=~BIT1
#define SCK_HP1OUT|=BIT2
#define SCK_LP1OUT&=~BIT2   //时钟源
#define MISO_H    (P1IN&BIT3)   //(主入从出) 方向设为输入
#define CSN_HP1OUT|=BIT4   //SPI片选使能,低电平使能
#define CSN_LP1OUT&=~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_WIDTH32      // 32 uints TX payload
#define RX_PLOAD_WIDTH32      // 32 uints TX payload
//===================================================================
char TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //本地地址
char RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //接收地址
char Tx_Buff={0};//发送数据
char Rx_Buff={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(charreg,char value)
{
char status;
CSN_L;                                //SPI片选使能
status=SPI_RW(reg);            //发送寄存器号
SPI_RW(value);                     //写入寄存器的值
CSN_H;                           //SPI片选使能关闭
return(status);
}

//读指令函数(向寄存器读一字节)
char SPI_Read_Reg (charreg)
{
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 = 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   12 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;
P1OUT&=~(BIT0+BIT6);
while(1)
{
    if(nRF24L01_RxPacket(Rx_Buff))
    {
      switch(Rx_Buff)
      {
      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;
      }
   
    }

}
}

249917994 发表于 2014-1-6 18:25:28

249917994 发表于 2014-1-6 18:25:47

jackbella 发表于 2014-1-8 00:15:26

这个无线模块可以接到任意的io口上的,我们只需要用io口模拟spi协议就行了,接受方若是pc的话,可以在pc端加个单片机,单片机接受到了信息再通过串口给pc吧。

249917994 发表于 2014-1-8 15:10:59

jackbella 发表于 2014-1-8 20:50:50

249917994 发表于 2014-1-8 15:10
有些不懂 能加你QQ问下你吗?我的是249917994

我的是1600797604,好久不玩这些东西啦。。。

blatand 发表于 2014-5-15 19:36:30

页: [1]
查看完整版本: 无线模块NRF24L01驱动,发送任意数据到单片机!用6410无线控制单片机MSP430G2553