lkz03022011 发表于 2011-9-20 17:13:35

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

用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;                                                                // 资源缓冲数组,用于收发


#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_WIDTH20                // 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_RETR0x04                  // '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_TX0x08                                 // 'Observe TX' register address
#define CD          0x09                                                 //'Carrier Detect' register address
#define RX_ADDR_P00x0A                                       // 'RX address pipe0' register address
#define RX_ADDR_P10x0B                                 // 'RX address pipe1' register address
#define RX_ADDR_P20x0C                                 // 'RX address pipe2' register address
#define RX_ADDR_P30x0D                                 // 'RX address pipe3' register address
#define RX_ADDR_P40x0E                                 // 'RX address pipe4' register address
#define RX_ADDR_P50x0F                                  // '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={"0","3","4","5","8"};

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

unsigned charSPI_ReceiveData;
unsigned char RX;

unsigned char Tx_Buffer;//={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 registerand 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=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;       
}

lkz03022011 发表于 2011-9-23 16:08:49

点击此处下载 ourdev_678971COMEPJ.rar(文件大小:111K) (原文件名:WirelessCom.rar)
页: [1]
查看完整版本: 原程序是用nrf2401A做语音通信的 现在想改用NRF24L01