搜索
bottom↓
回复: 1

原程序是用nrf2401A做语音通信的 现在想改用NRF24L01

[复制链接]

出0入0汤圆

发表于 2011-9-20 17:13:35 | 显示全部楼层 |阅读模式
用nrf24l01和凌阳单片机做无线语音通信 怎么都不成功 请大家帮看看

/****************************************/
/*   nRF24L01_SPI通信程序
     连线方式:
             IOB0---》CE      (7脚)
             IOB1---》CSN     (6脚)
             IOB2---》SCK     (5脚)
             IOB3---》MOSI    (4脚)
             IOB4---》MISO    (3脚)
             IOB5---》IRQ     (2脚)
*/
/****************************************/
#include "SPCE061A.H"
#include "DVR1600.h"
#include "Queue.h"

unsigned int PlayFlag=0;                                                                // 播放标志
unsigned int Cnt=0;                                                                                // 等待时间
//unsigned int SourceBuf[14];                                                                // 资源缓冲数组,用于收发


#define MISO      *P_IOB_Data
#define uchar      unsigned char

#define MOSI_High *P_IOB_Data|=0x0008
#define MOSI_Low  *P_IOB_Data&=0xfff7

#define SCK_High  *P_IOB_Data|=0x0004
#define SCK_Low   *P_IOB_Data&=0xfffb

#define CE_High   *P_IOB_Data|=0x0001
#define CE_Low    *P_IOB_Data&=0xfffe

#define CSN_High  *P_IOB_Data|=0x0002
#define CSN_Low   *P_IOB_Data&=0xfffd


#define TX_ADR_WIDTH    5                   // 5 bytes TX(RX) address width
#define TX_PLOAD_WIDTH  20                  // 20 bytes TX payload

#define        RX_DS      sta&0x40         // RX_DR=sta^6;
#define TX_DS      sta&0x20         //        TX_DS        =sta^5;
#define MAX_RT     sta&0x10         //        MAX_RT        =sta^4;


#define Code_Activate 0x73


// SPI(nRF24L01) commands
#define READ_REG    0x00                                                 // Define read command to register
#define WRITE_REG   0x20                                                 // Define write command to register
#define RD_RX_PLOAD 0x61                                         // Define RX payload register address
#define WR_TX_PLOAD 0xA0                                         // Define TX payload register address
#define FLUSH_TX    0xE1                                                 // Define flush TX register command
#define FLUSH_RX    0xE2                                                 // Define flush RX register command
#define REUSE_TX_PL 0xE3                                         // Define reuse TX payload register command
#define NOP         0xFF                                                         // Define No Operation, might be used to read status register
#define R_RX_PL_WID        0x60
#define Activate        0x50


// SPI(nRF24L01) registers(addresses)
#define CONFIG      0x00                                                 // 'Config' register address
#define EN_AA       0x01                      // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR   0x02                  // 'Enabled RX addresses' register address
#define SETUP_AW    0x03                     // 'Setup address width' register address
#define SETUP_RETR  0x04                  // 'Setup Auto. Retrans' register address
#define RF_CH       0x05                       // 'RF channel' register address
#define RF_SETUP    0x06                                         // 'RF setup' register address
#define STATUS      0x07                                         // 'Status' register address
#define OBSERVE_TX  0x08                                 // 'Observe TX' register address
#define CD          0x09                                                 //'Carrier Detect' register address
#define RX_ADDR_P0  0x0A                                         // 'RX address pipe0' register address
#define RX_ADDR_P1  0x0B                                 // 'RX address pipe1' register address
#define RX_ADDR_P2  0x0C                                 // 'RX address pipe2' register address
#define RX_ADDR_P3  0x0D                                 // 'RX address pipe3' register address
#define RX_ADDR_P4  0x0E                                 // 'RX address pipe4' register address
#define RX_ADDR_P5  0x0F                                    // 'RX address pipe5' register address
#define TX_ADDR     0x10                                         // 'TX address' register address
#define RX_PW_P0    0x11                                         // 'RX payload width, pipe0' register address
#define RX_PW_P1    0x12                                         // 'RX payload width, pipe1' register address
#define RX_PW_P2    0x13                                         // 'RX payload width, pipe2' register address
#define RX_PW_P3    0x14                                         // 'RX payload width, pipe3' register address
#define RX_PW_P4    0x15                                         // 'RX payload width, pipe4' register address
#define RX_PW_P5    0x16                                         // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17                                     // 'FIFO Status Register' register address
#define FEATURE         0x1d
#define DYNPD                0x1c

