搜索
bottom↓
回复: 43

我的nRF2401接收丢包为什么这么厉害?【恢复】

[复制链接]

出0入0汤圆

发表于 2009-1-16 12:12:44 | 显示全部楼层 |阅读模式
淘宝上买的9块钱的2401板子,,测试没有问题,但是接收数据的时候丢包非常严重

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-1-16 12:18:33 | 显示全部楼层
我的板子不仅丢包,而且还发生数据传输错误



以前就做过nRF905的程序,也没这么费劲,可能还是模块有问题

出0入0汤圆

 楼主| 发表于 2009-1-16 12:20:15 | 显示全部楼层
听说2401有bug,,有这回事儿吗?

出0入0汤圆

发表于 2009-1-16 12:24:17 | 显示全部楼层
距离太远了吧?

出0入0汤圆

 楼主| 发表于 2009-1-16 12:25:19 | 显示全部楼层
两个都放在我自己的桌上

出0入0汤圆

 楼主| 发表于 2009-1-16 12:30:59 | 显示全部楼层
基本上都是误码

出0入0汤圆

发表于 2009-1-16 12:53:34 | 显示全部楼层
还有人用过吗?发生这样的情况多不?



如果模块真的问题哪就不打算买了

出0入93汤圆

发表于 2009-1-16 12:59:12 | 显示全部楼层
我用过2401,近距离基本不丢的,错码没有发现过。发送接收除了最后一位不一样,别的要一样哈。

还有就是把地址位弄长点试试。比如24bit

出0入0汤圆

 楼主| 发表于 2009-1-16 13:02:58 | 显示全部楼层
那地址呢?

我是接收和发送的地址不一样,,地址一样好像不行啊

出0入0汤圆

发表于 2009-1-16 13:12:32 | 显示全部楼层
好像和延时的时序有关

我的也是老丢包



把CRC关了好些,但是会错

本贴被 zhihuisky 编辑过,最后修改时间:2009-01-16,13:16:07.

出0入93汤圆

发表于 2009-1-16 13:13:35 | 显示全部楼层
地址当然要一样了。不一样丢是肯定的。

发送接收配对的除了最后1bit决定发送接收外,其他必须一模一样。

如果还有同样的模块在发送,需要把他们的频段区分开(频段和地址不一样,看看控制字的说明就知道了)。

出0入0汤圆

 楼主| 发表于 2009-1-16 13:40:12 | 显示全部楼层
那个配置寄存器里面?

那就是说我只能做成单向的哦?

能加我qq聊下吗?
156353160

出0入93汤圆

发表于 2009-1-16 13:51:48 | 显示全部楼层
上班不能聊QQ的。给你发个最简单的单发送和接收功能的程序吧,你试试。

(2401tx.c)

#include <io.h>

#define SIG_OUT        PORTA
#define SIG_IN        PINA
#define SIG_DIR        DDRA

#define CLK                BIT0
#define DR1                BIT1
#define PWR                BIT2
#define DATA        BIT3
#define CS                BIT4
#define CE                BIT5

#define nRF_CE_0                (SIG_OUT &= ~CE)
#define nRF_CE_1                (SIG_OUT |= CE)
#define nRF_CS_0                (SIG_OUT &= ~CS)
#define nRF_CS_1                (SIG_OUT |= CS)
#define nRF_DATA_0                (SIG_OUT &= ~DATA)
#define nRF_DATA_1                (SIG_OUT |= DATA)
#define nRF_CLK_0                (SIG_OUT &= ~CLK)
#define nRF_CLK_1                (SIG_OUT |= CLK)
#define nRF_PWR_0                (SIG_OUT &= ~PWR)
#define nRF_PWR_1                (SIG_OUT |= PWR)
#define nRF_DATA                (SIG_IN&DATA)
#define nRF_DR1                        (SIG_IN&DR1)
#define nRF_DATA_IN                (SIG_DIR &= ~DATA)
#define nRF_DATA_OUT        (SIG_DIR |= DATA)

const unsigned int set_word[9] = {
        0x8E08, 0x1C10, 0x1000, 0x0000,
        0x0000, 0x0000, 0xE77E, 0xE763,
        0xEF14
};

