|
用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周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|