nrf24l01读取STATUS不正确
程序都断断续续搞了好几天了,高中生求大神们讲解。(为了这个问题刚刚给阿莫贡献了30元人民币{:mad:} )程序在向上位机发送的STATUS总是0x0e,我没有用另一个nrf24L01就收,没有接收机STATUS寄存器也应该有发送次数溢出中断啊。怎么修改能让程序等待IRQ引脚变低,然后正确读出STATUS寄存器,获知是发送成功还是发送次数溢出。我是跪了,大家帮帮我。
#include "reg51.h"
sbit Led_red=P2^0;
sbit Led_green=P2^1;
sbit g=P2^2;
#define on 1;
#define off 0;
#define h 1;
#define l 0;
sbit si=P3^4;
sbit so=P3^3;
sbit irq=P3^2;
sbitsl=P3^5;
sbit csn=P3^6;
sbit ce=P3^7;
#define uchardate
#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 // ??
#define TX_ADR_WIDTH 5
#define RX_ADR_WIDTH 5
#define TX_PLOAD_WIDTH1
#define RX_PLOAD_WIDTH1
constchar TX_ADDRESS= {0x01,0x22,0x03,0x04,0x05}; //????
const char RX_ADDRESS= {0x01,0x22,0x33,0x44,0x05}; //
#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 XTAL 11059200 // CUP ????
#define baudrate 9600 // ?????
voidsystem_init();
void nrf_init();
void other_init();
charSpi_rw(char);
void delay();
char SPI_Read_Reg(char address);
void SPI_Write_Reg(char address,char value);
int SPI_Write_Buf(char reg, char *pBuf, char uchars);
voidSPI_Read_Buf(char reg, char *pBuf, char chars);
void delay()
{int a;
for(a=1;a<10;a++);
}
char Vibration=1;
void exit_init();void sleep();
void receive () interrupt 0
{
g=on;
delay();
g=off;
sleep();
}
void send (char date,int time)
{int dir=0,success,temp;
char a;
ce=l;
SPI_Write_Reg(WRITE_REG+WR_TX_PLOAD,0XAA);
ce=h;
delay();
ce=l;
}
void usart()
{TMOD = 0x20;
TH1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate)));
TL1=(unsigned char)(256 - (XTAL / (32L * 12L * baudrate))); // ???0???
SCON = 0x50;
PCON = 0x00;
TR1 = 1;
IE = 0x00; // ??????
}
void main ()
{usart();
// system_init();
nrf_init();
send (0xaa,2);
SBUF=SPI_Read_Reg(STATUS);
while(1);
}
void system_init()
{
g=off;
nrf_init();
//exit_init();
// Led_green=off;
}
void nrf_init()
{
ce=l;
csn=h;
sl=0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH); // ??????
SPI_Write_Reg(WRITE_REG + EN_AA, 0x01); //0ͨµÀ´ò¿ª
SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01);//0ͨµÀÓ¦´ð
SPI_Write_Reg(WRITE_REG + RF_CH, 0); //ƵÂÊ
SPI_Write_Reg(WRITE_REG + RX_PW_P0, 0x01); //0ͨµÀÊý¾Ý¿í¶È
SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x07); //ËÙÂÊ
SPI_Write_Reg(WRITE_REG + SETUP_AW,0x03); //5×Ö½ÚµØÖ·¿í¶È
SPI_Write_Reg(WRITE_REG + CONFIG,0xa);
}
char Spi_rw(char date)
{
char dir=0;
for (dir=0;dir<8;dir++)
{
si = (date & 0x80); // output 'uchar', MSB to MOSI
date = (date << 1); // shift next bit into MSB..
sl = 1; // Set SCK high..
date |= so; // capture current MISO bit
sl= 0;
}
return (date);
}
int SPI_Write_Buf(char reg, char *pBuf, char chars)
{int dir;
csn=l;
Spi_rw(reg);
for (dir=0;dir<chars;dir++)
{
Spi_rw(*pBuf++);
}
csn=h;
}
voidSPI_Read_Buf(char reg, char *pBuf, char chars)
{int dir;
csn=l;
Spi_rw(reg);
for (dir=0;dir<chars;dir++)
{
pBuf=Spi_rw(0);
}
csn=h;
}
voidSPI_Write_Reg(char address,char value)
{csn=l;
Spi_rw(address);
Spi_rw(value);
csn=h;
}
char SPI_Read_Reg(char address)
{char temp;
csn=l;
Spi_rw(address);
temp=Spi_rw(0);
csn=h;
return temp;
} 求大神啊,我跪了好几天了 过来看看 你别光冒泡刷分啊,解决问题啊 本帖最后由 windingway 于 2014-3-22 08:32 编辑
建议楼主发帖的时候,在功能栏最右边一组里选择"添加代码文字",这样代码比较好阅读啊..
这个芯片的参考程序很多,楼主可以参考.
比如这个:参考程序,还有这个野火哥的资料 我用别人的例程也是这个问题 昨天才30注册的amo,不会用,下次注意,"添加代码" windingway 发表于 2014-3-22 08:17
建议楼主发帖的时候,在功能栏最右边一组里选择"添加代码文字",这样代码比较好阅读啊..
这个芯片的参考程序 ...
你做过?我都调试好几天了,就是不对,我跑别人的程序,问题依旧。 勤劳的小码农 发表于 2014-3-22 08:35
你做过?我都调试好几天了,就是不对,我跑别人的程序,问题依旧。
就我观察,楼主的send()函数中
void send (char date,int time)
{
int dir=0,success,temp;
char a;
ce=l;
SPI_Write_Reg(WRITE_REG+WR_TX_PLOAD,0XAA);
ce=h;
delay();
ce=l;
}
调用的SPI_Write_Reg(WRITE_REG+WR_TX_PLOAD,0XAA);有些问题?
看数据手册的SPI Command,想要发送有效数据(payload),要使用的SPI指令是W_TX_PAYLOAD吧,而不是"WRITE_REG+WR_TX_PLOAD" windingway 发表于 2014-3-22 08:40
就我观察,楼主的send()函数中
调用的SPI_Write_Reg(WRITE_REG+WR_TX_PLOAD,0XAA);有些问题?
看到了。我竟然没注意到,好多天了。中午放学回家我再试试。谢谢皮卡丘 勤劳的小码农 发表于 2014-3-22 09:05
看到了。我竟然没注意到,好多天了。中午放学回家我再试试。谢谢皮卡丘 ...
楼主你是高中生啊,厉害。 logosz 发表于 2014-3-22 09:18
楼主你是高中生啊,厉害。
过奖过奖,还请前辈多多指导 勤劳的小码农 发表于 2014-3-22 09:45
过奖过奖,还请前辈多多指导
你用示波器看下波形。再有就是注意是否开启了自动重发功能。以及中断是否开启。 勤劳的小码农 发表于 2014-3-22 09:45
过奖过奖,还请前辈多多指导
同学我很好奇你是怎么知道电子的,比如单片机之类的,可以编程的。我高中那会儿连C语言都没听说过。大学快毕业了才知道。{:sad:} logosz 发表于 2014-3-22 09:48
同学我很好奇你是怎么知道电子的,比如单片机之类的,可以编程的。我高中那会儿连C语言都没听说过。大学 ...
最初知道易语言 然后vb再然后c+再再然后单片机 勤劳的小码农 发表于 2014-3-22 09:55
最初知道易语言 然后vb再然后c+再再然后单片机
这么厉害。{:smile:} logosz 发表于 2014-3-22 09:48
同学我很好奇你是怎么知道电子的,比如单片机之类的,可以编程的。我高中那会儿连C语言都没听说过。大学 ...
话说我初中的时候就买过电子制作的书(青少年电子制作,一套10本的样子),可惜完全看不懂...小学的时候捣鼓小霸王,还写过basic程序呢.可惜直到大学毕业才开始入门的 我大学打算学计算机应用技术,真心喜欢电子 windingway 发表于 2014-3-22 11:00
话说我初中的时候就买过电子制作的书(青少年电子制作,一套10本的样子),可惜完全看不懂...小学的时候捣鼓 ...
你qq多少?你能不能远程协控帮我调一下程序,还是不对 勤劳的小码农 发表于 2014-3-22 12:48
你qq多少?你能不能远程协控帮我调一下程序,还是不对
同学,不知道你把手册看明白没有。看明白再搞。 我认为我吧数据手册看明白了,你找到的那个是我写的时候没注意到,是个失误。我阿莫上看到的别人的程序,在我这也是有毛病,和我写的程序一样 logosz 发表于 2014-3-22 12:58
同学,不知道你把手册看明白没有。看明白再搞。
我认为我吧数据手册看明白了,你找到的那个是我写的时候没注意到,是个失误。我阿莫上看到的别人的程序,在我这也是有毛病,和我写的程序一样 windingway 发表于 2014-3-22 08:40
就我观察,楼主的send()函数中
调用的SPI_Write_Reg(WRITE_REG+WR_TX_PLOAD,0XAA);有些问题?
你在回帖子时在那选的输入源码使输入显示成源码形式? 勤劳的小码农 发表于 2014-3-23 17:33
你在回帖子时在那选的输入源码使输入显示成源码形式?
你的程序调通了没?翻出来买的几个吃灰的24L01模块,我也试试.. windingway 发表于 2014-3-23 17:35
你的程序调通了没?翻出来买的几个吃灰的24L01模块,我也试试..
#include <reg52.h>
#include <intrins.h>
sbit MOSI=P3^4;
sbit MISO=P3^3;
sbit IRQ=P3^2;
sbitSCK=P3^5;
sbit CSN=P3^6;
sbit CE=P3^7;
void usart()
{TMOD = 0x20; // ???1???8???????, ???????
TH1=(unsigned char)(256 - (11059200 / (32L * 12L * 9600)));
TL1=(unsigned char)(256 - (11059200/ (32L * 12L * 9600))); // ???0???
SCON = 0x50;
PCON = 0x00;
TR1 = 1;
IE = 0x00; // ??????
}
#include <reg52.h>
#include <intrins.h>
typedef unsigned int uint;
typedef unsigned char uchar;
#define TX_ADDR_WITDH 5//?????????5???
#define RX_ADDR_WITDH 5//?????????5???
#define TX_DATA_WITDH 8//
#define RX_DATA_WITDH 8
#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// ???,??????????
#define CONFIG 0x00// ?????
#define EN_AA 0x01// “????”????
#define EN_RX_ADDR0x02// ?????????
#define SETUP_AW 0x03// ?????????
#define SETUP_RETR0x04// ?????????
#define RF_CH 0x05// ???????????
#define RF_SETUP 0x06// ???????
#define STATUS 0x07// ?????
#define OBSERVE_TX0x08// ???????
#define CD 0x09// ???????
#define RX_ADDR_P00x0A// ????0???????
#define RX_ADDR_P10x0B// ????1???????
#define RX_ADDR_P20x0C// ????2???????
#define RX_ADDR_P30x0D// ????3???????
#define RX_ADDR_P40x0E// ????4???????
#define RX_ADDR_P50x0F// ????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?????
//*********************************************************************************
uchar sta; // ????
#define RX_DR(sta & 0x40)// ????????
#define TX_DS(sta & 0x20)// ????????
#define MAX_RT (sta & 0x10)// ????????
sbit LED=P2^4;
uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x00};
uchar RX_Buffer;
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<120;i++);
}
//nRF24L01???
void nRF24L01_Init(void)
{
CE=0;//?????
CSN=1;
SCK=0;
IRQ=1;
}
//SPI????
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)//???8???8???
{
if(byte&0x80)//????????1
MOSI=1;//?NRF24L01?1
else //???0
MOSI=0;
byte<<=1;//????????
SCK=1;//SCK??,??????,????????
if(MISO)
byte|=0x01;
SCK=0;//SCK??
}
return byte;//???????
}
//SPI?????????
//reg:?????
//value:???(?)
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;//????
CSN=0;//SPI??
status=SPI_RW(reg);//???????,??????
SPI_RW(value);//?????
CSN=1;//
return status;//????
}
//SPI????
uchar SPI_R_byte(uchar reg)
{
uchar reg_value;
CSN=0;//SPI??
SPI_RW(reg);//????
reg_value=SPI_RW(0);//???????
CSN=1;
return reg_value;//??????
}
//SPI??RXFIFO?????
//reg:?????
//Dat_Buffer:????????
//DLen:????
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI??
status=SPI_RW(reg);//???????,????
for(i=0;i<Dlen;i++)
{
Dat_Buffer=SPI_RW(0);//????
}
CSN=1;
return status;
}
//SPI?TXFIFO???????
//reg:???????
//TX_Dat_Buffer:?????????
//Dlen:????
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI??,????
status=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer);//????
}
CSN=1;
return status;
}
//??????
void nRF24L01_Set_TX_Mode(uchar *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+RF_CH,0);//2.4GHZ
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);//1Mbps??,????:0DBM,????????
SPI_W_Reg(W_REGISTER+CONFIG,0x0e);//????,??,16?CRC??,CRC??
CE=1;//????
_delay_ms(5);//CE?????????10US??
}
//??????
uchar Check_Ack(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);//??????
if(TX_DS||MAX_RT)//??TX_DS?MAX_RT?1,????????TX_FIFO?????
{
SBUF=SPI_R_byte(R_REGISTER+STATUS);
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_TX);//??????????????,?????
CSN=1;
return 0;
}
else{
SBUF=SPI_R_byte(R_REGISTER+STATUS);
return 1;
}
}
void main(void)
{
uchar i;
P0=0xff;//???IO?
P1=0xff;
P2=0xff;
P3=0xff;
_delay_us(100);
usart();
nRF24L01_Init();//NRF24L01???
while(1)
{
for(i=0;i<TX_DATA_WITDH-1;i++)//??7???
{
nRF24L01_Set_TX_Mode(&TX_Buffer);//????
while(Check_Ack());//??????
LED=0;
_delay_us(5000);
LED=1;
}
}
}
windingway 发表于 2014-3-23 17:35
你的程序调通了没?翻出来买的几个吃灰的24L01模块,我也试试..
我是11.0592晶振,9600波特率,你试试上位机收到什么?我测试就用这一个nrf,正常情况应该在STATUS读到发送次数溢出标志啊,你试试 勤劳的小码农 发表于 2014-3-23 17:40
我是11.0592晶振,9600波特率,你试试上位机收到什么?我测试就用这一个nrf,正常情况应该在STATUS读到发 ...
恩,我周一上班搭个板子试试,我不会用AVR,一直用PIC,不过调起来应该是一样的. windingway 发表于 2014-3-23 17:41
恩,我周一上班搭个板子试试,我不会用AVR,一直用PIC,不过调起来应该是一样的. ...
这是51的,直接插好数据线,打开串口9600波特率就会收到STATUS的内容,看看StATUS合不合法就行,反正我是收到的0xff。 windingway 发表于 2014-3-23 17:41
恩,我周一上班搭个板子试试,我不会用AVR,一直用PIC,不过调起来应该是一样的. ...
程序测试了? 勤劳的小码农 发表于 2014-3-24 11:26
程序测试了?
正在搭电路板 windingway 发表于 2014-3-24 12:07
正在搭电路板
你只要修改io和串口的程序,尽量保持我的程序是我原来的逻辑 勤劳的小码农 发表于 2014-3-24 13:35
你只要修改io和串口的程序,尽量保持我的程序是我原来的逻辑
我自己移植了卖给我模块的人提供的程序,只发送的话,读取回来status寄存器的值为二进制0b00011111,看起来是正常的MAX_RT被置1了.
待会我再把接收端的板子搭起来看看.
另外,你的24L01供电是3.3V不?不能用5V供电的. windingway 发表于 2014-3-24 15:50
我自己移植了卖给我模块的人提供的程序,只发送的话,读取回来status寄存器的值为二进制0b00011111,看起来 ...
你移植我的程序试试
勤劳的小码农 发表于 2014-3-24 15:54
你移植我的程序试试
{:3_55:}
我打算先用自己移植好的,跑通了再说.. windingway 发表于 2014-3-24 15:56
我打算先用自己移植好的,跑通了再说..
我特关心我的程序 windingway 发表于 2014-3-24 15:56
我打算先用自己移植好的,跑通了再说..
你是如何做到天天在线的 勤劳的小码农 发表于 2014-3-24 16:23
你是如何做到天天在线的
上班党,困了累了一定要上论坛!..
今天下班前吧接收机的电路搭好了,明天调试. 你做什么工作?一月多少工资 windingway 发表于 2014-3-24 18:01
上班党,困了累了一定要上论坛!..
今天下班前吧接收机的电路搭好了,明天调试. ...
比卡丘,我的程序什么时候测试啊 本帖最后由 windingway 于 2014-3-25 19:04 编辑
勤劳的小码农 发表于 2014-3-25 10:07
比卡丘,我的程序什么时候测试啊
我移植的程序已经初步测试好了,你的程序我就不再移植了,看了看基本上是一个模式.这种事干一次就好.{:2_35:}
我的测试代码很简单,发送端发送4个数,如果接收端收到,并向发送端发出响应,那么发送端把这4个数加1后,再次发送,如此循环..
发送端和接收端只有main.c文件不同,其他文件一致
hardware.h保存硬件连线配置
NRF24L01.c和NRF24L01.h是无线模块的功能函数
main.c为发送端和接收端的测试.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
hardware.h
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifndef HARDWARE_H
#define HARDWARE_H
#include <htc.h>
#define _XTAL_FREQ 4000000
#define INPUT 1
#define OUTPUT 0
#define HIGH 1
#define LOW 0
#define _NRF_CE RA0
#define _NRF_CSN RA1
#define _NRF_IRQ RA2
#define _DIR_NRF_CE TRISA0
#define _DIR_NRF_CSN TRISA1
#define _DIR_NRF_IRQ TRISA2
#define _SPI_SCK RC3
#define _SPI_MISO RC4
#define _SPI_MOSI RC5
#define _DIR_SPI_SCK TRISC3
#define _DIR_SPI_MISO TRISC4
#define _DIR_SPI_MOSI TRISC5
#endif
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NRF24L01.h
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#ifndef NRF24L01_H
#define NRF24L01_H
/*******************************************************/
#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节
#define TX_DATA_WITDH 4//发送数据宽度4个字节
#define RX_DATA_WITDH 4//接收数据宽度4个字节
/*******************命令寄存器***************************/
#defineR_REGISTER 0x00//读取配置寄存器
#defineW_REGISTER 0x20//写配置寄存器
#defineR_RX_PAYLOAD 0x61//读取RX有效数据
#defineW_TX_PAYLOAD 0xa0//写TX有效数据
#defineFLUSH_TX 0xe1//清除TXFIFO寄存器
#defineFLUSH_RX 0xe2//清除RXFIFO寄存器
#defineREUSE_TX_PL 0xe3//重新使用上一包有效数据
#defineNRF_NOP 0xff//空操作
/******************寄存器地址****************************/
#defineNRF_CONFIG 0x00//配置寄存器
#defineEN_AA 0x01//使能自动应答
#defineEN_RXADDR 0x02//接收通道使能0-5个通道
#defineSETUP_AW 0x03//设置数据通道地址宽度3-5
#defineSETUP_RETR 0x04//建立自动重发
#defineRF_CH 0x05//射频通道设置
#defineRF_SETUP 0x06//射频寄存器
#defineNRF_STATUS_ADR 0x07//状态寄存器
#defineOBSERVE_TX 0x08//发送检测寄存器
#defineNRF_CD 0x09//载波
#defineRX_ADDR_P0 0x0a//数据通道0接收地址
#defineRX_ADDR_P1 0x0b//数据通道1接收地址
#defineRX_ADDR_P2 0x0c//数据通道2接收地址
#defineRX_ADDR_P3 0x0d//数据通道3接收地址
#defineRX_ADDR_P4 0x0e//数据通道4接收地址
#defineRX_ADDR_P5 0x0f//数据通道5接收地址
#defineTX_ADDR 0x10//发送地址
#defineRX_PW_P0 0x11//P0通道数据宽度设置
#defineRX_PW_P1 0x12//P1通道数据宽度设置
#defineRX_PW_P2 0x13//P2通道数据宽度设置
#defineRX_PW_P3 0x14//P3通道数据宽度设置
#defineRX_PW_P4 0x15//P4通道数据宽度设置
#defineRX_PW_P5 0x16//P5通道数据宽度设置
#defineFIFO_STATUS 0x17//FIFO状态寄存器
/*STATUS寄存器的位mask*/
#define bitRX_DR 0b01000000
#define bitTX_DS 0b00100000
#define bitMAX_RT 0b00010000
#define bitPX_P_NO 0b00001110
#define bit_TX_FULL 0b00000001
/*初始化 NRF24L01*/
void Nrf_Init(void);
/*SPI通信 NRF24L01*/
/*data为地址或数据*/
unsigned char Nrf_SPI(unsigned char data);
/*清空 TX FIFO*/
void Nrf_Flush_TX(void);
/*清空 RX FIFO*/
void Nrf_Flush_RX(void);
/*从NRF24L01读取一个字节的寄存器信息*/
/*address为寄存器地址*/
unsigned char Nrf_Read_Reg(unsigned char address);
/*向NRF24L01的寄存器写入一个字节*/
/*address为寄存器地址,data为要写入寄存器的数据*/
void Nrf_Write_Reg(unsigned char address,unsigned char data);
/*读取NRF24L01的寄存器,保存在data[]中*/
/*address为寄存器地址,*data为保存数组地址,length为保存字节数*/
/*当address为RX FIFO时,可保存NRF24L01收到的数据*/
void Nrf_Read_RX(unsigned char address,
unsigned char *data,unsigned char length);
/*读取NRF24L01的寄存器,保存在data[]中*/
/*address为寄存器地址,*data为发送数据数组地址,length为发送字节数*/
/*当address为TX FIFO时,可向FIFO写入数据*/
void Nrf_Write_TX(unsigned char address,
unsigned char *data,unsigned char length);
/*设置NRF24L01为接收模式,并启动发射*/
/**data为要传输的数据数组地址*/
void Nrf_Set_Tx(unsigned char *data);
/*设置NRF24L01为掉电模式*/
void Nrf_Power_Down(void);
/*设置NRF24L01为发送模式*/
void Nrf_Set_Rx(void);
/*产生IRQ中断后,检查NRF24L01的状态*/
unsigned char Nrf_Check_ACK(void);
/*读取NRF24L01接收到的数据*/
/* *data为保存数组的地址*/
unsigned char Nrf_Recevie_Data(unsigned char *data);
unsigned char NRF_STATUS;
unsigned char RX_ADR0 = {0x34,0x43,0x10,0x10,0x01};//pipe0 address
#endif
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
NRF24L01.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "NRF24L01.h"
#include "hardware.h"
void Nrf_Init(void)
{
Nrf_Write_Reg(W_REGISTER+NRF_CONFIG,0x02);//power up
Nrf_Write_Reg(W_REGISTER+NRF_STATUS_ADR,0xff);//clear interrupt
Nrf_Flush_TX(); //clear TX FIFO
Nrf_Flush_RX(); //clear RX FIFO
}
/*This function use hardware SPI of PIC16F883*/
unsigned char Nrf_SPI(unsigned char data)
{
unsigned char readback;
SSPBUF = data;
while (SSPIF==0) {}
while(BF==0){}
readback = SSPBUF;
return readback;
}
void Nrf_Flush_TX(void)
{
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(FLUSH_TX); //write Reg address
//first write,NRF24L01 will return STATUS register
_NRF_CSN= 1; //disable SPI
}
void Nrf_Flush_RX(void)
{
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(FLUSH_RX); //write Reg address
//first write,NRF24L01 will return STATUS register
_NRF_CSN= 1; //disable SPI
}
unsigned char Nrf_Read_Reg(unsigned char address)
{
unsigned char readback;
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(address); //write Reg address
//first write,NRF24L01 will return STATUS register
readback = Nrf_SPI(0); //read Reg
_NRF_CSN= 1; //disable SPI
return readback;
}
void Nrf_Write_Reg(unsigned char address,unsigned char data)
{
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(address); //write Reg address
//first write,NRF24L01 will return STATUS register
Nrf_SPI(data);
_NRF_CSN= 1; //disable SPI
}
void Nrf_Read_RX(unsigned char address,
unsigned char *data,unsigned char length)
{
unsigned char i;
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(address); //write Reg address
for(i=0;i<length;i++) //read registers, and save
{
*(data+i) = Nrf_SPI(0);
}
_NRF_CSN= 1; //disable SPI
}
void Nrf_Write_TX(unsigned char address,
unsigned char *data,unsigned char length)
{
unsigned char i;
_NRF_CSN= 0; //enable SPI
NRF_STATUS = Nrf_SPI(address); //write Reg address
for(i=0;i<length;i++) //write
{
Nrf_SPI(*(data+i));
}
_NRF_CSN= 1; //disable SPI
}
void Nrf_Set_Tx(unsigned char *data)
{
_NRF_CE= 0;
Nrf_Write_TX(W_REGISTER+TX_ADDR,RX_ADR0,TX_ADDR_WITDH);//Pipe0
Nrf_Write_TX(W_REGISTER+RX_ADDR_P0,RX_ADR0,TX_ADDR_WITDH); //Pipe0
Nrf_Write_TX(W_TX_PAYLOAD,data,TX_DATA_WITDH);
Nrf_Write_Reg(W_REGISTER+EN_AA,0x01); //enable auto ACK of Pipe0
Nrf_Write_Reg(W_REGISTER+EN_RXADDR,0x01); //enable Piep0
Nrf_Write_Reg(W_REGISTER+SETUP_RETR,0x0a); //retry 10 times,250us delay
Nrf_Write_Reg(W_REGISTER+RF_CH,0x40); //use channel 0x40
Nrf_Write_Reg(W_REGISTER+RF_SETUP,0x0f); //data rate 2Mbps
Nrf_Write_Reg(W_REGISTER+NRF_CONFIG,0x0e); //enable CRC,2bytes
_NRF_CE= 1;
__delay_us(20); //wait to transmit
// _NRF_CE= 0;
}
void Nrf_Power_Down(void)
{
_NRF_CE= 0;
Nrf_Write_Reg(W_REGISTER+NRF_CONFIG,0x0d); //PRX,PowerDown,16bitCRC
_NRF_CE= 1;
__delay_us(20);
}
void Nrf_Set_Rx(void)
{
_NRF_CE= 0;
Nrf_Write_TX(W_REGISTER+RX_ADDR_P0,RX_ADR0,TX_ADDR_WITDH); //Pipe0
Nrf_Write_Reg(W_REGISTER+EN_AA,0x01); //enable pipe0 auto ACK
Nrf_Write_Reg(W_REGISTER+EN_RXADDR,0x01); //enable pipe0
Nrf_Write_Reg(W_REGISTER+RF_CH,0x40); //use channel 0x40
Nrf_Write_Reg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); //pipe0 payload width
Nrf_Write_Reg(W_REGISTER+RF_SETUP,0x0f); //data rate 2Mbps
Nrf_Write_Reg(W_REGISTER+NRF_CONFIG,0x0f); //enable CRC,2bytes
_NRF_CE= 1; //Start active RX mode
__delay_us(150);
}
unsigned char Nrf_Check_ACK(void)
{
NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR);
if(NRF_STATUS&bitTX_DS) //PTX received ACK from PRX
{
Nrf_Flush_TX();
Nrf_Write_Reg(W_REGISTER+NRF_STATUS_ADR,bitTX_DS); //clear TX_DS bit
return 1;
}
else if(NRF_STATUS&bitMAX_RT) //PTX re-transmit over maximum number
{
Nrf_Flush_TX();
Nrf_Write_Reg(W_REGISTER+NRF_STATUS_ADR,bitMAX_RT); //clear MAX_RT bit
return 2;
}
else if(NRF_STATUS&bitRX_DR) //PRX received new data
{
return 3;
}
else
return 0;
}
unsigned char Nrf_Recevie_Data(unsigned char *data)
{
unsigned char rx_address,stat;
NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR); //read status register
if(NRF_STATUS&bitRX_DR) //PRX received new data
{
rx_address = NRF_STATUS & bitPX_P_NO; //pipe number
switch(rx_address)
{
case 0x00: Nrf_Read_RX(R_RX_PAYLOAD,data,RX_DATA_WITDH);//pipe0
stat = 1;
break;
default: stat = 0;
break;
}
Nrf_Write_Reg(W_REGISTER+NRF_STATUS_ADR,bitRX_DR); //clear RX_DR bit
_NRF_CSN= 0;
Nrf_SPI(FLUSH_RX); //flush RX FIFO
_NRF_CSN= 1;
}
return stat;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
发射端 main.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "hardware.h"
#include "NRF24L01.h"
__CONFIG(XT & WDTDIS& LVPDIS & DEBUGEN);
extern unsigned char NRF_STATUS;
unsigned char Data_TX={4,3,2,1};
unsigned char Data_RX;
unsigned char Trans_Status;
/*initialize PIC16F883*/
void Init_Sys(void)
{
ANSEL = ANSEL & 0b11111000; //RA0,RA1,RA2 as digital I/O
_DIR_NRF_CE= OUTPUT;
_DIR_NRF_CSN= OUTPUT;
_DIR_NRF_IRQ= INPUT;
_NRF_CE= 0;
_NRF_CSN= 1;
_DIR_SPI_SCK= OUTPUT;
_DIR_SPI_MISO= INPUT;
_DIR_SPI_MOSI= OUTPUT;
//set up MSSP mode as SPI master
CKP= 0;
CKE= 1;
SMP= 0;
SSPM3= 0;SSPM2= 0;SSPM1= 0;SSPM0= 0;
SSPEN= 1;
}
void main(void)
{
unsigned char i;
Nrf_Init(); //initialize NRF24L01
NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR); //get status of NRF24L01,for debug..
while(1)
{
Nrf_Set_Tx(Data_TX); //set NRF24L01 as transmitter,then transmit Data_TX[]
while(_NRF_IRQ){} //wait for ACK from receiver
Trans_Status = Nrf_Check_ACK(); //get transmit status
if(Trans_Status==2) //no ACK,for debug
{
Trans_Status = 2;
NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR);
Nrf_Write_Reg(W_REGISTER+NRF_STATUS_ADR,0xff);//clear interrupt
}
if(Trans_Status==1) //received ACK
{
Data_TX=i;
Data_TX=i;
Data_TX=i;
Data_TX=i;
i++;
__delay_ms(10);
}
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
接收端 main.c
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "hardware.h"
#include "NRF24L01.h"
__CONFIG(XT & WDTDIS& LVPDIS & DEBUGEN);
extern unsigned char NRF_STATUS;
unsigned char Data_TX={1,2,3,4};
unsigned char Data_RX={0,0,0,0};
unsigned char Trans_Status;
/*initialize PIC16F883*/
void Init_Sys(void)
{
ANSEL = ANSEL & 0b11111000; //RA0,RA1,RA2 as digital I/O
_DIR_NRF_CE= OUTPUT;
_DIR_NRF_CSN= OUTPUT;
_DIR_NRF_IRQ= INPUT;
_NRF_CE= 0;
_NRF_CSN= 1;
_DIR_SPI_SCK= OUTPUT;
_DIR_SPI_MISO= INPUT;
_DIR_SPI_MOSI= OUTPUT;
//set up MSSP mode as SPI master
CKP= 0;
CKE= 1;
SMP= 0;
SSPM3= 0;SSPM2= 0;SSPM1= 0;SSPM0= 0;
SSPEN= 1;
}
void main(void)
{
Nrf_Init(); //initialize NRF24L01
Nrf_Set_Rx(); //set NRF24L01 as receiver
while(1)
{
while(_NRF_IRQ){NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR);/*for debug*/} //wait for data from transimitter
Trans_Status = Nrf_Check_ACK(); ////get transmit status
if(Trans_Status==3) //received valid data
{
Trans_Status = 3; //for debug
Trans_Status= Nrf_Recevie_Data(Data_RX); //save data in Data_RX[]
NRF_STATUS = Nrf_Read_Reg(R_REGISTER+NRF_STATUS_ADR); //frodebug
_NRF_CE= 1; //re-enable receiver
}
}
}
还有一些逻辑分析仪抓的图,写注释比较麻烦就先不上传了
勤劳的小码农 发表于 2014-3-24 18:27
你做什么工作?一月多少工资
坑爹的医疗设备,月薪3K windingway 发表于 2014-3-25 19:07
坑爹的医疗设备,月薪3K
你是写大程序写管了,写个测试程序,命名还搞这么长 勤劳的小码农 发表于 2014-3-25 19:11
你是写大程序写管了,写个测试程序,命名还搞这么长
不是想命名长,而是命名短的时候会踩地雷.刚开始直接复制了头文件.一编译,江山一片红...查了一会发现
#define STATUS 0x07
这一句,跟单片机的头文件有冲突,PIC单片机也有个STATUS寄存器.
所以命名太短也有问题,另外,测试程序也是程序,以后也会用到,一次性搞定,以后直接拿来用就行了,就不用重新再把程序看一遍了.最近打算拿这玩意给相机做个无线快门遥控器... 这要是51单片机多好,我就能直接测试我的设备了 windingway 发表于 2014-3-25 19:02
我移植的程序已经初步测试好了,你的程序我就不再移植了,看了看基本上是一个模式.这种事干一次就好.{:2_35 ...
好像无论在什么状态,无论ce是高还是低,无论发送模式还是接收模式还是掉电,STATUS的寄存器都是可以正常读取的吧。 勤劳的小码农 发表于 2014-3-25 22:19
好像无论在什么状态,无论ce是高还是低,无论发送模式还是接收模式还是掉电,STATUS的寄存器都是可以正常 ...
应该是这样的.
51的参考程序我也有.
http://pan.baidu.com/s/1qWjSbfA
windingway 发表于 2014-3-22 11:00
话说我初中的时候就买过电子制作的书(青少年电子制作,一套10本的样子),可惜完全看不懂...小学的时候捣鼓 ...
#define KEY2 P22
这个p22是什么?找不到他的定义
晚上回家我试试。给你发信息还要是好友{:3_43:} 勤劳的小码农 发表于 2014-3-26 13:44
#define KEY2 P22
这个p22是什么?找不到他的定义
晚上回家我试试。给 ...
这个应该是测试程序定义的按键,P22是51的端口.定义在reg51.h里面
sbit P22 = P2^2; 没用过,goto指令找不到他 windingway 发表于 2014-3-26 13:49
这个应该是测试程序定义的按键,P22是51的端口.定义在reg51.h里面
sbit P22 = P2^2; ...
确认是模块损坏,卖我模块的淘宝已经关门大吉 勤劳的小码农 发表于 2014-3-27 11:12
确认是模块损坏,卖我模块的淘宝已经关门大吉
再买个新的好了,几块钱.供电不要用5V,很容易挂.手册上说IO可承受5V逻辑电平,我没试过,估计5V单片机直接连要串联2K左右电阻吧. windingway 发表于 2014-3-27 11:23
再买个新的好了,几块钱.供电不要用5V,很容易挂.手册上说IO可承受5V逻辑电平,我没试过,估计5V单片机直接连 ...
你的nrf是pcb天线还是外接天线?隔一道墙的情况下能传输多远? 勤劳的小码农 发表于 2014-3-27 23:51
你的nrf是pcb天线还是外接天线?隔一道墙的情况下能传输多远?
PCB天线的,便宜..
没试过具体能传多远,40块钱左右可以买到带功率放大的模块,用250kpbs速率,空旷地方传输距离一公里以上. windingway 发表于 2014-3-28 08:09
PCB天线的,便宜..
没试过具体能传多远,40块钱左右可以买到带功率放大的模块,用250kpbs速率,空旷地方传输 ...
pcb天线的(最强体积),隔一道墙,5米可以不?(250kbps) 是追求体积小,发错了 勤劳的小码农 发表于 2014-3-28 11:03
是追求体积小,发错了
未实验,不知道.不过估计差不多.
我说的带放大器的模块体积也不大,比如这个 windingway 发表于 2014-3-22 11:00
话说我初中的时候就买过电子制作的书(青少年电子制作,一套10本的样子),可惜完全看不懂...小学的时候捣鼓 ...
我在c语言里面嵌入汇编,嵌入的汇编程序需要用到内存,如何保证我嵌入的程序不使用c语言用到的内存
勤劳的小码农 发表于 2014-3-29 22:51
我在c语言里面嵌入汇编,嵌入的汇编程序需要用到内存,如何保证我嵌入的程序不使用c语言用到的内存
...
C代码在编译的时候会自动分配内存,除非你在C代码里指定了内存分配,如果没这样作,内存分配的问题就交给编译器处理了. windingway 发表于 2014-3-30 18:30
C代码在编译的时候会自动分配内存,除非你在C代码里指定了内存分配,如果没这样作,内存分配的问题就交给编 ...
怎么限定变量位置?是不是在指定位置定义变量,编译器就不会再用它,我可以随便在汇编修改?我追求精确,写了一个严格的精确到毫秒级别的延时程序
windingway 发表于 2014-3-28 11:59
未实验,不知道.不过估计差不多.
我说的带放大器的模块体积也不大,比如这个 ...
发错了,微妙 勤劳的小码农 发表于 2014-3-30 19:28
怎么限定变量位置?是不是在指定位置定义变量,编译器就不会再用它,我可以随便在汇编修改?我追求精确, ...
你在C代码里定义变量,可以指定变量在内存中的地址.如果不指定,编译器就自动为其分配地址.具体代码如何写,你可以发帖问一下,我基本上不用51,所以也不太清楚. windingway 发表于 2014-3-30 19:44
你在C代码里定义变量,可以指定变量在内存中的地址.如果不指定,编译器就自动为其分配地址.具体代码如何写, ...
我竟然驱动不起来24c08……我这么笨……驱动IIC的ad完全正常,驱动24C08就没反应 勤劳的小码农 发表于 2014-4-1 22:35
我竟然驱动不起来24c08……我这么笨……驱动IIC的ad完全正常,驱动24C08就没反应 ...
那啥,有个简单的办法,就是得花点钱.买个逻辑分析仪,论坛邮购部就有卖.我几年前花了接近1千块买了个周立功的逻辑分析仪,现在貌似几百块钱就可以买到了.用来看各种协议的通信波形很是便利.
windingway 发表于 2014-4-1 22:59
那啥,有个简单的办法,就是得花点钱.买个逻辑分析仪,论坛邮购部就有卖.我几年前花了接近1千块买了个周立功 ...
这个对目前的我还有点奢侈,我的小金库就一千多点……
我要是有时间可以看看我发的帖子,不过那个程序,不是我写的,别人写的,很简短,不知怎么驱动不起来24c08
那个nrf估计是以前有过误接5v,烧了
windingway 发表于 2014-4-1 22:59
那啥,有个简单的办法,就是得花点钱.买个逻辑分析仪,论坛邮购部就有卖.我几年前花了接近1千块买了个周立功 ...
在淘宝看了看逻辑分析仪,包邮才40。24m(有买家评论说用的是24m的精振,所以……)8通道。感觉一般的小设计还是降得住的 windingway 发表于 2014-4-1 22:59
那啥,有个简单的办法,就是得花点钱.买个逻辑分析仪,论坛邮购部就有卖.我几年前花了接近1千块买了个周立功 ...
我的amo账号在电脑上怎么登录不上去 你用的是不是360浏览器,是的话估计扥不上去 高中生 厉害 楼上好基友啊!!{:titter:} 观望你们好久了,成功了没有?
页:
[1]