void init_sys();
void init_2401(); 
unsigned int spi_read();
void spi_byte(unsigned char data);
void spi_word(unsigned int data);
void transmit_data(unsigned int data);

int main()
{
        init_sys();
        init_2401();
        while(1)
        {
                transmit_data(0x0806);
                unsigned int i;
                for (i=0; i<0x8000; i++);
        }
}

void init_sys()
{
        SIG_OUT = 0x00;
        SIG_DIR = CE + CS + CLK + PWR + DATA;
}


void init_2401()
{
        unsigned char i;
        nRF_PWR_1;
        nRF_CS_1;
        for(i=0; i<9; i++)
                spi_word(set_word);
        nRF_CS_0;
}

unsigned int spi_read()
{
        unsigned char i;
        unsigned int data = 0;
        nRF_DATA_IN;
        for (i=0; i<16; i++)
        {
                nRF_CLK_0;
                data <<= 1;
                if (nRF_DATA)
                        data |= 0x0001;        
                nRF_CLK_1;
        }
        nRF_CLK_0;
        return data;
}

void spi_byte(unsigned char data)
{
        unsigned char i;
        for (i=0; i<8; i++)
        {
                nRF_CLK_0;
                if (data&0x80)
                        nRF_DATA_1;
                else
                        nRF_DATA_0;
                data <<= 1;
                nRF_CLK_1;
        }
        nRF_CLK_0;
}

void spi_word(unsigned int data)
{
        unsigned char i;
        nRF_DATA_OUT;
        for (i=0; i<16; i++)
        {
                nRF_CLK_0;
                if (data&0x8000)
                        nRF_DATA_1;
                else
                        nRF_DATA_0;
                data <<= 1;
                nRF_CLK_1;
        }
        nRF_CLK_0;
}

void transmit_data(unsigned int data)
{
        nRF_CE_1;
        spi_byte(0xE7);
        spi_word(0x7EE7);
        spi_word(data);
        nRF_CE_0;        
}


(2401rx.c)
#include <io.h>

#define SIG_OUT        PORTA
#define SIG_IN        PINA
#define SIG_DIR        DDRA

#define CLK                BIT0
#define DR1                BIT1
#define PWR                BIT2
#define DATA        BIT3
#define CS                BIT4
#define CE                BIT5

#define nRF_CE_0                (SIG_OUT &= ~CE)
#define nRF_CE_1                (SIG_OUT |= CE)
#define nRF_CS_0                (SIG_OUT &= ~CS)
#define nRF_CS_1                (SIG_OUT |= CS)
#define nRF_DATA_0                (SIG_OUT &= ~DATA)
#define nRF_DATA_1                (SIG_OUT |= DATA)
#define nRF_CLK_0                (SIG_OUT &= ~CLK)
#define nRF_CLK_1                (SIG_OUT |= CLK)
#define nRF_PWR_0                (SIG_OUT &= ~PWR)
#define nRF_PWR_1                (SIG_OUT |= PWR)
#define nRF_DATA                (SIG_IN&DATA)
#define nRF_DR1                        (SIG_IN&DR1)
#define nRF_DATA_IN                (SIG_DIR &= ~DATA)
#define nRF_DATA_OUT        (SIG_DIR |= DATA)

const unsigned int set_word[9] = {
        0x8E08, 0x1C10, 0x1000, 0x0000,
        0x0000, 0x0000, 0xE77E, 0xE763,
        0xEF15
};
unsigned int data_buf[16];

void init_sys();
void init_2401(); 
unsigned int spi_read();
void spi_word(unsigned int data);

int main()
{
        init_sys();
        init_2401();
        while(1)
        {
                if (nRF_DR1)
                {
                        data_buf[0] = spi_read();
                        data_buf[0] = 0;
                }
        }
}

void init_sys()
{
        SIG_OUT = 0x00;
        SIG_DIR = CE + CS + CLK + PWR;
}


void init_2401()
{
        unsigned int i;
        nRF_PWR_1;
        nRF_DATA_OUT;
        nRF_CS_1;
        for(i=0; i<9; i++)
                spi_word(set_word);
        nRF_CS_0;
        nRF_DATA_IN;
        nRF_CE_1;
}

