搜索
bottom↓
回复: 1

求助:nRF24L01为什么读不到数据?

[复制链接]

出0入0汤圆

发表于 2016-1-30 16:46:14 | 显示全部楼层 |阅读模式
    最近接触nRF24L01无线发射模块,我在调试的过程中碰到了一个问题,让我很郁闷。
    我用的芯片是AVR16,从51上移植到16上的。开始直接用AVR SPI的功能,数据从另一片24L01能正常发射出去,另外一片24L01也能正常的接收数据,接收来的数据从串口发出。后来觉得每次都连着计算机来显示接收到的数据,所以加了数码管显示功能。因为用的是学习板,PORTB口接共阳的数码管,所以就不再用AVR的SPI功能了,改用PORTD口来模拟SPI,问题就来了。数据能经24L01发射,但是另外一片接收到的数据是错的(总是接收FF)。也不知道出错再哪里,希望这里的朋友帮我分析一下。

发射部分:
#include"avr/io.h"
#include"Allhead.h"
#include<util/delay.h>
extern uchar dis_buff[4];                                                        //显示缓冲器
/*********************主函数***************************/
int main(void)
{
        LAMP_DDR |= _BV(LAMP2);                                                //指示灯
        uchar i=3;
        uint tt=1234,temp=0;
        uchar tx_buff[TX_DATA_WIDTH];                                        //发射缓存器
        timer0_init();                                                                //定时器0初始化
        spi_master_init();                                                                //spi初始化
        nrf_io_init();                                                                //nRF24L01初始化
        nrf_tx_mode();                                                                //nRF24L01设置为发射模式
        LAMP2_CLR();                                                                //初始化成功指示
        _delay_ms(1500);
        LAMP2_SET();
       
        while(1)
    {
                for(i=3,temp=tt;i!=0xff;i--)
                {
                        dis_buff[i]=temp%10;
                        temp/=10;
                }                                                                        //把需要发射的16bit数各位分解出来,放到显示缓冲器里
                /************以字符发射*************/
                tx_buff[0]='0'+dis_buff[0];                                       
                tx_buff[1]='0'+dis_buff[1];
                tx_buff[2]='0'+dis_buff[2];
                tx_buff[3]='0'+dis_buff[3];
                nrf_write_dats(WR_TX_PAYLOAD,tx_buff,TX_DATA_WIDTH);//把需要发射的数据写入nRF24L01
                while(IRQ_STA());                                                //等待发射完成
                nrf_ack();                                                                //清空nRF24L01发射缓存,请中断,清…………       
                /************发射完成指示***********/
                LAMP2_SET();
                _delay_ms(500);
                LAMP2_CLR();
                _delay_ms(500);
                /***********待发送的变量自加************/
                if(tt>9999) tt=0;
                tt++;
        }
        return 0;
}


接收部分:
#include<avr/io.h>
#include<util/delay.h>
#include<Allhead.h>
#include<avr/interrupt.h>

extern uchar dis_buff[4];
/************************主函数********************/
int main(void)
{
        uchar rec_buff[RX_DATA_WIDTH];
        timer0_init();
        spi_master_init();
        uart_init();
        nrf_io_init();
        nrf_rx_mode();
        put_str("初始化成功,通讯正常……");
        put_char('\r');put_char('\n');
        put_str("准备接收以下数据");
        _delay_ms(3000);

        while(1)
        {
                put_char('\r');put_char('\n');
                //接收到数据
                if(!IRQ_STA())
                {
                        nrf_ack();
                        nrf_read_dats(RD_RX_PAYLOAD,rec_buff,RX_DATA_WIDTH);
                        put_str("NRF24L01接收的数据:");
                        for(uchar i=0;i<RX_DATA_WIDTH;i++)
                        {
                                put_char(rec_buff[i]);
                                dis_buff[i]=rec_buff[i]-'0';
                        }
                }
                //接收不到数据,数码管显示 - - - -
                else
                {
                        put_str("NRF24L01接收的数据:nothing");
                        for(uchar i=0;i<4;i++)
                                dis_buff[i]=11;
                }       
                _delay_ms(1500);
        }
}