unsigned char Buffer[5]={"0","3","4","5","8"};

unsigned char TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};  // Define a static TX address

unsigned char  SPI_ReceiveData;
unsigned char RX[16];

unsigned char Tx_Buffer[14];  //={0x02,0x00,0x00};

//端口初始化
void Initial_IO()  //初始化IOB端口
{
           *P_IOB_Dir=0xffcf;    //set IRQ,MISO input ,the other output
           *P_IOB_Attrib=0xffcf;  
           *P_IOB_Data=0x0000;
   
           *P_IOA_Dir = 0xff00;           //设置A口低8位为同向下拉输入,控制键盘
        *P_IOA_Attrib = 0xff00;      
        *P_IOA_Data = 0x0000;  
}


//延时函数
void delay1us(unsigned char t)
{
    while(--t)
    *P_Watchdog_Clear=1;
}


//写一个字节到24L01,同时读一个字节
unsigned char SPI_RW(unsigned char byte)   
{
     unsigned char bit_ctr;
        
     for(bit_ctr=0;bit_ctr<8;bit_ctr++)   //output 8-bit
       {
           if(byte&0x80)  
              MOSI_High;
           else
             MOSI_Low;
            
             byte=(byte<<1);
            
             SCK_High;
             if(MISO&0x0010)
             byte |= 1;      
             SCK_Low;
       }
       return(byte);  //return read byte
}


unsigned char SPI_Read(unsigned char reg)
{
        unsigned char reg_val;

          CSN_Low;               // CSN low, initialize SPI communication...
         
          SPI_RW(reg);            // Select register to read from..
          reg_val = SPI_RW(0);    // ..then read registervalue
         
          CSN_High;                // CSN high, terminate SPI communication
         
          return(reg_val);        // return register value
}


/****向寄存器reg写一个字节,同时返回状态字节**************/
unsigned char SPI_RW_Reg(unsigned char reg,unsigned char value)
{
   unsigned char status;
   CSN_Low;
   
   status=SPI_RW(reg);   //select register  and write value to it
   SPI_RW(value);  
   
   CSN_High;
   return(status);     
}


/********读出bytes字节的数据*************************/
unsigned char SPI_Read_Buf(uchar reg,uchar *pBuf,uchar bytes)
{
          uchar status,byte_ctr;
          CSN_Low;
  
    status=SPI_RW(reg);      
    for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
           pBuf[byte_ctr]=SPI_RW(0);
  
           CSN_High;
           return(status);
}


/****************写入bytes字节的数据*******************/
unsigned char SPI_Write_Buf(uchar reg,uchar *pBuf,uchar bytes)
{
           uchar status,byte_ctr;
           CSN_Low;
           delay1us(1);
   
           status=SPI_RW(reg);      
           for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
           SPI_RW(*pBuf++);
   
           CSN_High;
           delay1us(1);
           return(status);
}





/*接收函数,返回1表示有数据收到,否则没有数据接收到**/
unsigned char nRF24L01_RxPacket(unsigned char *rx_buf)
{
   unsigned char sta,revale=0;  
               
   SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);  
   CE_High;
   delay1us(10);
   
          sta=SPI_Read(STATUS);                 // read register STATUS's value
           if(sta&0x40)                                            // if receive data ready (RX_DR) interrupt
    {
                  CE_Low;                // stand by mode
                  SPI_Read_Buf(RD_RX_PLOAD,rx_buf,WR_TX_PLOAD); // read receive payload from RX_FIFO buffer
                     revale =1;
     }
     SPI_RW_Reg(WRITE_REG+STATUS,sta);   // clear RX_DR or TX_DS or MAX_RT interrupt flag
     return revale;
   
}