unsigned int spi_read()
{
        unsigned char i;
        unsigned int data = 0;
        nRF_DATA_IN;
        for (i=0; i<16; i++)
        {
                nRF_CLK_0;
                data <<= 1;
                if (nRF_DATA)
                        data |= 0x0001;        
                nRF_CLK_1;
        }
        nRF_CLK_0;
        return data;
}

void spi_word(unsigned int data)
{
        unsigned char i;
        nRF_DATA_OUT;
        for (i=0; i<16; i++)
        {
                nRF_CLK_0;
                if (data&0x8000)
                        nRF_DATA_1;
                else
                        nRF_DATA_0;
                data <<= 1;
                nRF_CLK_1;
        }
        nRF_CLK_0;
}


附加一个2401的简单中文和英文数据手册说明,中文里面有简单的讲解配置字,详细的还是看英文的ds吧。

点击此处下载 ourdev_589986.pdf(文件大小:240K) (原文件名:2.4GHz 射频收发芯片nRF2401 及其应用.pdf) 
点击此处下载 ourdev_589987.pdf(文件大小:249K) (原文件名:nRF2401A_rev1_0.pdf) 

2401看明白配置字,用还是挺方便的。跟读写存储器一样。

出0入0汤圆

 楼主| 发表于 2009-1-16 14:03:49 | 显示全部楼层
把数据长度放小一点,用一样的地址,错误少很多了,只是前面十个字节很少出错了,,不知道还有哪里的问题,
还有就是把地址长度设为0x11的话通讯就不能进行

出0入0汤圆

 楼主| 发表于 2009-1-16 14:43:10 | 显示全部楼层
多谢friendljy ,,现在明白了地址和频段的概念,还有原先地址长度不能设成0x11,,要设置成8的倍数,,还要小于40

但是现在数据还是有丢包现象,地址长度用的是4个字节(0x20),数据长度是0x80(16个字节)

出0入0汤圆

 楼主| 发表于 2009-1-16 14:50:59 | 显示全部楼层
SIGNAL(SIG_INTERRUPT0)
{
        //外中断0        
#if send
        cli();        
        if(!(PIND & 1<<2))
        {        
                _delay_ms(80);
                if(!(PIND & 1<<2))
                {
                        //buf[0]++;
                        RF_TxPacket(buf);
                        _delay_ms(200);
                }
        }
        sei();
#endif

#if rec
        cli();
        //rec_test();
        RF_RxPacket(tmp);        
        putarr(tmp,16);
        _delay_ms(100);
        sei();
#endif        
}

我这个发送如果放在中断中,,长按中断,在刚开始传输的时候,数据有点错误,稳定传输的时候,数据没有问题,过段时间后数据会突然错掉,慢慢的全部变为0,感觉配置中应该没有什么问题了

出0入0汤圆

 楼主| 发表于 2009-1-16 15:43:52 | 显示全部楼层
直接主程序上发送错码更多了

出0入93汤圆

发表于 2009-1-16 15:52:33 | 显示全部楼层
主程序发送要有足够的发送间隔。
看2401的数据手册,每一包写到2401里面会有一个打包时间,你写的速度不能超过打包时间。
建议先加足够长的延时调试,最后再确定你需要的速度。

出0入0汤圆

 楼主| 发表于 2009-1-16 16:30:32 | 显示全部楼层
延时几百个ms也是这样

出0入0汤圆

发表于 2009-1-16 16:49:01 | 显示全部楼层
我做的程序是每秒钟发一次,地址8位,数据8位,16位CRC。
发送和接收板可以说是挨着放的,但是接收端总是丢包,收到的数据还经常是错误的。

出0入0汤圆

 楼主| 发表于 2009-1-17 08:17:09 | 显示全部楼层
想想还可能真是模块的问题啊

出0入0汤圆

发表于 2009-1-17 11:23:45 | 显示全部楼层
检查一下你的电源干净不?

出0入0汤圆

发表于 2009-1-17 11:31:50 | 显示全部楼层
把码率放低点试试,最好是加前向纠错.

出0入0汤圆

发表于 2009-1-17 11:59:20 | 显示全部楼层
我4月份用过这个不如905,最后选择905了。



频率放到最低,报文长点就不行了。

出0入0汤圆

 楼主| 发表于 2009-1-19 12:14:33 | 显示全部楼层
吐血,,居然是我开关电源的问题

出0入31汤圆

