两片单片机的无线传输用NRF905 接收端 发送端 程序分别怎么写 好困惑

两片单片机的无线传输用NRF905 接收端 发送端 程序分别怎么写 好困惑,第1张

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


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12529216.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存