/****************发送函数***************************/
void nRF24L01_TxPacket(unsigned char *tx_buf)
{
                unsigned char sta;
     sta=SPI_Read(STATUS);
     SPI_RW_Reg(WRITE_REG+STATUS,0x70);
     sta=SPI_Read(STATUS);
     
     CSN_Low;               // CSN low, initialize SPI communication...
           SPI_RW(FLUSH_TX);            // Select register to read from..
           CSN_High;
           
           sta=SPI_Read(STATUS);
           delay1us(1);
           sta=SPI_Read(STATUS);
           
     CE_Low;                //  CE=0;
     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);       // WritesTX_Address to nRF24L01
     
     
     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);     //RX_Addr0 same as TX_Adr for Auto.Ack
     SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);   // Writes data to TX payload
     
     
     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);            // Set PWR_UP bit, enable CRC(2 bytes) &Prim:TX. MAX_RT & TX_DS enabled..
     
     CE_High;                //CE=1;
     delay1us(10);
     CE_Low;       //CE=0;
     sta=SPI_Read(STATUS);
     sta=SPI_Read(STATUS);
}   


void RX_Mode(void)
{
        CE_Low;   //CE=0;
        delay1us(1);

       
    SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
          SPI_Write_Buf(WR_TX_PLOAD, Buffer, TX_PLOAD_WIDTH); // Writes data to TX payload
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
          SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
          SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  
         
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..


          CE_High;   //CE = 1   Set CE pin high to enable RX device
         
    delay1us(1);
  //  This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
  //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.
}


void TX_Mode(void)
{
        CE_Low;      //CE=0;
       
        delay1us(1);
       
          SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
          //SPI_Write_Buf(WR_TX_PLOAD,Tx_Buffer, TX_PLOAD_WIDTH);         // Writes data to TX payload

        SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
          SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
          SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
         
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
   
    CE_High;    //        CE=1;  
    delay1us(1);  
}


void nRF24L01_Initial(void)
{
        unsigned char Connected_Count;
          CE_Low;                        //nRF24L01_CE=0;                         chip enable
          CSN_Low;
          CSN_High;                        //nRF24L01_CSN=1;                         Spi disable
          SCK_Low;          //nRF24L01_SCK=0;                         Spi clock line init high
          
          
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0c);
          
          SPI_RW_Reg(WRITE_REG + STATUS, 0x70);
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
          delay1us(250);
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
          SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03); // Setup address width=5 bytes
        SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x55); // 500us + 86us, 10 retrans...
        SPI_RW_Reg(WRITE_REG + RF_CH, 40);
        SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);
        SPI_RW_Reg(WRITE_REG + RX_PW_P0, 32);
        SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01       
          SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
         
         
          SPI_RW_Reg(WRITE_REG + FEATURE, 0x04);
          SPI_Read_Buf(READ_REG+ FEATURE         ,&Connected_Count,1);
  //        SPI_Read_Buf(R_RX_PL_WID          ,&Connected_Count,1);
        if(Connected_Count==0x00)
        {
                SPI_RW_Reg(Activate, Code_Activate);
        }
        //Connected_Count=0;
       
       
        SPI_RW_Reg(WRITE_REG + FEATURE, 0x07);
    SPI_RW_Reg(WRITE_REG + DYNPD, 0x01);
          
          
          
       
       
}


