TQ2440裸机跑NRF24l01模块

这个模块调试了2个多星期,亲,你没看错,是调试了两个多星期。

我觉得调试这个模块带给我最大的感受,是忍耐,忍耐,再忍耐,当你再一个境遇中毫无进展的时候,你只有慢慢去磨,或许一瞬间就是曙光。

模块本身并不难,首先我把MOSI接到模块的MISO,显然出错了 这样一个星期就过去了。

当我偶然把那个MOSI对接到MISO的时候,我发现我瓜的可以,再这么简单的问题上犯原则性的错误。


其次,SPI可以工作的时候,模块并不能发射东西,这下我就郁闷了赛。这个问题不好办,我仔细对比了一下标签的430程序,减去一些冗余的模块,发现只要发射就可以读。

那不简单,我在2440上也让它发射,就能读了。但是天有不测风云,还是那样,不能读!


没辙了么?我调了时间,可以进行精准的1us ,1ms定时,这个不错,之前一直没有实现,但是昨天我实现了,昨天是2012年12月26日。


然后,我在配置函数里面逐行打印,读取寄存器里面的值,我发现都是对的,除了一个地方是我自己填错了表征。


然后我是用while寻去发送,神奇的是可以读了。不说废话,下面贴代码。ADS1.2编译

标签发送的数据格式是,以2048这个号为例,为

buf[5]=2048>>0&0xff=0;

buf[4]=2048>>8&0xff=8;

buf[3]=2048>>16&0xff=0;

buf[2]=2048>>24&0xff=0;

buf[1]为状态标志,根据标签的供电啊。等状态在这个状态位设置

buf[0]为以上所有buf的和,也算是一个奇偶校验的东西吧。


#include "def.h"
#include "uart.h"
#include <stdlib.h>
#include "2440addr.h"
#include "nrf24l01.c"

//config里面 PWN_UP为1 ,而CE为0.则是standby 1模式:没有正在进行的数据传输。
//PWR_UP为1,PRIM_RX为0,CE为1,则数据进入TXFIXO发送
//同上,但是CE由1变0,则芯片保持在TX状态直到数据发送完毕,可能进入到standby1 模式
#define ID_NUM 2048  // ID号配置 


const uchar StatusInfo[STATUS_INFO_LENGTH] = {0X00};
//{0,0,8,0}
const uchar ID[ID_LENGTH] = {((unsigned long)ID_NUM>>24)&0xFF,((unsigned long)ID_NUM>>16)&0xFF,(ID_NUM>>8)&0xFF,(ID_NUM>>0)&0xFF};


void Delay(int num)
{
  while(num--);
}


void Main()
{
	
	uchar sta,i;
	uchar buf[5];
	
	nrf_init_io();
	spi_init();
	Uart0_Init(115200);
	//	for(i=0;i<4;i++)
	//{
	////	ucTxBuf[i]=ID[i];
	//}
	//ucTxBuf {0,0,8,0,0,8}
	//总共6位
	
  // ucTxBuf[4]=0x00;//状态位
  // for(i=0;i<6;i++)
     // ucTxBuf[5]+=ucTxBuf[i];//校验位
      
      
	delayms(2);
    RadioModuleOpen();
	delayms(2);
	RadioBasicConfig();
	SendIDMode();
	
	
	while(1)
	{
	
      SendTagID();
      delayms(2000);
     
	}
  
  

	
   
}

nrf24l01.h

#ifndef _NRF24L01_H_
#define _NRF24L01_H_

// Define interface to nRF24L01

#define TX_ADR_WIDTH   5  // 5字节宽度的发送/接收地址
#define RX_ADR_WIDTH   5

#define TX_PLOAD_WIDTH	5    // 数据通道有效数据宽度
#define RX_PLOAD_WIDTH  5

#define TX_DS	5
#define RX_DR   6

// SPI(nRF24L01) commands
#define READ_REG    0x00  // Define read command to register
#define WRITE_REG   0x20  // Define write command to register
#define RD_RX_PLOAD 0x61  // Define RX payload register address
#define WR_TX_PLOAD 0xA0  // Define TX payload register address
#define FLUSH_TX    0xE1  // Define flush TX register command
#define FLUSH_RX    0xE2  // Define flush RX register command
#define REUSE_TX_PL 0xE3  // Define reuse TX payload register command
#define NOP         0xFF  // Define No Operation, might be used to read status register