发表于 2009-1-19 12:40:02 | 显示全部楼层
具体说说,让大家也见识见识,开关电源有什么问题?

出0入0汤圆

 楼主| 发表于 2009-1-19 13:25:51 | 显示全部楼层
我这里两个开关电源都不能用,,两个9v的普通的开关电源,,

自己后面加一个7805和1117到3.3



待机中,电源比较干净

但是发送的过程中不知哪里进来的信号干扰很厉害,,退偶电容一点都没用,原先以为我用电解电容的问题,后来换上但电容也是一样的



换成稳压电源就ok了

出0入0汤圆

 楼主| 发表于 2009-1-19 13:29:00 | 显示全部楼层
双向传输怎么设计好啊

出0入0汤圆

发表于 2009-1-19 16:31:15 | 显示全部楼层
.

出0入0汤圆

发表于 2009-1-19 16:41:45 | 显示全部楼层
小生以为可以这样做,注意的有3个方面

1:不要用开关电源,因为开关电源的纹波很大还有不同频率的谐波,RF芯片的能量都是从电源直接获得所以一旦偶合到里面肯定影响到功能.如果实在要用这样+5V-----^^^^^^^^(220uH/200mA带磁屏蔽电感)-----------------------------+2.8(AP2121(LDO 高纹波抑制比))

                      |                                      |

                    0.1uF                                   100uF/16V*2(钽电容低BSR)

                      |                                      |

                     GND                                    GND

当然有的时候用一个AP2121也可以搞定

2:2个模块的距离不要小于0.5米,容易产生信号的饱和

3:如果是模块,模块下面的那个电路板的区域最好不要辅铜

出0入0汤圆

 楼主| 发表于 2009-1-19 21:24:54 | 显示全部楼层
楼上的厉害啊

出0入0汤圆

发表于 2009-1-20 08:32:54 | 显示全部楼层


是NGA的你么?首页模特了啊! (原文件名:26090260702.jpg) 

出0入0汤圆

发表于 2009-4-15 11:36:58 | 显示全部楼层
谁的账号啊?

出0入0汤圆

发表于 2009-4-19 16:02:47 | 显示全部楼层
求助:按范本程序发送和接受都设置为: 00CCCCCCCC  时接受端收到的数据是正确的,当发送和接收地址改为00CCCCCCC1时就接受不到数据了,请问:NRF2401的地址应如何设置。

出0入0汤圆

发表于 2009-4-19 17:15:04 | 显示全部楼层
求助:按范本程序发送和接受地址都设置为: 00CCCCCCCC  时接受端收到的数据是正确的,当发送和接收地址改为00CCCCCCC1时就接受不到数据了,请问:NRF2401的地址应如何设置。  
   
再说明一下 地址宽度为0X10(2字节)

出0入0汤圆

发表于 2009-4-21 14:05:31 | 显示全部楼层
发送端的地址 是要写在发送程序里的,你之所以不好使了,是因为你改的是发射机“配置字”里的地址,发射端更改目标地址时应该去更改写2401时的前两个字节(也就是目标地址),而接受机更改的是“配置字”中的通道地址。

也就是说,发射时可以随便呼叫某地址,与发射端的配置无关,接受端必须配置自己的地址!!! 在配置字中


丢包很可能是地址问题,地址太短容易丢包,只要能收的到,就不应该是模块的问题,建议地址宽度该为32,相信会有好转!!

出0入0汤圆

发表于 2009-9-7 14:59:20 | 显示全部楼层
mark,最近刚好用到。

出0入0汤圆

发表于 2009-9-12 00:03:43 | 显示全部楼层
mark
不知道为什么只能接受到一次
然后要重开电才又可以接受一次数据

出0入0汤圆

发表于 2009-11-8 19:55:48 | 显示全部楼层
学到不少东西!

出0入0汤圆

发表于 2010-4-25 00:07:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-30 15:18:03 | 显示全部楼层
我的程序几乎不丢,接受的比发送的多,程序加上好多功能之后,几乎有收不到数据!怎么办

出0入0汤圆

发表于 2010-7-31 13:34:06 | 显示全部楼层
mark,最近刚好用到。

出0入0汤圆

发表于 2011-2-26 20:33:51 | 显示全部楼层
学到不少
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-20 11:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表