高级会员
- 积分
- 538
- 威望
- 249
- 贡献
- 119
- 兑换币
- 143
- 注册时间
- 2012-11-17
- 在线时间
- 85 小时
- 毕业学校
- 重庆大学
|
我的nrf24l01不能读写寄存器,nrf寄存器是好的,拿到别人51单片机实验过了,可以用,但是我们的xs128不行啊,一步一步检查最后发现连寄存器都不能读写,无论是模拟spi还是硬件spi,手上两块xs128都不行,下面是我现在测读写寄存器的程序,灯不灭,表示没读成功。。。。求大神帮忙,纠结好几天了#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#define TX_ADDR_WITDH 5//发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 17
#define RX_DATA_WITDH 17
/******************************************************************
// nRF24L01指令格式:
*******************************************************************/
#define R_REGISTER 0x00 // 读寄存器
#define W_REGISTER 0x20 // 写寄存器
#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD 0xA0 // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP 0xFF // 空操作,可以用来读状态寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // “自动应答”功能寄存
#define EN_RX_ADDR 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 // 数据通道1有效数据宽度设置寄存器
#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器
#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器
#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器
#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器
#define FIFO_STATUS 0x17 // FIFO状态寄存器
#define SlaveAddress 0x46
//*********************************************************************************
#define MISO PORTA_PA7
#define MOSI PORTA_PA6
#define SCK PORTA_PA5
#define CSN PORTA_PA4
#define CE PORTA_PA3
#define IRQ PORTA_PA2
#define LED PORTA_PA0
//---------------全局变量-----------------------
byte sta; // 状态变量
#define RX_DR (sta & 0x40) // 接收成功中断标志
#define TX_DS (sta & 0x20) // 发射成功中断标志
#define MAX_RT (sta & 0x10) // 重发溢出中断标志
byte const TX_Addr[TX_ADDR_WITDH]= {0x43,0x43,0x10,0x10,0x01}; //本地地址
//byte const RX_Addr[RX_ADDR_WITDH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//byte RX_Buffer[RX_DATA_WITDH]={0};
//extern byte RX_Buffer[RX_DATA_WITDH];
byte ddd;
/*************函数声明*****************/
void nRF24L01_Init(void);
byte SPI_RW(byte byte);
byte SPI_W_Reg(byte reg,byte value);
byte SPI_R_byte(byte reg);
//byte SPI_R_DBuffer(byte reg,byte *Dat_Buffer,byte Dlen);
byte SPI_W_DBuffer(byte reg,byte *TX_Dat_Buffer,byte Dlen);
void nRF24L01_Set_TX_Mode(byte *TX_Data);
//void nRF24L01_Set_RX_Mode(void);
byte Check_Ack(void);
//byte nRF24L01_RX_Data(void);
//void nrf_send_com(byte *TX_Data);
void S12_init()
{
CLKSEL&=0x7f; //选定外部时钟
PLLCTL&=0xbc; //禁止锁相环
SYNR=0x02; //PLL增频因子
REFDV=0x01; //PLL分频因子,最终得到24M总线频率
PLLCTL|=0x40; //锁相环电路使能
_asm(nop);
_asm(nop);
CLKSEL|=0x80; //选定锁相环时钟为系统时钟
IRQCR&=0xbf; //禁止触发外部中断
COPCTL=0X00; //看门狗无效
}
/*软件延时,24M总线频率时延时时间约为delaytime 1us*/
void _delay_us(int delaytime)
{
int i;byte j;
for (i=0;i<delaytime;i++)
for (j=0;j<8;j++);
}
/*软件延时,24M总线频率时延时时间约为delaytime 1ms*/
void delay(int delaytime)
{
int i;
for (i=0;i<delaytime;i++)
_delay_us(1000);
}
/*nRF24L01初始化*/
void nRF24L01_Init(void)
{
_delay_us(2000);
CE=0;//待机模式
CSN=1;
SCK=0;
IRQ=1;
}
/*SPI时序函数*/
byte SPI_RW(byte data)
{
byte i;
for(i=0;i<8;i++)//一字节8位循环8次写入
{
MOSI = (data & 0x80); // byte最高位输出到MOSI
data<<=1;//低一位移到最高位
SCK=1;//SCK拉高,写入一位数据,同时读取一位数据
if(MISO)
data|=0x01;
SCK=0;//SCK拉低
}
return data;//返回读取一字节
}
/*SPI写寄存器一字节函数*/
/*reg:寄存器地址*/
/*value:一字节(值)*/
byte SPI_W_Reg(byte reg,byte value)
{
byte status;//返回状态
CSN=0;//SPI片选
status=SPI_RW(reg);//写入寄存器地址,同时读取状态
SPI_RW(value);//写入一字节
CSN=1;//
return status;//返回状态
}
/*SPI*/
byte SPI_R_byte(byte reg)
{
byte reg_value;
CSN=0;//SPI片选
SPI_RW(reg);//写入地址
reg_value=SPI_RW(0);//读取寄存器的值
CSN=1;
return reg_value;//返回读取的值
}
/*SPI读取RXFIFO寄存器数据*/
/*reg:寄存器地址*/
/**Dat_Buffer:用来存读取的数据*/
/*DLen:数据长度*/
//byte SPI_R_DBuffer(byte reg,byte *Dat_Buffer,byte Dlen)
//{
// byte reg_value,i;
// CSN=0;
// reg_value=SPI_RW(reg);
// for(i=0;i<Dlen;i++)
// {
// Dat_Buffer[i]=SPI_RW(0);
// }
// CSN=1;
// return reg_value;
//}
/*SPI向TXFIFO寄存器写入数据*/
/*reg:写入寄存器地址*/
/*TX_Dat_Buffer:存放需要发送的数据*/
/*Dlen:数据长度*/
byte SPI_W_DBuffer(byte reg,byte *TX_Dat_Buffer,byte Dlen)
{
byte status,i;
CSN=0;//SPI片选,启动时序
status=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer[i]);//发送数据
}
CSN=1;
return status;
}
/*设置发送模式*/
void nRF24L01_Set_TX_Mode(byte *TX_Data)
{
CE=0;//待机(写寄存器之前一定要进入待机模式或掉电模式)
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);/*写寄存器指令+接收节点地址+地址宽度*/
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);/*为了接收设备应答信号,接收通道0地址与发送地址相同*/
SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*写有效数据地址+有效数据+有效数据宽度*/
SPI_W_Reg(W_REGISTER+EN_AA,0x01);/*接收通道0自动应答*/
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);/*使能接收通道0*/
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自动重发延时250US+86US,重发10次*/
//SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
SPI_W_Reg(W_REGISTER+RF_CH,0x40);/*(2400+40)MHZ选择射频通道0X40*/
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率,发射功率:0DBM,低噪声放大器增益*/
SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*发送模式,上电,16位CRC校验,CRC使能*/
CE=1;//启动发射
delay(5);/*CE高电平持续时间最少10US以上*/
}
/*设置接收模式*/
//void nRF24L01_Set_RX_Mode(void)
//{
// CE=0;//待机
// //SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);
// SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,RX_Addr,TX_ADDR_WITDH);
// SPI_W_Reg(W_REGISTER+EN_AA,0x01);
// SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);
// //SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);
// SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
// SPI_W_Reg(W_REGISTER+RF_CH,0x40);
// SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);
// SPI_W_Reg(W_REGISTER+CONFIG,0x0f);
// CE=1;
// delay(5);
//}
/*检测应答信号*/
byte Check_Ack(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);/*读取寄存状态*/
if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT为1,则清除中断和清除TX_FIFO寄存器的值*/
{
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_TX);
CSN=1;
return 0;
}
else
return 1;
}
/*检测接收是否成功*/
//byte nRF24L01_RX_Data(void)
//{
// //byte i,status;
// sta=SPI_R_byte(R_REGISTER+STATUS);
// if(RX_DR)
// {
// CE=0;
// SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
// //P3=RX_Buffer[0];
// SPI_W_Reg(W_REGISTER+STATUS,0xff);
// CSN=0;
// SPI_RW(FLUSH_RX);
// CSN=1;
// return 1;
// }
// else
// return 0;
//}
//void nrf_send_com(byte *TX_Data)
//{
// nRF24L01_Set_TX_Mode(TX_Data);
// delay(100);
// while(Check_Ack());
//}
void main(void) {
/* put your own code here */
DDRA=0XFF;
nRF24L01_Init();
LED=1;
while(1)
{
/* CE=0;
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x03);
CE=1;
delay(20); */
ddd=SPI_R_byte(R_REGISTER+EN_RX_ADDR);
if(ddd==0x03)
{
LED=0;
}
else
{
LED=1;
}
delay(500);
}
EnableInterrupts;
for(;;) {
/* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
注:EN_RX_ADDR默认值是0x03.灯不灭。。。
|
|