// SPI(nRF24L01) registers(addresses)
#define CONFIG      0x00  // 'Config' register address
#define EN_AA       0x01  // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR   0x02  // 'Enabled RX addresses' register address
#define SETUP_AW    0x03  // 'Setup address width' register address
#define SETUP_RETR  0x04  // 'Setup Auto. Retrans' register address
#define RF_CH       0x05  // 'RF channel' register address
#define RF_SETUP    0x06  // 'RF setup' register address
#define STATUS      0x07  // 'Status' register address
#define OBSERVE_TX  0x08  // 'Observe TX' register address
#define CD          0x09  // 'Carrier Detect' register address
#define RX_ADDR_P0  0x0A  // 'RX address pipe0' register address
#define RX_ADDR_P1  0x0B  // 'RX address pipe1' register address
#define RX_ADDR_P2  0x0C  // 'RX address pipe2' register address
#define RX_ADDR_P3  0x0D  // 'RX address pipe3' register address
#define RX_ADDR_P4  0x0E  // 'RX address pipe4' register address
#define RX_ADDR_P5  0x0F  // 'RX address pipe5' register address
#define TX_ADDR     0x10  // 'TX address' register address
#define RX_PW_P0    0x11  // 'RX payload width, pipe0' register address
#define RX_PW_P1    0x12  // 'RX payload width, pipe1' register address
#define RX_PW_P2    0x13  // 'RX payload width, pipe2' register address
#define RX_PW_P3    0x14  // 'RX payload width, pipe3' register address
#define RX_PW_P4    0x15  // 'RX payload width, pipe4' register address
#define RX_PW_P5    0x16  // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17  // 'FIFO Status Register' register address




//声明外部函数

#define     CSN_H   (rGPGDAT |=(1<<2))
#define   	CSN_L	(rGPGDAT &=~(1<<2))
#define  	CE_H	(rGPBDAT |=(1<<1))
#define		CE_L	(rGPBDAT &=~(1<<1))
#define     SPI_SCK_EN	(rSPCON0 &=~(1<<4))
#define		SPI_SCK_UEN	(rSPCON0 |=(1<<4))
#define 	SPI_RUN (rSPCON0 |=( 1<<4 | 1<<3 ))
#define		SPI_STOP	(rSPCON0 &=~( 1<<4 | 1<<3 ))


//与读卡器通信模块
//读卡器通信 定义

#define BIT0                (0x0001)
#define BIT1                (0x0002)
#define BIT2                (0x0004)
#define BIT3                (0x0008)
#define BIT4                (0x0010)
#define BIT5                (0x0020)
#define BIT6                (0x0040)
#define BIT7                (0x0080)
#define BIT8                (0x0100)
#define BIT9                (0x0200)
#define BITA                (0x0400)
#define BITB                (0x0800)
#define BITC                (0x1000)
#define BITD                (0x2000)
#define BITE                (0x4000)
#define BITF   

#define STATUS_INFO_LENGTH   1
#define ID_LENGTH            4
#define TX_ID_ADR_WIDTH    5   /*24l01 transmit address width*/ 
#define TX_ID_PLOAD_WIDTH  6  /*24l01 send ID data length*/ 

#define TX_ID_RADIO_FREQ  16

/*parameter of receive cmd mode*/
#define RX_CMD_ADR_WIDTH    5   /*24l01 receive command address width*/ 
#define RX_CMD_PLOAD_WIDTH  6  /*24l01 receive command data length*/
#define RX_CMD_RADIO_FREQ 4

#define   ALARM  2
#define   IRQ_DETECT    (rGPFDAT&1<<4)
#define    OUTPUT_PWR      3
#define CMD_ALARM         0x01
#define CMD_MODIFYID      0x02
#define CMD_SLEEPTAG      0x03
#define CMD_WRITEDATA     0x04
#define CMD_READDATA      0x05
#define CMD_MODIFYFREQ    0x06
#define CMD_MODIFYSTATUS  0x07

#define RECV_ALARM_INTERVAL 0x03
#define WAIT_ALARM_TIMES    0x0A
#define WORK_LED_TIMES      0X05
#define WORK_FREQUENCE       0x400

#define OUTPUT_PWR  3//3: 0dbm, 2: -6dbm, 1: -12dbm, 0: -18dbm
#define ID_LENGTH 4
#define STATUS_INFO_LENGTH  1
#define VOLT_DETECT

