430控制的NRF24L01接收程序有点问题,哪位大神给瞧瞧、、、
#include "msp430x14x.h"
#include "BoardConfig.h"
#define uchar unsigned char
#define uint unsigned int
/*******************NRF24L01端口定义************/
#define BIT(x) (1 << (x))
#define CE 5
#define CSN 4
#define SCLK 3
#define MOSI 2
#define MISO 1
#define IRQ 0
#define PORT P5OUT
#define PDIR P5DIR
#define PIN P5IN
#define TX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
#define RX_ADR_WIDTH 5 // 5 bytes TX(RX) address width
#define TX_PLOAD_WIDTH 32 // 1 bytes TX payload
#define RX_PLOAD_WIDTH 32 // 1 bytes TX payload
uchar TX_ADDRESS[TX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};//本地地址
uchar RX_ADDRESS[RX_ADR_WIDTH]= {0xE7,0xE7,0xE7,0xE7,0xE7};//接收地址
/*************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栈入栈出状态寄存器设置
/************************函数声明*************************/
void IO_init();
void nrf2401_init();
uchar SPI_RW(uchar byte);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read(uchar reg);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);
void RX_Mode(void);
uchar nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
void delay(uint t)
{
uint i;
for(i=0;i<t;i++);
}
/*******************NRF24L01检测是否存在***************/
uchar NRF24L01_Check(void)
{
uchar bu[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
uchar bu1[5];
uchar i;
SPI_Write_Buf(WRITE_REG+TX_ADDR,bu,5);//写入5个字节的地址.
SPI_Read_Buf(TX_ADDR,bu1,5); //读出写入的地址
for(i=0;i<5;i++)if(bu1[i]!=0XA5)break;
if(i!=5) return 1; //NRF24L01不在位
return 0; //NRF24L01在位
}
/*********************NRF2401初始化****************************/
void nrf2401_init()
{
delay(100);
PORT &=~BIT(CE);
PORT |= BIT(CSN);
PORT &=~BIT(SCLK);
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
}
/*********************读写操作********************/
uchar SPI_RW(uchar byte)
{
uchar i;
PORT &=~(BIT(SCLK));
for(i=0;i<8;i++) // output 8-bit
{
if(byte & 0x80)
PORT |= BIT(MOSI);
else
{
PORT &= ~(BIT(MOSI)); // output "byte", MSB to MOSI
}
byte = (byte << 1); // shift next bit into MSB..
PORT |=BIT(SCLK); // Set clk high..
if(PIN&(BIT(MISO)))
byte |= BIT0; // capture current MISO bit
else
{
byte &=~BIT0;
}
PORT &=~BIT(SCLK); // set clk low
}
PORT &=~(BIT(MOSI)); //PULL DOWN THE MOSI
return byte;
}
/*******************读写寄存器*********************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
PORT &=~BIT(CSN); // CSN low, init SPI transac
tion
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
PORT |=BIT(CSN); // CSN high again
return status; // return nRF24L01 status byte
}
/***********************读一个字节从24L01********************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;
PORT &=~BIT(CSN); // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
PORT |=BIT(CSN); // CSN high, terminate SPI communication
return reg_val; // return register value
}
/**********************read RX payload, Rx/Tx address********************/
/*****************连续读多个寄存器函数******************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
PORT &=~BIT(CSN); // 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++)
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
PORT |=BIT(CSN); // Set CSN high again
return status; // return nRF24L01 status byte
}
/*****************write TX payload, Rx/Tx address********************/
/*****************连续写多个寄存器函数******************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,byte_ctr;
PORT &=~BIT(CSN); // 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(*pBuf++);
PORT |=BIT(CSN); // Set CSN high again
return status; // return nRF24L01 status byte
}
/***************数据接收配置函数******************/
void RX_mode()
{
PORT &=~BIT(CE);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
PORT |= BIT(CE);
delay(200);
}
/**************数据读取后放如rx_buf接收缓冲区中**************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
uchar flag=0;
uchar status;
status=SPI_Read(STATUS); // 读取状态寄存器来判断数据接收状况
if(status & 0x40) // 判断是否接收到数据
{
PORT &= ~BIT(CE); //SPI使能
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer
flag =1;
}
SPI_RW_Reg(WRITE_REG+STATUS, status); //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志
return flag;
}
/************************发送数据函数**************************/
/****************--功能:发送 tx_buf中数据--******************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
PORT &=~BIT(CE); //StandBy I模式
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, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
PORT |= BIT(CE); //置高CE,激发数据发送
delay(50);
}
/**********选择系统主时钟为8MHz********/
void clock_init()
{
uchar i;
BCSCTL1 &= ~XT2OFF; // 打开XT2高频晶体振荡器
do
{
IFG1 &= ~OFIFG; //清除晶振失败标志
for (i = 0xFF; i > 0; i--); //等待8MHz晶体起振
}
while ((IFG1 & OFIFG)); // 晶振失效标志仍然存在
BCSCTL2 |= SELM_2+SELS; //选择主时钟为高频晶振
}
/**************************IO端口初始化***********************/
void IO_init()
{
PDIR |= BIT(CSN) + BIT(CE) + BIT(SCLK) + BIT(MOSI);
P3OUT |=0xff;
}
void main()
{
uchar RxBuf[32];
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
BoardConfig(0xba);
nrf2401_init();
// clock_init();
IO_init();
while(1)
{
RX_mode();
// while(!nRF24L01_RxPacket(RxBuf));
nRF24L01_RxPacket(RxBuf);
if(RxBuf[0]==1)
{
P3OUT =0x01;
delay(1000);
RxBuf[0]=0;
}
}
}
一周热门 更多>