微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > 基于凌阳单片机的无线采集系统(发射模块为NFR905)

基于凌阳单片机的无线采集系统(发射模块为NFR905)

时间:10-02 整理:3721RD 点击:
//这是发射主程序,请大神帮忙检查下,我们接收不到数据
#include <SPCE061A.h>
#include "weicaozuo.h"
//----------------------------------------------------------------------------------------------------------------
#define uint unsigned int
#define uchar unsigned char
//----------------------------------------------------------------------------------------------------------------
#define BYTE_BIT0 0x01
#define BYTE_BIT7 0x80
//----------------------------------------------------------------------------------------------------------------
unsigned char DATA_BUF; //16位
#define DATA7 ((DATA_BUF&BYTE_BIT7) != 0)
#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0)
//---------------------------------------------------发送数据缓冲区-------------------------------------------------
#define TxRxBuf_Len 2
unsigned char TxRxBuf[TxRxBuf_Len];
/***********************************************端口定义************************************************************************
//----------------------------------------NRF905 数据交换端口---------------------------------------------------
bit CSN=PB_0;
bit MOSI=PB_1;
bit MISO=PB_2;
bit SCK=PB_3;

//----------------------------------------NRF905工作模式控制端口------------------------------------------------------
bit PWR=PB_4;
bit TRX_CE=PB_5;
bit TXEN=PB_6;

//----------------------------------------nrf905状态端口---------------------------------------------------------
bit AM=PB_7;
bit DR=PB_8;
bit CD=PB_9;

********************************************************************************************************************/

//----------------------------------------nrf905控制指令-------------------------------------------
#define WC 0x00 // 写配置寄存器(RF-Configuration Register)
#define RC 0x10 // 读配置寄存器(RF-Configuration Register)
#define WTP 0x20 // 向TX-Payload寄存器写入发送有效数据
#define RTP 0x21 // 从TX-Payload寄存器读取发送有效数据
#define WTA 0x22 // 向TX-Address寄存器写入发送地址
#define RTA 0x23 // 从TX-Address寄存器读取发送地址
#define RRP 0x24 // 从RX-Payload寄存器读取接收到的有效数据

//------------------------------------------------NRF905寄存器配置------------------------------------------------
typedef struct RFConf
{
uchar n;
uchar buf[10];
}RFConf;
RFConf RxTxConf=
{
10,
0x4c,0x0c,0x44,0x02,0x02,0xCC,0xCC,0xCC,0xCC,0x58
};
//配置命令
//CH_NO,配置频段在430MHZ
//输出功率为10db,不重发,节电为正常模式
//地址宽度设置,为4字节
//接收发送有效数据长度为2字节
//接收地址
//CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
//================================================延时===========================================================
void Delay(unsigned int n)
{
uint i;
for(i=0;i<n;i++)
{
*P_Watchdog_Clear=0x0001; //清狗
}
}
//=================================================SPI读函数=======================================================
uchar SpiRead(void)
{
uchar j;
for (j=0;j<8;j++) //循环8次发送一个字节的数据
{
DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
SCK=1;
if (MISO) //读取最高位,保存至最末尾,通过左移位完成整个字节
{
DATA_BUF|=BYTE_BIT0; //最低位写1
}
else
{
DATA_BUF&=BYTE_BIT0; //最低位写0
}
SCK=0;
}
return DATA_BUF;
}
//===========================================SPI写函数===============================================================
void SpiWrite(unsigned char send)
{
unsigned char i;
DATA_BUF=send; //将需要发送的数据写入缓存
for (i=0;i<8;i++) //循环8次发送一个字节的数据
{
if (DATA7) //总是发送最高位
{
MOSI=1;
}
else
{
MOSI=0;
}
SCK=1;
DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
SCK=0;
}
}

//------------------------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
*P_IOB_Dir = 0x007B;
*P_IOB_Attrib = 0x03ff;
*P_IOB_Data=0xffff;
CSN=1; // Spi disable
SCK=0; // Spi clock line init low
DR=0; // Init DR for input
AM=0; // Init AM for input
CD=0; // Init CD for input
PWR=1; // nRF905 power on
TRX_CE=0; // Set nRF905 in standby mode
TXEN=0; // set radio in Rx mode

}

//-------------------------------------主机通过SPI接口向905配置寄存器写入信息-------------------------------------------------
void Config905(void)
{
uchar i;
CSN=0; // SPI使能输入
SpiWrite(WC); // 写配置字命令
for (i=0;i<RxTxConf.n;i++) // 循环写配置字
{
SpiWrite(RxTxConf.buf[i]); //RxTxConf保存预先设置好的配置信息
}
CSN=1; // 结束SPI数据输入
}
//-----------------------------------------------------发送数据打包---------------------------------------------------
void TxPacket(uchar *TxRxBuf)
{
uchar i;
CSN=0; //SPI使能,准备写入数据信息
SpiWrite(WTP); // Write payload command
for (i=0;i<2;i++)
{
SpiWrite(TxRxBuf[i]); // 写入2字节发送数据
}
CSN=1; //关闭SPI,保存写入的数据
Delay(10);
CSN=0; // SPI使能,准备写入地址信息
SpiWrite(WTA); // Write address command
for (i=0;i<4;i++) // 写入与对方地址一样的地址
{
SpiWrite(RxTxConf.buf[i+5]);
}
CSN=1; // 关闭SPI
TRX_CE=1; // 进入发送模式,启动射频发送
Delay(10); // 进入ShockBurst发送模式后,芯片保证数据发送完成后返回STANDBY模式z
TRX_CE=0; // 关闭发送开关
}
//----------------------------------------------设置发送状态---------------------------------------------
void SetTxMode(void)
{
TRX_CE=0;
TXEN=1;
Delay(6000); // nrf905_Delay for mode change(>=650us)
}

extern void F_AD_Initial(void);
extern unsigned int F_ReadAD(unsigned int);
unsigned int uiCircleChannelNumber=1;
int main()
{
nRF905Init();
Config905();
F_AD_Initial();
uiCircleChannelNumber=1;

while(1)
{
for(uiCircleChannelNumber=1;uiCircleChannelNumber<4;uiCircleChannelNumber++)
{
TxRxBuf[0]=(F_ReadAD(uiCircleChannelNumber)&0x00ff);//采集通道数据
TxRxBuf[1]=((F_ReadAD(uiCircleChannelNumber)&0xff00)>>8);
TxPacket(TxRxBuf); //发送数据打包
SetTxMode(); //设置发送初始状态

}
if(uiCircleChannelNumber==4)
{
uiCircleChannelNumber=1;
}



}

}

//这是AD转换子程序
//*************************************************************

// 时钟源为Fosc/8,采样率为8KHz
.include SPCE061A.inc
.CODE
.public _F_AD_Initial;
_F_AD_Initial: .PROC
PUSH r1,r1 TO [sp];
R1 = 0x0001 //允许A/D
[P_ADC_Ctrl] = R1

r1=0x0000; //通过读P_ADC触发ADC自动转换
[P_DAC_Ctrl] = r1;

r1 = 0x0001 //LINE1输入
[P_ADC_MUX_Ctrl] = r1;

POP r1,r1 FROM [sp];
RETF
.ENDP


//************** A/D 转换程序 **********************//
.public _F_ReadAD
_F_ReadAD: .PROC
PUSH r2,r5 TO [sp];
BP=SP+1;
r1 = [BP+6];
[P_ADC_MUX_Ctrl] = r1;//设置通道号
r1=0x0001;
[P_Watchdog_Clear]=r1;
r2=16 //进行4次转换
r3=0
L_SampleLoop:
r1=[P_ADC_MUX_Data] //读[P_ADC_MUX_Data],启动一次AD转换
r1=0x8000
L_VoltageConverLoop:
TEST r1,[P_ADC_MUX_Ctrl]
JZ L_VoltageConverLoop;
r1=[P_ADC_MUX_Data] //AD转换值
r1=r1 LSR 4 //将AD值移到低10位
r1=r1 LSR 2
r3+=r1 //四次A/D值累加
r2-=1
jnz L_SampleLoop
r3=r3 LSR 4 //结果除以4,求4次的平均值
r1=r3 //返回结果

POP r2,r5 FROM [sp];
RETF
.ENDP



//接收端程序
#include <SPCE061A.h>
#include "weicaozuo.h"
//----------------------------------------------------------------------------------------------------------------
#define uint unsigned int
#define uchar unsigned char
//----------------------------------------------------------------------------------------------------------------
#define BYTE_BIT0 0x01
#define BYTE_BIT7 0x80
//----------------------------------------------------------------------------------------------------------------
unsigned char DATA_BUF;
#define DATA7 ((DATA_BUF&BYTE_BIT7) != 0)
#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0)
//---------------------------------------------------接收数据缓冲区-------------------------------------------------
#define TxRxBuf_Len 2
unsigned char TxRxBuf[TxRxBuf_Len]={0x00,0x00};
/***********************************************端口定义************************************************************************
//----------------------------------------NRF905 数据交换端口---------------------------------------------------
bit CSN=PA_0;
bit MOSI=PA_1;
bit MISO=PA_2;
bit SCK=PA_3;

//----------------------------------------NRF905工作模式控制端口------------------------------------------------------
bit PWR=PA_4;
bit TRX_CE=PA_5;
bit TXEN=PA_6;

//----------------------------------------nrf905状态端口---------------------------------------------------------
bit AM=PA_7;
bit DR=PA_8;
bit CD=PA_9;

********************************************************************************************************************/
//----------------------------------------nrf905控制指令-------------------------------------------
#define WC 0x00
#define RC 0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
//------------------------------------------------NRF905寄存器配置------------------------------------------------
typedef struct RFConf
{
uchar n;
uchar buf[10];
}RFConf;
RFConf RxTxConf=
{
10, //配置命令//
0x4c, //CH_NO,配置频段在430MHZ
0x0c, //输出功率为10db,不重发,节电为正常模式
0x44, //地址宽度设置,为4字节
0x02,0x02, //接收发送有效数据长度为2字节
0xCC,0xCC,0xCC,0xCC, //接收地址
0x58 //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
};
//================================================延时===========================================================
void Delay(unsigned int n)
{
uint i;
for(i=0;i<n;i++)
{
*P_Watchdog_Clear=0x0001; //清狗
}
}
//=================================================SPI读函数=======================================================
uchar SpiRead(void)
{
uchar j;
for (j=0;j<8;j++) //循环8次发送一个字节的数据
{
DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
SCK=1;
if (MISO) //读取最高位,保存至最末尾,通过左移位完成整个字节
{
DATA_BUF|=BYTE_BIT0; //最低位写1
}
else
{
DATA_BUF&=BYTE_BIT0; //最低位写0
}
SCK=0;
}
return DATA_BUF;
}
//===========================================SPI写函数===============================================================
void SpiWrite(unsigned char send)
{
unsigned char i;
DATA_BUF=send; //将需要发送的数据写入缓存
for (i=0;i<8;i++) //循环8次发送一个字节的数据
{
if (DATA7) //总是发送最高位
{
MOSI=1;
}
else
{
MOSI=0;
}
SCK=1;
DATA_BUF=DATA_BUF<<1; //左移一位,准备下一位数据
SCK=0;
}
}
//------------------------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
*P_IOA_Dir = 0x007B;
*P_IOA_Attrib = 0x03ff;
CSN=1; // Spi disable
SCK=0; // Spi clock line init low
DR=1; // Init DR for input
AM=0; // Init AM for input
CD=0; // Init CD for input
PWR=1; // nRF905 power on
TRX_CE=0; // Set nRF905 in standby mode
TXEN=0; // set radio in Rx mode
}
//--------------------------------------------------主机通过SPI接口向905配置寄存器写入信息-----------------------------------------------
void Config905(void)
{
uchar i;
CSN=0; // SPI使能输入
SpiWrite(WC); // 写配置字命令
for (i=0;i<RxTxConf.n;i++) // 循环写配置字
{
SpiWrite(RxTxConf.buf[i]); //RxTxConf保存预先设置好的配置信息
}
CSN=1; // 结束SPI数据输入
}
//-----------------------------------------------设置接收初始化---------------------------------------------------
void SetRxMode(void)
{
TXEN=0;
TRX_CE=1;
Delay(6000); // nrf905_Delay for mode change(>=650us)
}

//----------------------------------------------------读NRF905接收数据------------------------------------------------------------
void RxPacket(void)
{
uchar i;
TRX_CE=0; // 设置 nRF905 进入待机模式
CSN=0; // 使能SPI
SpiWrite(RRP);
for (i = 0 ;i < 2 ;i++)
{
TxRxBuf[i]=SpiRead(); // 通过SPI接口从905芯片读取数据保存到Buf中
}
CSN=1;
Delay(10);
while(DR||AM);
TRX_CE=1;

}

extern void F_UART_Initial(void);
extern void F_UART_WriteByteData(unsigned int uiVoltageValue);
//-----------------------------------------------------------------------------------------------------------------
void main(void)
{

F_UART_Initial();
nRF905Init();
Config905();
// SetRxMode();
// RxPacket();
while(1)
{

SetRxMode();
RxPacket();
//分两次发送一个通道的电压值。
F_UART_WriteByteData(TxRxBuf[0]);//发送低8bit
Delay(1000);
F_UART_WriteByteData(TxRxBuf[1]);//发送高2bit
}


}

//串口通信程序
//========================================================================================================//
.include SPCE061A.inc
.CODE

//========================================================================================================
//函数: F_UART_Initial
//语法:void F_UART_Initial()
//描述:初始化UART
//参数:无
//返回:无
//========================================================================================================

.PUBLIC _F_UART_Initial;
_F_UART_Initial:
INT OFF;
r1 = 0x0000; //未使能任何中断
[P_INT_Ctrl] = r1;
r1 = 0x0480; //设置IOB7为输入IOB10为输出
[P_IOB_Attrib] = r1;
R1 = 0x0400;
[P_IOB_Dir] = R1;
R1 = 0x0000;
[P_IOB_Data] = R1;

R1 = 0x0000; //设置波特率为9600bps
[P_UART_BaudScalarLow] = R1;
R1 = 0x0005;
[P_UART_BaudScalarHigh] = R1;


R1 = 0x0080;
[P_UART_Command1] = R1;
R4 = 0x00C0; //使能输入和输出
[P_UART_Command2] = R4;
IRQ ON
RETF

//========================================================================================================
//函数: F_UART_Write
//语法:void F_UART_Write(unsigned int)
//描述:写UART
//参数:为要写入串口的值,其低8bit为有效值。
//返回:无
//========================================================================================================
.PUBLIC _F_UART_WriteByteData
_F_UART_WriteByteData:
PUSH r1,r5 TO [sp]
bp=sp+1;
r1=[bp+7];//command value
r4=0xFFFF;
L_Check_TxRDY:
r3=0x0001;
[P_Watchdog_Clear]=r3;
r4-=1;
JZ L_UART_Write_Timeout;
r2 = [P_UART_Command2];
r2 &= 0x0040; //检测输出是否READY
JZ L_Check_TxRDY;
[P_UART_Data] = r1;//send data
L_UART_Write_Timeout:
POP r1,r5 FROM [SP]
RETF;

谢谢大神,请多指教!

哪位前辈懂的,跪求指教啊,急急急,十万火急

这咋办,收不到不一定是发的问题,也可能是收的问题,你得确认一下啊。收发调试是比较麻烦。仔细查一下无线模块的资料。有没有发送成功的标志先判断一下。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top