/*Tag Work Status*/
#define WORK  1
#define WORK_PREP 0
#define SLEEP   2
#define VoltOutPut_1 (P1IN & BIT3) // 低电平有效 电压低的时候是低电压

typedef unsigned char  uchar;
typedef unsigned int   uint;

uchar ucVoltDetCnt;

uchar ucRecvCmdInterval;
uchar ucWaitCmdTime;
uchar ucWorkLedTime;
uchar ucWaitAlarmTimes;
unsigned int  uiWorkFrequence;

uchar ucAlarmFlag;
uchar ucWorkState;

uchar ucTxBuf[6]={0x00,0x00,0x08,0x00,0x00,0x08};
uchar ucRxBuf[6];
uchar ucWorkState;

const uchar   TX_ID_ADDRESS[TX_ID_ADR_WIDTH]  = {0x43,0x10,0x10,0x34,0x01}; /*24l01 transmit address*/ 
const uchar   RX_CMD_ADDRESS_BROADCAST[RX_CMD_ADR_WIDTH]  = {0x74,0x66,0x22,0x98,0x13}; /*24l01 receive command address*/ 
uchar   RX_CMD_ADDRESS_SINGELCAST[ RX_CMD_ADR_WIDTH ] = {0xe5,0xe5,0xe5,0xe5,0xe5};


extern void    SendTagID(void);/*Send the TagID to the Reader*/
extern void    SendIDMode(void);/*Set the Radio Module into SendIDMode*/
extern void    RecCmdMode(void);/*Set the Radio Module into RecCmdMode*/
extern uchar   CmdDetect(void);/*Detect if Receive the Cmd from Reader*/
extern void    RadioBasicConfig(void);
extern void    SendTagInfo(void);
extern void     RadioModuleOpen(void);


extern void delayus(unsigned int time);
extern void delayms(unsigned int time);

extern void nrf_init_io(void);
extern void nrf_delay(int num);
extern void spi_init(void);
extern unsigned char SPI_RW(unsigned char byte);
extern unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value);
extern unsigned char SPI_Read(unsigned char reg);
extern unsigned char SPI_Read_Buf(unsigned char reg, unsigned char * pBuf, unsigned char bytes);
extern unsigned char SPI_Write_Buf(unsigned char reg,unsigned char * pBuf, unsigned char bytes);
extern void RX_Mode(void);
extern void TX_Mode(unsigned char * BUF);
extern uchar NRF24L01_Check(void);
extern void nRF24L01_TxPacket(uchar *tx_buf);
extern uchar nRF24L01_RxPacket(uchar *rx_buf);
extern void  CmdProcess(void);


#endif   /* _API_DEF_ */

nrf24l01.c


#include "nrf24l01.h"
#include "2440addr.h"
#include "uart.h"


 unsigned char  TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};  // 定义一个静态发送地
 unsigned char  RX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};  // 定义一个静态接收地址
 
 unsigned char  RX_BUF[TX_PLOAD_WIDTH];
 unsigned char  TX_BUF[TX_PLOAD_WIDTH]={0x01,0x02,0x03,0x04,0x05};


typedef unsigned char  uchar;
typedef unsigned int  uint;
void nrf_init_io(void)
{
//SPI 时钟时能

rCLKCON &=~(1<<18);
rCLKCON |=(1<<18);
//nSS 输出 CSN

rGPGCON &=~(3<<4);
rGPGCON |=(1<<4);
rGPGDAT |=(1<<2);
rGPGUP  &=~(1<<2);


//MOSI GPE12

rGPECON &=~(3<<24);
rGPECON |=(2<<24);
rGPEUP  &=~(1<<12);

//MISO   GPE11

rGPECON &=~(3<<22);
rGPECON |=(2<<22);
rGPEUP  &=~(1<<11);


//SCK GPE13
rGPECON &=~(3<<26);
rGPECON |=(2<<26);
rGPEUP  &=~(1<<13);

//CE OUTPUT   GPB1

rGPBCON &=~(3<<2);
rGPBCON |=(1<<2);
rGPBUP  &=~(1<<1);
rGPBDAT &=~(1<<1);


//IRQ INPUT GPF4
rGPFCON &=~(3<<8);
rGPFUP  &=~(1<<4);
rGPFDAT |=(1<<4);



  CE_L;
  CSN_H;
}

