#include "main.h"
__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF&BOREN_OFF&CLKOUTEN_OFF);
__CONFIG(WRT_OFF&STVREN_OFF&BORV_HI&LPBOR_OFF&LVP_OFF);
const unsigned char TX_ADDRESS[12][TX_ADR_WIDTH]={{0x34,0x43,0x10},{0xc2,0xc2,0xc2},
{0xc3,0xc2,0xc2},{0xc4,0xc2,0xc2},
{0xc5,0xc2,0xc2},{0xc6,0xc2,0xc2},
{0xc2,0xc2,0xc2},{0xc3,0xc2,0xc2},
{0xc4,0xc2,0xc2},{0xc5,0xc2,0xc2},
{0xc6,0xc2,0xc2},{0x34,0x43,0x10},}; //发送地址
//const unsigned char RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10}; //接收地址
unsigned char txBuf[16] = {0};
unsigned char measureCh; //测量通道
void delay(unsigned char x)
{
unsigned int i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
void led()
{
RA5=1;
__delay_ms(500);
RA5=0;
__delay_ms(500);
}
void InitNRF24L01()
{
TRISC5 = 0; //CE 输出
TRISC4 = 0; //CSN 输出
TRISA2 = 1; //IRQ 输入
//延时10.3ms
//设置PWM_UP位为1,并且等待1.5ms,进入待机模式1
//SPI 端口设置
TRISC0 = 0;//spi时钟
TRISC1 = 1;//spi数据输入,实际上由模块自动控制
TRISC2 = 0;//spi数据输出口
//TRISA5 = 1;//原来是spi从机选择,主控下,没用,作为输入口
CKP = 0;//时钟空闲为低
CKE = 1;//第一边沿采样数据
SSPM0 = SSPM1 = SSPM2 = SSPM3 = 0;//spi主控模式,1/4时钟周期
SSP1IF = 0;//清除中断位
SSPEN = 1;//使能SSP
}
void Reset24L01_SPI_CTRL()
{
CKP = 0;//时钟空闲为低
CKE = 1;//第一边沿采样数据
SSPM0 = SSPM1 = SSPM2 = SSPM3 = 0;//spi主控模式,1/4时钟周期
SSP1IF = 0;//清除中断位
SSPEN = 1;//使能SSP
}
/********SPI端口收发字节,并返回从机字节*************/
/********无片选控制***********************************/
unsigned char SPI_SendByte(unsigned char byte)
{
unsigned char rtData;
SSPBUF = byte;
led();
while(SSP1IF == 0) //等待发送完毕
;
led();
rtData = SSPBUF;
SSP1IF = 0;
return rtData;
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* value 给寄存器写的值 */
/* 出口参数:status 状态值 */
/*********************************************/
unsigned char NRF24L01_Write_Reg(unsigned char reg,unsigned char value)
{
unsigned char status;
CSN = 0;
status = SPI_SendByte(reg);//发送寄存器地址,并读取状态值
SPI_SendByte(value);
CSN = 1;
return status;
}
/*************************************************/
/* 函数功能:读24L01的寄存器值 (一个字节) */
/* 入口参数:reg 要读的寄存器地址 */
/* 出口参数:value 读出寄存器的值 */
/*************************************************/
unsigned char NRF24L01_Read_Reg(unsigned char reg)
{
unsigned char value;
CSN = 0;
SPI_SendByte(reg);//发送寄存器值(位置),并读取状态值
value = SPI_SendByte(0);
CSN = 1;
return value;
}
/**********************************************/
/* 函数功能:给24L01的寄存器写值(多个字节) */
/* 入口参数:reg 要写的寄存器地址 */
/* *pBuf 值的存放数组 */
/* len 数组字节长度 */
/**********************************************/
unsigned char NRF24L01_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char len)
{
unsigned char status,u8_ctr;
CSN = 0;
status = SPI_SendByte(reg);//发送寄存器值(位置),并读取状态值
for(u8_ctr=0; u8_ctr<len; u8_ctr++)
SPI_SendByte(*pBuf++); //写入数据
CSN = 1;
return status; //返回读到的状态值
}
/*********************************************/
/* 函数功能:读24L01的寄存器值(多个字节) */
/* 入口参数:reg 寄存器地址 */
/* *pBuf 读出寄存器值的存放数组 */
/* len 数组字节长度 */
/* 出口参数:status 状态值 */
/*********************************************/
unsigned char NRF24L01_Read_Buf(unsigned char reg,unsigned char *pBuf,unsigned char len)
{
unsigned char status,u8_ctr;
CSN = 0;
status=SPI_SendByte(reg);//发送寄存器地址,并读取状态值
for(u8_ctr=0;u8_ctr<len;u8_ctr++)
pBuf[u8_ctr]=SPI_SendByte(0);//读出数据
CSN = 1;
return status; //返回读到的状态值
}
/********************************************/
/* 函数功能:检测24L01是否存在 */
/* 返回值; 0 存在 */
/* 1 不存在 */
/********************************************/
unsigned char NRF24L01_Check(void)
{
unsigned char check_in_buf[5]={0x11,0x22,0x33,0x44,0x55};
unsigned char check_out_buf[5]={0x00};
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5);
NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5);
if((check_out_buf[0] == 0x11)&&\
(check_out_buf[1] == 0x22)&&\
(check_out_buf[2] == 0x33)&&\
(check_out_buf[3] == 0x44)&&\
(check_out_buf[4] == 0x55))
return 0;
else
return 1;
}
/*********************************************/
/* 函数功能:设置24L01为发送模式 */
/*********************************************/
void NRF24L01_TX_Mode(void)
{
CE = 0; //CE拉低,使能24L01配置
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(unsigned char*)&TX_ADDRESS[measureCh][0],TX_ADR_WIDTH);//写TX节点地址
NRF24L01_Write_Reg(WRITE_REG+SETUP_AW,0x01); //3字节 地址宽度
//NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(unsigned char*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK
NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x00);
NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x00); ////禁止通道0的自动应答
NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x00); ////禁止通道0的接收地址
//NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
NRF24L01_Write_Reg(WRITE_REG+RF_CH,RFCHANNAL); //设置RF通道为40
NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x26); ////设置TX发射参数,0db增益,250kbps
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0C); //配置基本工作模式的参数;PWR_DOWN,EN_CRC,16BIT_CRC,接收模式,开启所有中断,进入掉电模式
//CE 当前为低,为待机模式1
//CE = 1; //CE置高,使能发送
}
/**********************************************/
/* 函数功能:设置24L01为发送模式 */
/* 入口参数:txbuf 发送数据数组 */
/* 返回值; 0x10 达到最大重发次数,发送失败*/
/* 0x20 成功发送完成 */
/* 0xff 发送失败 */
/**********************************************/
unsigned char NRF24L01_TxPacket(unsigned char *txbuf)
{
unsigned char state;
CE = 0;; //CE拉低,使能24L01配置
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 2个字节
CE = 1; //CE置高,使能发送
while(IRQ == 1);//等待发送完成
state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
/*if(state&MAX_TX)//达到最大重发次数
{
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
return MAX_TX;
}
if(state&TX_OK)//发送完成
{
return TX_OK;
}*/
return 0xff;//发送失败
}
//发送温度数据
void SendT()
{
CE = 0;
__delay_ms(2);
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e); //上电 //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
__delay_ms(2);
//CE = 1;
__delay_ms(50);
NRF24L01_TxPacket(txBuf);
__delay_ms(2);
CE = 0;
__delay_ms(2);
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0c); //掉电休眠 //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
__delay_ms(2);
//CE = 1;
}
void SendFirst()
{
txBuf[1] = 0^(CHANNAL+0xc8);
RC3 = 1; //打开发射模块电源开关
__delay_ms(50);
//发射前重新初始化
Reset24L01_SPI_CTRL(); //InitNRF24L01();
__delay_ms(2);
NRF24L01_TX_Mode();
__delay_ms(2);
///////////////////////////////
SendT();
__delay_ms(50);
RC3 = 0;
}
void Init(void)
{
INTCON = 0;//关闭总中断,禁止外设,timer0,外部,电平中断,清除timer0,外部,电平中断标志
ANSELC=0;
ANSELA=0X10;
//RBPU = 0; //使能RB口线 上拉
InitNRF24L01();
NRF24L01_TX_Mode();
PEIE = 1;//开外设中断
//GIE = 1;//开总中断
}
void main()
{
TRISA5=0;
RA5=0;
OSCCON |= 0x72; //8M内部振荡器
while(HFIOFS == 0) //等待稳定
;
//测量通道号,0-11对应1-12路测量通道
measureCh = CHANNAL;
txBuf[0] = measureCh; //地址标识
/////////////////////////////////
TRISA0 = 0;
TRISA1 = 0;
RA0 = RA1 = 0;
TRISC3 = 0;//发射模块电源控制开关
RC3 = 0;
__delay_ms(1000);
Init();
SendFirst();
while(1)
{
led();
}
} |
|