SPI操作时序相关:
#include"avr/io.h"
#include"util/delay.h"
#include"Allhead.h"

void spi_master_init(void)
{
        //设置SKC\CE\MOSI\CSN为输出,IRQ\MISO为输入
        SPI_DDR |= _BV(SCK)|_BV(CE)|_BV(MOSI)|_BV(CSN);
        SPI_DDR &=~_BV(IRQ)&~_BV(MISO);
        //SPI使能,主机模式,16分频
        //SPCR |= _BV(SPE)|_BV(MSTR)|_BV(SPR0);       
}
/*
uchar spi_transmit(uchar dat)
{
        SPDR = dat;
        while(!(SPSR & _BV(SPIF)));
        SPSR |= _BV(SPIF);
        return SPDR;       
}
*/
uchar spi_transmit(uchar date)
{
        uchar i;
           for(i=0;i<8;i++)          // 循环8次
           {
                //byte最高位输出到MOSI
                if(date&0x80)
                        MOSI_SET();
                else
                        MOSI_CLR();
                date<<=1;
                // 低一位移位到最高位
                SCK_SET();
                if(MISO_GET())               // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
                        date|=0x01;               // 读MISO到byte最低位
                SCK_CLR();
           }
        _delay_us(40);
    return date;                   // 返回读出的一字节       
}
为了方便调试,我在这个.c的文件里做了两个spi_transmit的函数,一个是AVR自身功能的,一个是模拟的。

还有端口、引脚、引脚操作的宏定义
#ifndef _PIN_H_
#define _PIN_H_
/****************spi端口**************************/
#define        SPI_DDR                        DDRD
#define        SPI_PORT                PORTD
#define        SPI_PIN                        PIND
/*****************指示灯端口********************/
#define        LAMP_PORT                PORTD
#define        LAMP_DDR                DDRD
#define        LAMP_PIN                PIND
/*****************串口********************/
#define        UART_PORT                PORTD
#define        UART_DDR                DDRD
#define        UART_PIN                PIND
/****************spi引脚定义*********************/
#define        CE                                2
#define        IRQ                                3
#define        CSN                                4
#define        MOSI                        5
#define        MISO                        6
#define        SCK                                7
/****************灯引脚定义*********************/
#define        LAMP2                        1
/****************串口引脚定义*********************/
#define        RXD                                0
#define        TXD                                1
/****************spi引脚操作定义******************/
#define        CE_SET()                SPI_PORT |= _BV(CE)
#define        CE_CLR()                SPI_PORT &=~_BV(CE)
#define        IRQ_STA()                (SPI_PIN & _BV(IRQ))
#define        SPI_EN()                SPI_PORT &=~_BV(CSN)
#define        SPI_DI()                SPI_PORT |= _BV(CSN)
#define IRQ_CLR()                SPI_PORT |= _BV(IRQ)
#define        MOSI_CLR()                SPI_PORT &=~_BV(MOSI)
#define        MOSI_SET()                SPI_PORT |= _BV(MOSI)
#define        SCK_CLR()                SPI_PORT &=~_BV(SCK)
#define        SCK_SET()                SPI_PORT |= _BV(SCK)
#define        MISO_GET()                (SPI_PIN &= _BV(MISO))
/****************灯引脚操作定义******************/
#define        LAMP2_SET()                LAMP_PORT |= _BV(LAMP2)
#define        LAMP2_CLR()                LAMP_PORT &=~_BV(LAMP2)
/******************结束**************************/
#endif
最后上图片
发射板
  xx,传不了图片。算了!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

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

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

出0入0汤圆

 楼主| 发表于 2016-2-3 13:46:49 | 显示全部楼层
我操!!!!端口、引脚号及引脚操作的宏定义里取得MISO引脚上的电平竟然是这样。笑话了,大意了
#define        MISO_GET()                (SPI_PIN &= _BV(MISO))      //这是错误的

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

本版积分规则

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

GMT+8, 2024-6-12 02:17

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

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