void spi_init(void)
{

rSPCON0 &=(~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(3 << 5)));
rSPCON0 |=(1<<3 | 1<<4);
rSPPRE0 =0x18;//1M
rSPPIN0 &=~((1<<0)|(1<<1)|(1<<2));
 rCLKCON|=(1<<18);     //使能SPI的时钟模块
}

void delayus(unsigned int time)
{
U32 val = 5;  
 rTCFG0 &= ~(0xff<<8);  
 rTCFG0 |= 0x4<<8;   //prescaler = 4+1  
 rTCFG1 &= ~(0xf<<8);  
 rTCFG1 |= 0<<8;  //mux = 1/2  
  
 rTCNTB2 = val;//这个是装载计数值得,关键要在TCON里面设置需不需要自动装载。  
 rTCMPB2 = val>>1;  // 50%  
 rTCON &= ~(0xf<<12);  
 rTCON |= 0xb<<12;  //interval, inv-off, update TCNTB3&TCMPB3, start timer 2  
 rTCON &= ~(2<<12);  //clear manual update bit  
 while(time--) {  
  while(rTCNTO2>=val>>1);  
  while(rTCNTO2<val>>1);  
 };  
} 



void delayms(unsigned int time)  
/*此处使用timer3 
  Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value} 
  PCLK=50MHz 
  实际计时频率为50M/4/2=6.25MHz 
  定时时间的计算:计数一次为1/6.25M=1/6.25us 计数数值为TCNTBn中的计数值比如是counter 
  那么计数时间为counter*1/6.25us, 
  此例当中counter=6250-1,目前尚不清楚为什么减去一 
  6250*(1/6.25us)=1000us即1ms 
  这样的话 Delay函数的意思就是延迟time毫秒 
*/  
  
{  
 U32 val = (PCLK>>3)/1000-1;  
   
 rTCFG0 &= ~(0xff<<8);  
 rTCFG0 |= 3<<8;   //prescaler = 3+1  
 rTCFG1 &= ~(0xf<<12);  
 rTCFG1 |= 0<<12;  //mux = 1/2  
  
 rTCNTB3 = val;  
 rTCMPB3 = val>>1;  // 50%  
 rTCON &= ~(0xf<<16);  
 rTCON |= 0xb<<16;  //interval, inv-off, update TCNTB3&TCMPB3, start timer 3  
 rTCON &= ~(2<<16);  //clear manual update bit  
 while(time--) { 
 //因为是递减计数,所以是可以的哈 
  while(rTCNTO3>=val>>1);  
  while(rTCNTO3<val>>1);  
 };  
}   
void nrf_delay(int num)
{

while(num--);
}

unsigned char SPI_RW(unsigned char byte)
{
 unsigned char ret=0;
 rSPTDAT0=byte;
 while(!(rSPSTA0&(1<<0)));
 	//rSPTDAT0=byte;
 while(!(rSPSTA0&(1<<0)));
 	ret=rSPRDAT0;
 return (ret);
}

unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
 unsigned char status;
 CSN_L;
 delayus(5);                   // CSN置低,开始传输数据
 status = SPI_RW(reg);      // 选择寄存器,同时返回状态字      
 SPI_RW(value); 
 delayus(5);            // 然后写数据到该寄存器
 CSN_H; 
 delayus(5);                  // CSN拉高,结束数据传输
 return(status);            // 返回状态寄存器
}
unsigned char SPI_Read(unsigned char reg)
{
unsigned char reg_val;
CSN_L;                // CSN置低,开始传输数据
SPI_RW(reg);                // 选择寄存器
reg_val = SPI_RW(0); // 然后从该寄存器读数据
CSN_H;                 // CSN拉高,结束数据传输
return(reg_val);            // 返回寄存器数据
}


unsigned char SPI_Read_Buf(unsigned char reg, unsigned char * pBuf, unsigned char bytes)
{

unsigned char status, i;
CSN_L;                    // CSN置低,开始传输数据
status = SPI_RW(reg);       // 选择寄存器,同时返回状态字
for(i=0; i<bytes; i++)
pBuf[i] = SPI_RW(0);    // 逐个字节从nRF24L01读出
CSN_H;                   // CSN拉高,结束数据传输
return(status);             // 返回状态寄存器 

}

unsigned char SPI_Write_Buf(unsigned char reg,unsigned char *pBuf ,unsigned char bytes)

{
 unsigned char status,i ;
 CSN_L;  		 // CSN置低,开始传输数据
 status=SPI_RW(reg);
 for(i=0;i<bytes;i++)
 SPI_RW(pBuf[i]);		 // 逐个字节写入nRF24L01
 CSN_H;			 // CSN拉高,结束数据传输
 return (status);			// 返回状态寄存器
}


void RX_Mode(void)
{
CE_L;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);// 接收设备接收通道0使用和发送设备相同的发送地址
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);  // 接收通道0选择和发送通道相同有效数据宽度
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);               // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00);           // 使能接收通道0
SPI_RW_Reg(WRITE_REG + SETUP_RETR,0x0a);			//automatic send
SPI_RW_Reg(WRITE_REG + RF_CH, 40);                 // 选择射频通道0x40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);            // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0xff);              // CRC使能,16位CRC校验,上电,接收模式
CE_H;                                            // 拉高CE启动接收设备
}
void TX_Mode(unsigned char * BUF)
{
CE_L;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);     // 写入发送地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);  // 为了应答接收设备,接收通道0地址和发送地址相同
SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH);                  // 写数据包到TX FIFO
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);       // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);   // 使能接收通道0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a);  // 自动重发延时等待250us+86us,自动重发10次
SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // 选择射频通道0x40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);    // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0xfe);     // CRC使能,16位CRC校验,上电
//SPI_RW_Reg(WRITE_REG + STATUS,0XFF);
CE_H;								   // 拉高CE启动接收设备
}

//检测24l01是否存在
uchar NRF24L01_Check(void)
{
uchar buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
uchar i;    
SPI_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. 
SPI_Read_Buf(TX_ADDR,buf,5); //读出写入的地址  
for(i=0;i<5;i++)
{
   if(buf[i]!=0xa5)
    {
     break;
    } 
   Uart0_Printf("buf[%d]=%x\n",i,buf[i]);    

 }
  if(i!=5)
      return 1;
  return 0;
}

unsigned char nRF24L01_RxPacket(uchar *rx_buf)
{	 
    uchar revale=0;
    uchar sta;
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0,RX_ADDRESS, RX_ADR_WIDTH);
	CE_L;
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x1f);   		// IRQ收发完成中断响应,16位CRC	,主接收
	CE_H; 
	nrf_delay(1000);
	sta=SPI_Read(STATUS);	// 读取状态寄存其来判断数据接收状况
	if(RX_DR)				// 判断是否接收到数据
	{
	    CE_L; 			//SPI使能
		SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
		revale =1;			//读取数据完成标志
		
	}
	SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
	return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(uchar *tx_buf)
{
	CE_L;			//StandBy I模式	
	SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);               // 使能接收通道0自动应答
	SPI_RW_Reg(WRITE_REG + RF_CH, 40);         // 选择射频通道0x40
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);    // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
	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, 0x1e);   		 // IRQ收发完成中断响应,16位CRC,主发送
	CE_H;		 //置高CE,激发数据发送
	nrf_delay(1000);	
}


//与读卡器通信模块
void SendTagID(void)
{
  uchar ucStatus;
  uchar ucCnt;
  
  CSN_L;
  delayus(1);
  ucStatus =SPI_RW(FLUSH_TX);//清空TX fifo
  CSN_H;
  
  RadioModuleOpen();
  delayms(20);
  RadioBasicConfig();
  SendIDMode();

  
  SPI_Write_Buf(WR_TX_PLOAD, ucTxBuf, TX_ID_PLOAD_WIDTH); /* Writes data to TX payload*/
  delayms(5);
  CE_H;
  delayms(5);
  ucStatus=SPI_Read(STATUS);
  Uart0_Printf("after tx,status=%x\n",ucStatus);
  CE_L;
   
  delayms(5);
}

//
void SendIDMode (void)
{       
  uchar ucRegVal;
  CE_L ;
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      // Enable Auto.Ack:Pipe0
  SPI_RW_Reg(WRITE_REG + RF_CH,TX_ID_RADIO_FREQ);        // Select RF channel 40
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x3e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
  
  CSN_L;
  SPI_RW(FLUSH_TX);
  CSN_H;
  CSN_H;
  ucRegVal = SPI_RW(FLUSH_RX);
  CSN_H; 
  
  SPI_RW_Reg(WRITE_REG+STATUS,ucRegVal);
}


