⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf24e1v1.c

📁 基于无线单片机24e1的组网程序。在无线传感器之类的应用中的成功案例。
💻 C
字号:
//========================================================
//深圳奥特迅电力设备有限公司
//电池监控系统用无线传输模块
//文件名:RF24E1.C
//描述:无线收发模块处理,无线子系统的初始化配置;spi操作;
//无线收发操作;子系统工作在shockburst接收模式下
//收到无线数据,LED指示
//喂狗操作
//By:Andylee 2006-6-13
//anssett@163.com
//程序编译时,必须设置好XRAM的起始地址和大小,否则有可能程序不可运行!!!
//2006-6-26开始
//2006-8-14修改完善
//=========================================================
#include "Main.h"
#include "Setting.h"
#include "crc.h"

#include <BATTERY.H>

extern bit jz_req;
extern bit jz_over;
extern bit adc_monitor;
extern bit addrSet;
extern bit addrEcho;
extern bit HostCfg;
extern unsigned  char idata inCnt;
extern unsigned  char idata inBuf[9];
unsigned int idata t_1s;
unsigned int idata t_500ms;
unsigned int idata  RunADC;
unsigned  int idata ChxBZ[4];		//通道x的标准输入
unsigned  int idata ChInx_SC[4];		//保存校正时通道x的实际采样值
//#define addr_jz 0xf0;				//保存校正参数的首地址0xff0
//#define addrRfaddr 0xe7;			//保存无线通讯地址的e2rom地址(fe7~fea:本机地址;feb~fee:主站地址)
unsigned int OneSCnt;				//每个通道采样16次,做平滑均值滤波处理
unsigned int xdata  ADC_LIST[4][32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
									0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
									0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
									0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned long xdata ADC_SUM[4]={0,0,0,0};		//四个通道的16次采样值的累加和
unsigned char idata ADC_Cnt;					//采样计数器
unsigned int idata adcResult_list[4]={0,0,0,0};//保存最终采样值
unsigned int idata rFtxBuf[4]={0,0,0,0};
unsigned int idata Vcc;
unsigned long idata Vcc_Sum;
unsigned int data Vcc_list[16];
sbit P04=P0^4;						//备用
sbit WP=P0^3;
sbit Clr_Dog=P0^5;					//喂狗用
sbit Led_Show=P0^6; 				//LED点灯
sbit e2rom_cs=P0^0;					//外部e2rom的偏选
Set idata Setting;
/*unsigned char code RxTxConfig[] = {
    RF_DATA_LENGTH * 8, RF_DATA_LENGTH * 8,	 	//信道2和1的数据长(单位为位)
	0x00, 0x00, 0x00, 0x00, 0x00, 				//信道2的地址(如没有5字节长,则较低的位为有效位,下同)
	0xaa, 0xbb, 0x12, 0x34, 0x83,  				//信道1的地址
												//地址的位数(B0100_00xx),
												//CRC位数(16位Bxxxx_xx1x,8位Bxxxx_xx0x,CRC允许(Bxxxx_xxx0,0禁止,1允许)
	B1000_0001,//------------------------------------------------------------------------------------------------------------

							//位7,RX2_EN,为0只有信道1接收,为1允许2个信道同时接收
							//位6,CM,通讯方式,0:direct mode,1:ShockBurst mode,24e1只能为1
							//位5,RF DATA RATE,0:250Kbps,1:1Mbps,250Kbps时可提高接收灵敏度10dbm,1Mbps时要求16M晶体
							//位4,3,2,晶体频率,为该值+1再*4,如为2,则为12M晶体,3 ,16M
							//位1,0:发射功率:00:-20,	01:-10 10:-5 11:0dbm	 
	B0100_1111,//------------------------------------------------------------------------------------------------------------ 	 				
							//B0110_1111,1信道接收,shockBurst方式 ,1Mbps,16Mhz,0 DBm
							//B1111_111x,表示频率, 实际频率为2400+(B1111_111x >> 1)
							//位0,RX_EN,为0发送,为1接收
	B0000_0100,	 			//2402Mhz,接收方式	 (最后一位 RX_EN 为1表接收方式)
};							//这里设定为发射模式
*/
struct RFConfig
{
    unsigned char n;
    unsigned char buf[15];
};

typedef struct RFConfig RFConfig;

#define ADDR_INDEX  8   // Index to address bytes in RFConfig.buf 
#define ADDR_COUNT  4   // Number of address bytes

RFConfig xdata tconf =	//定义在xram是因为buf[15]中的地址段可能要动态修改。
{
    15,
    8, 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xaa, 0xbb, 0x12, 0x34, 0x81, 0x4f, 0x04
};

RFConfig xdata rconf =	//定义在xram是因为buf[15]中的地址段可能要动态修改。
{
    15,
    8, 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xaa, 0xbb, 0x12, 0x34, 0x81, 0x4f, 0x05
};

//================================================================
//函数功能:100us软件延时程序
//filename:Delay100us()
//input:
//output:none
//================================================================
void Delay100us(unsigned char n)
{
    	unsigned char i;
    	while(n--)
        for(i=0;i<35;i++)
            ;
}
//================================================================
//函数功能:毫秒软件延时程序
//filename:Delay100us()
//input:
//output:none
//================================================================

void Delayms(unsigned char n)
{
    unsigned char j;
    while(n--)
        for(j=0;j<10;j++)
	    	Delay100us(10);

}
//================================================================
//函数功能:片内SPI接口操作
//filename:fSpiRdWr()
//input:char 读操作,输入参数0
//output:none
//================================================================
uchar SpiReadWrite(uchar dat){
	EXIF &= ~0x20;                          		// Clear SPI interrupt
   	SPI_DATA = dat;                           		// Move byte to send to SPI data register
    	while((EXIF & 0x20) == 0x00);            	// Wait until SPI hs finished transmitting
    	return SPI_DATA;
}
//================================================================
//函数功能:将无线子系统设置为接收模式
//on the spec.page26:
//If nFRF2401 subsystem is to be configured for 2 channel RX in ShockBuust
//a total of 120 bits must be shifted in during the first configuration after VDD is 
//applied.Once the wanted protocol,modus and RF channed are set ,only one bit(RXEN) is 
//shifted in to switch between RX and TX.So this function can do that like it.
//On the spec.page28
//After VDD is turned on shockburst configureation is done once and remains set whilst VDD is 
//present.during operation only the first byte for frequecy channel and Rx/Tx switch need
//to be changed!
//We can be so lasy!!
//filename:SetRxMode()
//input:none
//output:none
//================================================================
static void SetRxMode(void)
{
    	CE = 0;
    	CS = 1;
    	Delay100us(0);
    	SpiReadWrite(rconf.buf[14]);
    	CS = 0;
}
//================================================================
//函数功能:将无线子系统设置为发射模式
//filename:SetRxMode()
//input:none
//output:none
//================================================================

static void SetTxMode(void)
{
    	CE = 0;
    	CS = 1;
    	Delay100us(0);
    	SpiReadWrite(tconf.buf[14]);
    	CS = 0;
}
//================================================================
//函数功能:将无线子系统初始化
//filename:SetRxMode()
//input:none
//output:none
//================================================================
void fRfInit(void){
	uchar b;
    PWR_UP = 1;                     	// Turn on Radio
    Delay100us(30);                 	// Wait > 3ms 
    SPICLK = 0;                     	// Max SPI clock (XTAL/8)
    SPI_CTRL = 0x02;                	// Connect internal SPI controller to Radio
   	CS = 1;                     		// RF SPI CS = 1,进行配置
	Delay100us(0);
    for(b=0;b<rconf.n;b++)				//初始化位接收状态
    {
        SpiReadWrite(rconf.buf[b]);
    }
    CS = 0;	  							//退出配置状态
	Delay100us(0);
	CE = 1;								//启动接收
}

//================================================================
//函数功能:发射一数据包(8个字节的采样值)
//filename:TransmitPacket()
//input:
//output:none
//2006-8-17:修改内容:先校正后再发送,
//            修改前:逐个校正逐个发送
//2006-8-18:加形参,为零校正发射,为1不校正,因为这时上位机控制(在系统校正)
//2006-8-31:去掉形参,不考虑在系统校正,没事做
//2006-9-05:增加无线发送缓冲区,以免采样缓冲区被这个函数修改(问题很严重)
//================================================================

void TransmitPacket(void)
{
    unsigned char i;
    
	for(i=0;i<4;i++)
		rFtxBuf[i]=Calibration(i);

    CE = 1;
    Delay100us(0);
	for(i=0;i<ADDR_COUNT;i++)
    		SpiReadWrite(tconf.buf[ADDR_INDEX+i]);	//写目标地址

	for(i=0;i<4;i++)
	{	
    SpiReadWrite((unsigned char)(rFtxBuf[i]>>8));//写数据(8字节)
	SpiReadWrite((unsigned char)(rFtxBuf[i]&0xff));    
	}
	CE = 0;
    Delay100us(3);                  	  	// Wait ~300us   
}
/*****************************************************************************************
//函数名:RxCmd()
//输入:none
//输出:输出接收到的一个字节
//功能描述:接收主站命令
/*****************************************************************************************/
unsigned char  RxCmd(void)
{
    unsigned char b;
   /* CE = 1;
    while(DR1 == 0);
	while(DR1)
	{*/
    b = SpiReadWrite(0);
	return b;
 	//CE = 0;

}
/*****************************************************************************************
//函数名:SendC()
//输入:发送的数据
//输出:无
//功能描述:串口发送
/*****************************************************************************************/
void SendCh(unsigned char c)
{	
	EA=0;
	TI=0;
	SBUF = c;
	while(!TI);
	TI=0;
	EA=1;
	
} 

/*****************************************************************************************
//函数名:void InitADC(void)
//输入:无
//输出:无
//功能描述:Nrf24E1ADC初始化
/*****************************************************************************************/
void InitADC()
{
	ADCCON = 0x20;                  //  NPD=1,内部参考电压
	ADCSTATIC &= 0x1c;
	ADCSTATIC |= 0x03;              // 12位ADC
	
}
/*****************************************************************************************
//函数名

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -