NRF905的程序中只有nRF905Init()Config905()RX() 前两个初始化,后个传输函数,执行后在TRXBUF数组中会有相应的值。以下是接收的主函数,这是控制电机左右转动的程序。(小车部分)
void main(void)
{
nRF905Init()
Config905()
while(1)
{
RX()
if(TxRxBuf[0]==0x11){in1=1in2=0in5=1in6=0}//从左往右
if(TxRxBuf[1]==0x11){in3=1in4=0in7=1in8=0}//从右往左
if(TxRxBuf[0]==0x22){in1=1in2=1in5=1in6=1}//从左往右
if(TxRxBuf[1]==0x22){in3=1in4=1in7=1in8=1}//从右往左
in1=1in2=0
}
}
遥控部分:就俩按键 一个做转一个右转 这是无线遥控小车的遥控部分。
void main(void)
{
nRF905Init()
Config905()
while(1)
{
if(KEY0 ==0){TxRxBuf[0]=0x11}
if(KEY0 ==1){TxRxBuf[0]=0x22}
if(KEY1 ==0){TxRxBuf[1]=0x11}
if(KEY1 ==1){TxRxBuf[1]=0x22}
SetTxMode()// Set nRF905 in Tx mode
TxPacket(TxRxBuf)// Send data by nRF905
}
}
那么在设置上:就按以下设置:
#include <reg52.h>
#include <ABSACC.h>
#include <intrins.h>
#include <stdio.h>
//----------------------------------------------------------------------------------------------------------------
#define uint unsigned int
#define uchar unsigned char
//----------------------------------------------------------------------------------------------------------------
#define BYTE_BIT0 0x01
#define BYTE_BIT1 0x02
#define BYTE_BIT2 0x04
#define BYTE_BIT3 0x08
#define BYTE_BIT4 0x10
#define BYTE_BIT5 0x20
#define BYTE_BIT6 0x40
#define BYTE_BIT7 0x80
//----------------------------------------------------------------------------------------------------------------
bdata unsigned char DATA_BUF
#define DATA7 ((DATA_BUF&BYTE_BIT7) != 0)
#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0)
sbit flag =DATA_BUF^7
sbit flag1 =DATA_BUF^0
//---------------------------------------------------发送数据缓冲区-------------------------------------------------
#define TxRxBuf_Len 4
unsigned char TxRxBuf[TxRxBuf_Len]=
{
0x29,0x30,0x31,0x32,
}
//----------------------------------------------NRF905控制IO------------------------------------------------------
sbit TXEN=P1^0
sbit TRX_CE=P3^2
sbit PWR=P1^1
//----------------------------------------------NRF905 SPI接口---------------------------------------------------
sbit MISO=P1^6
sbit MOSI=P1^5
sbit SCK=P1^7
sbit CSN=P1^3
//----------------------------------------nrf905状态标志---------------------------------------------------------
sbit AM=P1^4
sbit DR=P3^3
sbit CD=P1^2
//---------------------------------------------------------------------------------------------------------------
sbit led3=P2^0
sbit led2=P2^1
sbit led1=P2^2
sbit led0=P2^3
//--------------------------------------------------------------------------------------------------------------
sbit KEY0=P3^6
sbit KEY1=P3^7
//--------------------------------------------------------------------------------
sbit BELL=P3^4
//-----------------------------------------------------------------------------------------------------------------
uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90} //0~~9段码
//-------------------------------------------------------nrf905控制指令-------------------------------------------
#define WC 0x00
#define RC 0x10
#define WTP 0x20
#define RTP 0x21
#define WTA 0x22
#define RTA 0x23
#define RRP 0x24
//------------------------------------------------NRF905寄存器配置------------------------------------------------
unsigned char idata RFConf[11]=
{
0x00, //配置命令//
0x4c, //CH_NO,配置频段在430MHZ
0x0c, //输出功率为10db,不重发,节电为正常模式
0x44, //地址宽度设置,为4字节
0x04,0x04, //接收发送有效数据长度为32字节
0xCC,0xCC,0xCC,0xCC, //接收地址
0x58, //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
}
code TxAddress[4]={0xcc,0xcc,0xcc,0xcc}
char tf
//------------------------------------------------延时------------------------------------------------------------
static void Delay(uchar n)
{
uint i
while(n--)
for(i=0i<80i++)
}
//---------------------------------------------------SPI读函数-----------------------------------------------------
unsigned char SpiRead(void)
{
unsigned char j
for (j=0j<8j++)
{
DATA_BUF=DATA_BUF<<1
SCK=1
if (MISO) //读取最高位,保存至最末尾,通过左移位完成整个字节
{
DATA_BUF|=BYTE_BIT0
}
else
{
DATA_BUF&=~BYTE_BIT0
}
SCK=0
}
return DATA_BUF
}
//-------------------------------------------------SPI写函数----------------------------------------------------------
void SpiWrite(unsigned char send)
{
unsigned char i
DATA_BUF=send
for (i=0i<8i++)
{
if (DATA7) //总是发送最高位
{
MOSI=1
}
else
{
MOSI=0
}
SCK=1
DATA_BUF=DATA_BUF<<1
SCK=0
}
}
//------------------------------------------------------初始化nRF905---------------------------------------------
void nRF905Init(void)
{
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
}
//-----------------------------------------------------初始化寄存器-----------------------------------------------
void Config905(void)
{
uchar i
CSN=0 // Spi enable for write a spi command
//SpiWrite(WC) // Write config command写放配置命令
for (i=0i<11i++) // Write configration words 写放配置字
{
SpiWrite(RFConf[i])
}
CSN=1 // Disable Spi
}
//-----------------------------------------------------发送数据打包---------------------------------------------------
void TxPacket(uchar *TxRxBuf)
{
uchar i
//Config905()
CSN=0
SpiWrite(WTP) // Write payload command
for (i=0i<4i++)
{
SpiWrite(TxRxBuf[i]) // Write 32 bytes Tx data
}// Spi enable for write a spi command
CSN=1
Delay(1) // Spi disable
CSN=0 // Spi enable for write a spi command
SpiWrite(WTA) // Write address command
for (i=0i<4i++) // Write 4 bytes address
{
SpiWrite(TxAddress[i])
}
CSN=1 // Spi disable
TRX_CE=1 // Set TRX_CE high,start Tx data transmission
Delay(1) // while (DR!=1)
TRX_CE=0 // Set TRX_CE low
}
//----------------------------------------------------------设置发送状态---------------------------------------------
void SetTxMode(void)
{
TRX_CE=0
TXEN=1
Delay(1) // delay for mode change(>=650us)
}
//-----------------------------------------------设置发送状态---------------------------------------------------
void SetRxMode(void)
{
TXEN=0
TRX_CE=1
Delay(1) // delay for mode change(>=650us)
}
//-------------------------------------------------判断数据接收状态-----------------------------------------------------
unsigned char CheckDR(void) //检查是否有新数据传入 Data Ready
{
if (DR=1&&TRX_CE==1 && TXEN==0)
{
// Delay(50)
return 1
}
else
{
return 0
}
}
//----------------------------------------------------读NRF905接收数据------------------------------------------------------------
void RxPacket(void)
{
uchar i
Delay(1)
// TRX_CE=0 // Set nRF905 in standby mode
Delay(100)
TRX_CE=0
CSN=0 // Spi enable for write a spi command
Delay(1)
SpiWrite(RRP)
for (i = 0 i < 4 i++)
{
TxRxBuf[i]=SpiRead() // Read data and save to buffer
}
CSN=1
Delay(10)
TRX_CE=1
}
//--------------------------------------------------------数据接收------------------------------------------------
void RX(void)
{
SetRxMode() // Set nRF905 in Rx mode
while (CheckDR()==0)
Delay(10)
RxPacket()
}
这些是子函数。只要把一些关于电机的sbit定义去掉,剩下的就是真正的子函数了。
那么,需注意的就只有nRF905Init()Config905()RX() SetTxMode()和一个TXbuf数组,把这几个用好了,程序就跳出来了。nRF905Init()Config905()收发都需要,SetTxMode()发送要,RX() 接收要。就是这样了,最起码我看是这样。
/******************************************************************************************\说明:看到网上好所人问51单片机+nRF905射频通信问题,所以将自己之前初学时写得测试代码贴出来,供初学者参考。
双工的,既能收也能发。可以通过按钮控制另一块板上的小灯亮灭(按住亮,松开灭), 也可将串口收到的数据通过无线方式发送出去,(发送1、2时也可控制LED灯亮),也可将收到的无线信号通过串口输出,
日期:2012年4月23日
硬件:单片机型号:STC89C52RC,晶振11.0592M,射频芯片通过10根导线与单片机IO口连接
射频芯片nRf905,模块自带天线长度约10cm,发射频率433M,频道1
其他外设:2个按键,2个led灯,一个串口
功能:用于测试nRF905,可通过串口发送接收,波特率9600,也可通过按键发送,led显示
核心函数:Init905() RxPacket() TxPacket()
/*******************************************************************************************/
//#include <reg9e5.h>
//#include "ISD51.h"
#include<reg52.h>
#include <intrins.h>
#include<stdlib.h>
#include<string.h>
#define INT8U unsigned char
#define INT16Uunsigned int
#defineTIMER10XFD//256-(110592/(12*32*96))
//*****************************************************************************
//寄存器宏定义
//*****************************************************************************
#define WRC 0x00 //W_RF_CONFIG
#define RRC 0x10 //R_RF_CONFIG
#define WTP 0x20 //W_TX_PAYLOAD
#define RTP 0x21 //R_TX_PAYLOAD
#define WTA 0x22 //W_TX_ADDRESS
#define RTA 0x23 //R_TX_ADDRESS
#define RRP 0x24 //R_RX_PAYLOAD
#define RAD 0x40 //R_ADC_DATA
#define WAC 0x44 //W_ADC_CONFIG
#define RAC 0x46 //R_ADC_CONFIG
#define WTU 0x50 //W_TEST_UNLOCK (use with data A5)
#define WTR 0x52 //W_TEST_REGISTER
#define RTR 0x53 //R_TEST_REGISTER
#define CC 0x80 //CHANNEL_CONFIG
#define SAV 0xC0 //START_ADC_CONV
#define HFREQ1 // 0=433MHz, 1=868/915MHz19/08/2004 set 915mhz
#define POWER3 // 0=min power...3 = max power
///////////////////////////////////////////////////////////////////////////////
#define RFLEN 32 //数据长度,最大32
INT8U data UartRecCnt=0 //串口接收计数
#define do_uart() if(UartRecCnt<RFLEN-1){TxBuf[UartRecCnt++]=SBUF} //串口中断处理宏
INT8U RxBuf[RFLEN]={0} //接收数据缓冲区
INT8U TxBuf[RFLEN]={0} //发送数据缓冲区
//********定义与9e5不一样******************************************************
//I/O口定义
//*****************************************************************************
sbit LED1 =P1^0
sbit LED2 =P1^1
sbit LED3= P1^2
sbit LED4= P1^3
sbit KEY1 =P1^6
sbit KEY2 =P1^7
/////////定义与9e5不一样//////////////////////////////////////////////////////
sbitTX_EN=P0^0
sbitTRX_CE=P0^1
sbitPOW_UP=P0^2
sbitCD=P0^3
sbitAM=P0^4
sbitDR=P0^5
sbitMISO=P0^6
sbitMOSI=P0^7
sbitSCK=P2^0
sbitCE_905=P2^1
//*****************************************************************************
//配置寄存器
//*****************************************************************************
code INT8U Nrf905Config[10] = {
0x28,//频道设置
//0x0e,//自动重发关,发送节电模式关,输出功率10dB,915MHZ
0x0c, //自动重发关,发送节电模式关,输出功率10dB,433MHZ
0x44,//收发地址都为4字节
RFLEN,//0x04,//接收数据长度,4字节
RFLEN,//0x04,//发送数据长度,4字节
0xe7,//4字节地址
0xe7,
0xe7,
0xe7,
//0xdf//CRC开,16位校验,16M晶振,外部时钟使能500KHZ输出
0x58//CRC开,8位校验,16M晶振,禁止外部时钟
}
///////////////////////////////////////////////////////////////////////////////
//*****************************************************************************
//函数名:void Delay(INT8U n)
//输入:时间
//输出:无
//功能描述:廷时100us
//*****************************************************************************
void Delay(INT8U n)
{
INT8U i
while(n--)
for(i=0i<40i++)//for(i=0i<35i++)
}
//***************************** 该函数与nRF9e5不同 ****************************
//函数名:INT8U SpiReadWrite(INT8U b)
//输入:发送的数据
//输出:收到的数据
//功能描述:SPI发送接收一个字节
//*****************************************************************************
INT8U SpiReadWrite(INT8U dat)
{
INT8U i,temp
temp = 0
SCK = 0
for(i=0i<8i++)
{
if(dat &0x80)
{
MOSI = 1
}
else MOSI = 0
dat <<= 1
SCK = 1
_nop_()
_nop_()
temp <<= 1
if(MISO)temp++
SCK = 0
_nop_()
_nop_()
}
return temp
}
//***************************** 该函数与nRF9e5不同 ****************************
//函数名:void InitCpu(void)
//输入:无
//输出:无
//功能描述:Cpu初始化
//*****************************************************************************
void InitCpu(void)
{
LED2=0
LED1=0
Delay(10)
}
//***************************** 该函数与nRF9e5不同 ****************************
//函数名:InitUart(void)
//输入:无
//输出:无
//功能描述:串口初始化
//*****************************************************************************
void InitUart(void)
{
SCON = 0x50 //串口方式1,允许接收
TMOD = 0x21 //定时器1工作方式2,定时器0工作方式1
TH1 = TIMER1
TL1 = TIMER1
TR1 = 1 //启动定时器1
ES = 1
EA = 1
}
//*****************************************************************************
//函数名:void SendCh(INT8U c)
//输入:发送的数据
//输出:无
//功能描述:发送一个字节
//*****************************************************************************
void SendCh(INT8U c)
{
//EA = 0
//TI = 0
SBUF = c
while(!TI)//等待发送完成
TI = 0
//EA = 1
}
/*******************************************************************************************/
//发送字符串到串口
void SendStr(INT8U *p)
{
while(*p!='\0')
{ SBUF=*p //待发送的数据写入缓冲区
while(!TI) //等待发送完成
TI=0//清零发送标志位
p++ //指针加1
}
}
/*****************************************************************************
//函数名:void Init905(void)
//输入:无
//输出:无
//功能描述:Nrf905初始化,这里我们配置成32位地址。
//******************************************************************************/
void Init905(void)
{
INT8U i
POW_UP = 1 //905上电
//Delay(200)
SCK = 0 // Spi clock line init high
TRX_CE=0
TX_EN=0 //配置模式
CE_905 = 0
SpiReadWrite(WRC)
for(i=0i<10i++)
{
SpiReadWrite(Nrf905Config[i])//写入配置寄存器
}
CE_905 = 1
}
//*****************************************************************************
//函数名:TransmitPacket(INT8U *pBuf)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
//*****************************************************************************
void TransmitPacket(INT8U *pBuf)
{
INT8U i
CE_905 = 0
SpiReadWrite(WTP)
for(i=0i<Nrf905Config[4]i++)
{
SpiReadWrite(pBuf[i])//写入发送数据缓冲区
}
CE_905 = 1
TX_EN = 1
TRX_CE = 1 //使能发送
Delay(1)
TRX_CE = 0
}
//*****************************************************************************
//函数名:INT8U Recepacket(INT8U *pBuf)
//输入:接收数据缓冲区
//输出:成功返回1,否则返回0
//功能描述:接收数据存在缓冲区内
//*****************************************************************************
INT8U Recepacket(INT8U *pBuf)
{
INT8U i
TX_EN = 0TRX_CE = 1 //进入接收模式
if(!DR)return 0 //查询DR的状态
//原始代码采用的是等待超时的方法
/*ResetTimer(1)//复位超时计数器。
while(DR == 0)//有收到切换到空闲状态时退出接收状态。
{
if(ReadTimer(1) >300)//300MS超时退出。
{
TRX_CE = 0
return 0
}
}*/
TRX_CE = 0 // Set nRF905 in standby mode
CE_905 = 0 // Spi enable for write a spi command
SpiReadWrite(RRP)// Read payload command
for(i=0i<Nrf905Config[3]i++)//读出数据。
{
pBuf[i] = SpiReadWrite(0)
}
while(DR)//直到DR为高。
/*{
SpiReadWrite(0)
}*/
CE_905 = 1
return 1
}
/*串口接收中断函数*/
void int_rec(void) interrupt 4 using 2
{
if(RI) //查询接收标志位(有数据发送过来时置为1)
{
RI = 0 //接收标志位清零
//SendCh(SBUF)//让从电脑上传到单片机的数据,传回的电脑显示
do_uart()//对接受到得字符 *** 作
}
}
/************************************************************************/
//功能:把串口接收的数据通过无线发射出去
//采取延时读取串口接收计数的方法,判读串口发送数据是否完毕,提高发送效率
void UartToRf(void )
{
INT8U Tmp=0//临时变量,暂存UartRecCnt
do
{
Tmp=UartRecCnt
Delay(5) //延时,等待
}
while(Tmp!=UartRecCnt)//判段来自串口的字符串是否发送完毕
TransmitPacket(TxBuf) //通过射频发送
memset(TxBuf,0,UartRecCnt) //清空缓冲区
UartRecCnt=0//串口接受计数清零
}
//载波监听发送,重试3次,仍失败不发送
unsigned char CDSend(void)
{
unsigned char i=0
do
{
if(!CD) //载波监听
{
TransmitPacket(TxBuf)//发送数据
return 0 //发送成功,返回0
}
SendCh(0x30+i)
Delay(rand()&0x0f)//随机延时
LED3=~LED3
}while(++i<3) //最多3次
SendStr("fail")
return 1 //发送失败,返回1
}
/***********************主程序*************************************************/
main()
{
Init905() //初始化Nrf905
InitCpu() //初始化CPU
//InitTimer()
InitUart() //初始化串口。
LED2 = 1
LED1 = 1 //两个LED灭。
//SendCh('R')
while(1)
{
LED2=1 LED1=1
if(KEY1 == 0)//按键1按下
{
TxBuf[0] = 0x31
//TransmitPacket(TxBuf)//发送数据
CDSend()
}
if(KEY2 == 0)//按键2按下
{
TxBuf[0] = 0x32
//TransmitPacket(TxBuf)//发送数据
CDSend()
}
if(Recepacket(RxBuf))//接收到数据。
{
if(RxBuf[0] == 0x31)
{
LED1 = 0
Delay(5)
}
else if(RxBuf[0] == 0x32)
{
LED2 = 0
Delay(5)
}
SendStr(RxBuf) //将从无线收到的数据发到串口
}
if(UartRecCnt) //串口收到数据时相应处理
{
/*Delay(2*RFLEN) //延时,等待字符串发送完毕.时间过短的话会出现串口数据未发完,缓冲区已情况的情况
TransmitPacket(TxBuf) //通过射频发送
memset(TxBuf,0,UartRecCnt) //清空缓冲区
UartRecCnt=0//串口接受计数清零
*/
UartToRf() //新编发送函数
}
}
}
//end
#include <reg51.h>#include <intrins.h>
#include <nrf905.h>
#define uint8 unsigned char
#define uint16 unsigned char
uint8 tout[2]={0x00,0x00}//1发送指示,2接受指示
uint8 txbuf[4]={0x00,0x00,0x00,0x00}
uint8 databuf
sbit LEDR=P1^0
sbit LEDT=P1^1
uint8 nrfcfg[10]={
0x4c, //频道设置
0x0c, //自动重发开,发送节电模式关,输出功率为10mw,915Mhz
0x44, //收发数据长度都为4个字节
0x0d, //接收数据长度8个字节
0x04, //发送数据长度为8个字节
0xe7,
0xe7,
0xe7,
0xe7,
0x58, //crc开,8位效验,16M晶振
}void dly100us(uint8 n){ //delay 100us
uint8 i
while(n--)
for(i=0i<35i++)
}
uint8 spiwr(uint8 rwchr){
uint8 i
for(i=0i<8i++){
rwchr<<=1
MOSI=CY
_nop_()
CY=MISO
SCK=1
rwchr|=CY
SCK=0
}
return rwchr}void uart_timer_init(void){
SCON=0x50
TMOD=0x21
TH0=0xb1
TL0=0xe0
TH1=0xfd
TL1=0xfd
PCON=0x80
TR1=1
TR0=1
ET0=1
ES=1
// PS=1
EA=1
}
void send_char(uint8 xyz){
ET0=0
SBUF=xyz
while(TI==0)
TI=0
ET0=1
}void comrece(void) interrupt 4 using 3{
if(RI){
RI=0
txbuf[0]=SBUF
}
} void timer1(void) interrupt 1 using 0{
EA=0
TH0=0xb1
TL0=0xe0
tout[0]++
tout[1]++
if(tout[0]==5)
LEDR=1
if(tout[1]==5)
LEDT=1
EA=1
}void initnrf(void){//初始化nrf905配置
uint8 i
TRX_E=0
TX_E=0
CSN=0
spiwr(WC)
for(i=0i<10i++)
spiwr(nrfcfg[i])
CSN=1
TRX_E=1//允许接受数据
TX_E=0
dly100us(10)
}void txdata(uint8 *txbuf){ //写入发送有效数据,并启动发送
uint8 i
LEDT=0
tout[1]=0
CSN=0
spiwr(WTA)
for(i=5i<9i++) //写入发送的地址
spiwr(nrfcfg[i])
CSN=1
_nop_()
_nop_()
CSN=0
spiwr(WTP) //写入发送的数据
for(i=0i<4i++)
spiwr(txbuf[i])
CSN=1
TRX_E=1
TX_E=1
dly100us(10)
TX_E=0
} void rxdata(uint8 *rxbuf){ //读出接受缓冲区的内容
uint8 i
TRX_E=0 //读数据时退出接收/发射状态
LEDR=0
tout[0]=0
CSN=0
spiwr(RRP)
for(i=0i<13i++) //读出接受的数据
rxbuf[i]=spiwr(0)
while(DR)
_nop_()
CSN=1
TRX_E=1
TX_E=1
dly100us(10)
txdata(txbuf)}void main(void){
uint8 i
uint8 rxbuf[13]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
PWR_UP=1
initnrf()
uart_timer_init()
while(1){ while(DR)
{
rxdata(rxbuf)
for(i=0i<13i++)
send_char(rxbuf[i])
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)