void RecCmdMode(void)
{
  uchar ucRegVal;

  CE_L ;
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      /* Enable Auto.Ack:Pipe0*/
  SPI_RW_Reg(WRITE_REG + RF_CH, RX_CMD_RADIO_FREQ); /* Select RF channel 40*/
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x3f);     /* Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..*/
  
  CSN_L;
  SPI_RW(FLUSH_TX);
  CSN_H;
  CSN_L;
  ucRegVal = SPI_RW(FLUSH_RX);
  CSN_H;

  SPI_RW_Reg(WRITE_REG+STATUS,ucRegVal);
  CE_H ; /* Set CE pin high to enable RX device*/
}


uchar CmdDetect(void)
{
  uchar sta;
  uchar ucCnt;
  uchar ucFlag=0;
  uchar ucCheckout=0;
  if ((IRQ_DETECT) == 0)  /*judge if detect the interrupt request from nrf24l01*/  
  {       
    CE_L;           /*Set nrf24l01 into standby mode to reduce the power consumption*/
    sta=SPI_Read(STATUS);	/*read register STATUS's value*/
    //////////////////////////////
    if(sta & RX_DR)    	/*if receive the command from reader*/
    {
      SPI_Read_Buf(RD_RX_PLOAD,ucRxBuf,RX_CMD_PLOAD_WIDTH);/*read receive payload from RX_FIFO buffer*/ 
      ucCheckout=0;
      for (ucCnt=0;ucCnt<RX_CMD_PLOAD_WIDTH-1;ucCnt++)
        ucCheckout+=ucRxBuf[ucCnt];
      

      if ( ((ucRxBuf[0] == ucTxBuf[0]) && (ucRxBuf[1] == ucTxBuf[1]) && (ucRxBuf[2] == ucTxBuf[2]) && (ucRxBuf[3] == ucTxBuf[3])) 
         || ((ucRxBuf[0] == 0xff) && (ucRxBuf[1] == 0xff) && (ucRxBuf[2] == 0xff) && (ucRxBuf[3] == 0xff)))

      {
        ucFlag = 1;
      }
    }
    SPI_RW_Reg(WRITE_REG+STATUS,sta);/*clear RX_DR or TX_DS or MAX_RT interrupt flag*/
  }
  return ucFlag;
}


void RadioModuleClose(void)
{
  uchar cCfgWord;
  cCfgWord = SPI_Read(READ_REG+CONFIG);
  cCfgWord &= ~BIT1;
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x3c); 
}


void RadioModuleOpen(void)
{
  uchar cCfgWord;
  cCfgWord = SPI_Read(READ_REG+CONFIG);
  cCfgWord &= ~BIT1;
  //发射模式
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x3e); 
  delayms(5);
}


void RadioBasicConfig(void)
{
  uchar ucCnt;
  uchar  buf[5],station;
  uchar buf2[1]={0x03};
  CE_L;

  //TX_ID_ADDRESS:{0x43,0x10,0x10,0x34,0x01}
  SPI_Write_Buf(WRITE_REG + TX_ADDR, (uchar*)TX_ID_ADDRESS, TX_ID_ADR_WIDTH);    // Writes TX_Address to nRF24L01
  SPI_Read_Buf(TX_ADDR,buf,5);
  for(ucCnt=0;ucCnt<5;ucCnt++)
 	Uart0_Printf("TX_ADDR[%d]=%x\n",ucCnt,buf[ucCnt]);
 
 //	0x00
  SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 500us + 86us, 10 retrans
  station=SPI_Read(SETUP_RETR);
  Uart0_Printf("SETUP_RETR=%x\n",station);
  
  //ucTxBuf {0,0,8,0,0,8}
  //经过for之后
  //RX_CMD_ADDRESS_SINGELCAST里面的值为{e5,0,0,8,e5}
   for (ucCnt = 0;ucCnt < ID_LENGTH; ucCnt++)
       RX_CMD_ADDRESS_SINGELCAST[RX_CMD_ADR_WIDTH - ID_LENGTH + ucCnt] = ucTxBuf[ucCnt];   
 
 
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uchar*)RX_CMD_ADDRESS_SINGELCAST, RX_CMD_ADR_WIDTH); /*Use the same address on the RX device as the TX device*/ 
  SPI_Read_Buf(RX_ADDR_P0,buf,5);
  for(ucCnt=0;ucCnt<5;ucCnt++)
 	Uart0_Printf("RX_ADDR_P0[%d]=%x\n",ucCnt,buf[ucCnt]);
 	
 	//{0x74,0x66,0x22,0x98,0x13}
   SPI_Write_Buf(WRITE_REG + RX_ADDR_P1, (uchar*)RX_CMD_ADDRESS_BROADCAST, RX_CMD_ADR_WIDTH);
   SPI_Read_Buf(RX_ADDR_P1,buf,5);
   for(ucCnt=0;ucCnt<5;ucCnt++)
 	 Uart0_Printf("RX_ADDR_P1[%d]=%x\n",ucCnt,buf[ucCnt]);
 	
  //0x07
  SPI_RW_Reg(WRITE_REG + RF_SETUP, (OUTPUT_PWR<<1) + 1);   /*TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR*/
   station=SPI_Read(RF_SETUP);
  Uart0_Printf("RF_SETUP=%x\n",station);
  
  //0x03
  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x03);  /* Enable Pipe0*/
  delayus(10);
  SPI_Write_Buf(WRITE_REG + EN_RXADDR, buf2,1);  /* Enable Pipe0*/
  station=0;
    station=SPI_Read(EN_RXADDR);
  Uart0_Printf("EN_RXADDR=%x\n",station);
  
  //0x06
  SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_CMD_PLOAD_WIDTH); /* Select same RX payload width as TX Payload width*/
    station=SPI_Read(RX_PW_P0);
  Uart0_Printf("RX_PW_P0=%x\n",station);
  
  //0x06
  SPI_RW_Reg(WRITE_REG + RX_PW_P1, RX_CMD_PLOAD_WIDTH); /* Select same RX payload width as TX Payload width*/
    station=SPI_Read(RX_PW_P1);
  Uart0_Printf("RX_PW_P1=%x\n",station);
  
  CE_H;
}

void SendTagInfo(void)
{
  unsigned int uiResultInteger;
  switch (ucWorkState)
  {
    case WORK_PREP:
      {
        RadioModuleOpen();
        ucWorkState = WORK;
      }break;
    case WORK:
      {

        SendTagID();
/***************************work led and alarm work **************************/
        if(--ucWorkLedTime <= 0)
        {
          ucWorkLedTime = WORK_LED_TIMES;/*Reset the Led on interval*/

        }/*End of  "if(--cWorkLedTime <= 0)"*/

    /***************************receive the cmd **************************/
        if(ucRecvCmdInterval-- <= 0)
        {
          ucRecvCmdInterval = RECV_ALARM_INTERVAL; /**/
          RecCmdMode();
          while (ucWaitCmdTime-- > 0) /*wait for receive command*/
          {
            nrf_delay(1000);  /*delay 100 us*/
            if (CmdDetect())      /*if detect the cmd from reader*/
            {
                CmdProcess();
                break;
            }/*End of "if (CmdDetect() == 0)"*/
          }/*End of "while (ucWaitCmdTime-- > 0)"*/
          ucWaitCmdTime = WAIT_ALARM_TIMES; /*reset wait time in command receive mode*/
          SendIDMode();/*set the radio module into SendIDmode*/
        }/*End of "if(ucRecvCmdInterval-- <= 0)"*/
    /********************************************************************/

        RadioModuleClose();/*close the radio module for reduce power consumption*/
        ucWorkState = WORK_PREP;
      }break;
  }
}

void CmdProcess(void)
{
  uchar ucCnt;
  switch (ucRxBuf[ID_LENGTH])/*judge the command type*/
  {
  case CMD_ALARM:/*alarm command*/
    {
      ucAlarmFlag=ucRxBuf[ID_LENGTH+1];
    }break;
  case CMD_MODIFYID:/*TagID modify command*/
    {
      for (ucCnt=0;ucCnt<ID_LENGTH;ucCnt++)
        ucTxBuf[ucCnt]=ucRxBuf[ucCnt+ID_LENGTH+1];
      ucTxBuf[TX_ID_PLOAD_WIDTH-1]=0;
      for (ucCnt=0;ucCnt<(TX_ID_PLOAD_WIDTH-1);ucCnt++)
        ucTxBuf[TX_ID_PLOAD_WIDTH-1]+=ucTxBuf[ucCnt];
    }break;

  case CMD_MODIFYSTATUS:/*modify the status of tag sended to reader*/
    {
         for (ucCnt=0;ucCnt<STATUS_INFO_LENGTH;ucCnt++)
        ucTxBuf[ucCnt+ID_LENGTH]=ucRxBuf[ucCnt+ID_LENGTH+1];
     }break;
  }
}


你可能感兴趣的:(TQ2440裸机跑NRF24l01模块)