/****************** 配置函数********************************/
void nRF24L01_Config(void)
{
     CE_Low;          //        CE=0 ;chip enable
     CSN_High;       //CSN=1   Spi disable
     SCK_Low;       //SCK=0   // Spi clock line init high
     CE_Low;        //CE=0;
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) &Prim:RX. RX_DR enabled..
   
    SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);          //  频道0自动 ACK应答允许
    SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
   
    SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x02); // Setup address width=5 bytes
    SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
   
    SPI_RW_Reg(WRITE_REG + RF_CH, 0);
    SPI_RW_Reg(WRITE_REG + RF_SETUP,0x0f); // TX_PWR:0dBm, Datarate:2Mbps,
}
//*************************************************************************************************
/*void Record()
{SACM_DVR1600_Initial(); // DVR1600初始化
SACM_DVR1600_Rec(0,3); // 开始录音,选择16Kbps码率。第一个参数无意义。
while(SACM_DVR1600_Status()&0x01) // 检测录音是否完成(当录音数据充满Flash后录音完成)
{
*P_Watchdog_Clear = 0x01; // 清看门狗
SACM_DVR1600_ServiceLoop(); // 进行压缩编码
}
}
void PlayRecord(void)
{
SACM_DVR1600_Initial(); // DVR1600初始化
SACM_DVR1600_Play(0, 3, 3); // 开始放音,由DAC1和DAC2输出。第一个参数无意义。
while(SACM_DVR1600_Status()&0x01) // 检测放音是否完成
{
*P_Watchdog_Clear = 0x01; // 清看门狗
SACM_DVR1600_ServiceLoop(); // 进行解码
}
}*/
main()
{  
        unsigned int i;
//        unsigned char a=0;  
          Initial_IO();  
          nRF24L01_Initial();
          CE_Low;
          SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
         
  *P_INT_Mask |= C_IRQ4_1KHz;                                                        // 打开1KHz中断,接收资源
        __asm("int fiq,irq ");   
          
           while(1)
    {
    *P_Watchdog_Clear = 0x01;

                if((*P_IOA_Data&0x0001) == 1)                                        // Key1按下,录音并发送
                {
                        *P_INT_Mask &= ~C_IRQ4_1KHz;                                // 关闭1KHz中断,禁止接收语音资源
                TX_Mode();                                                        // nRF2401工作方式,发送

                        Queue_Init();                                                                // 初始化编解码队列       
                        SACM_DVR1600_Initial();                                                // DVR 初始化
                        SACM_DVR1600_Rec(0,1);                                                // 录音(12k编码)

                        while((*P_IOA_Data&0x0001) != 0)                        // Key1 一直按下
                        {
                                *P_Watchdog_Clear = 0x01;
                                SACM_DVR1600_ServiceLoop();                                // 编码
                                if(Queue_Test() != 0xffff)                                // 有数据?
                                {
                                        for(i=0; i<L_Fram; i++)
                                        {
                                                Tx_Buffer = Queue_Read();        // 读取编码数据
                                        }
                                //        nRF2401_SendBuffer_Word(SourceBuf,L_Fram);        // 发送数据
                                nRF24L01_TxPacket(Tx_Buffer);
                                }
                        }
                SACM_DVR1600_Stop();
                RX_Mode();                                                        // nRF2401工作方式,接收
                        *P_INT_Mask |= C_IRQ4_1KHz;                                        // 打开1KHz中断,接收语音资源
                }
                if(PlayFlag == 0xff)                                                        // 接收到数据
                {
                        Queue_Init();                                                                // 初始化编解码队列       
                        SACM_DVR1600_Initial();                                                // DVR 初始化
                        SACM_DVR1600_Play(0, DAC_1+DAC_2, RAMP_UP_DN);        // 放音,双声道,淡入淡出

                        while(PlayFlag == 0xff)
                        {
                                SACM_DVR1600_ServiceLoop();                                // 解码
                                *P_Watchdog_Clear = 0x01;
                        }
                        SACM_DVR1600_Stop();                                                // DVR停止
                }
   
    }
}

//====================================================================================
//语法格式:void IRQ4()__attribute((ISR))
//功能描述: 1KHz中断,用于接收语音资源数据
//入口参数: 无
//出口参数: 无
//====================================================================================
void IRQ4()__attribute((ISR));
void IRQ4()
{
        int i;
//        if((nRF24L01_RxPacket()) == 1)                                // 有数据请求
                if(nRF24L01_RxPacket(RX))
        {
                PlayFlag = 0xff;                                                // 置位语音播放标志
                Cnt = 0;
        //        SPI_Read_Buf(Tx_Buffer);                        // 读取资源
        //        {
                        if(Queue_Test() >= L_Fram)                        // 资源缓冲不满
                        {
                                for(i=0; i< L_Fram; i++)
                                {
                                        Queue_Write(Tx_Buffer);        // 填补缓冲
                                }
                        }
        //        }
        }
        else
        {
                Cnt++;
                if(Cnt >= 500)                                                        // 0.5s没有数据,结束语音播放
                {
                        PlayFlag = 0x00;
                        Cnt = 0;
                }
        }
        *P_INT_Clear = C_IRQ4_1KHz;       
}

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

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

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-3-29 07:55

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

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