nrf24l01无线温度传输51单片机Word文件下载.docx
《nrf24l01无线温度传输51单片机Word文件下载.docx》由会员分享,可在线阅读,更多相关《nrf24l01无线温度传输51单片机Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。
sbitIRQ=P1^6;
//中断
ucharbdatasta;
sbitRX_DR=sta^6;
//接收数据准备就绪
sbitTX_DS=sta^5;
//已发送数据
sbitMAX_RT=sta^4;
sbitDQ=P3^3;
unsignedchartime;
//设置全局变量,专门用于严格延时
//*********************************************NRF24L01*************************************
//***************************************NRF24L01寄存器指令*******************************************************
#defineREAD_REG0x00//读寄存器指令
#defineWRITE_REG0x20//写寄存器指令
#defineRD_RX_PLOAD0x61//读取接收数据指令
#defineWR_TX_PLOAD0xA0//写待发数据指令
#defineFLUSH_TX0xE1//冲洗发送FIFO指令
#defineFLUSH_RX0xE2//冲洗接收FIFO指令
#defineREUSE_TX_PL0xE3//定义重复装载数据指令
#defineNOP0xFF//保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#defineCONFIG0x00//配置收发状态,CRC校验模式以及收发状态响应方式
#defineEN_AA0x01//自动应答功能设置
#defineEN_RXADDR0x02//可用信道设置
#defineSETUP_AW0x03//收发地址宽度设置
#defineSETUP_RETR0x04//自动重发功能设置
#defineRF_CH0x05//工作频率设置
#defineRF_SETUP0x06//发射速率、功耗功能设置
#defineSTATUS0x07//状态寄存器
#defineOBSERVE_TX0x08//发送监测功能
#defineCD0x09//地址检测
#defineRX_ADDR_P00x0A//频道0接收数据地址
#defineRX_ADDR_P10x0B//频道1接收数据地址
#defineRX_ADDR_P20x0C//频道2接收数据地址
#defineRX_ADDR_P30x0D//频道3接收数据地址
#defineRX_ADDR_P40x0E//频道4接收数据地址
#defineRX_ADDR_P50x0F//频道5接收数据地址
#defineTX_ADDR0x10//发送地址寄存器
#defineRX_PW_P00x11//接收频道0接收数据长度
#defineRX_PW_P10x12//接收频道0接收数据长度
#defineRX_PW_P20x13//接收频道0接收数据长度
#defineRX_PW_P30x14//接收频道0接收数据长度
#defineRX_PW_P40x15//接收频道0接收数据长度
#defineRX_PW_P50x16//接收频道0接收数据长度
#defineFIFO_STATUS0x17//FIFO栈入栈出状态寄存器设置
//**************************************************************************************
voidinit_io(void)
{
CE=0;
CSN=1;
SCK=0;
}
voiddelay_ms(unsignedintx)
unsignedinti,j;
for(i=0;
i<
x;
i++)
{
j=108;
while(j--);
}
ucharSPI_RW(ucharbyte)//发送指令,接受状态,返回值为状态值
ucharbit_ctr;
for(bit_ctr=0;
bit_ctr<
8;
bit_ctr++)
{
MOSI=(byte&
0x80);
byte=(byte<
<
1);
SCK=1;
byte|=MISO;
SCK=0;
}
return(byte);
ucharSPI_RW_Reg(ucharreg,ucharvalue)
ucharstatus;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
ucharSPI_Read(ucharreg)
ucharreg_val;
SPI_RW(reg);
//写指令
reg_val=SPI_RW(0);
//读reg的内容
return(reg_val);
ucharSPI_Read_Buf(ucharreg,uchar*pBuf,ucharbytes)
ucharstatus,byte_ctr;
for(byte_ctr=0;
byte_ctr<
bytes;
byte_ctr++)
pBuf[byte_ctr]=SPI_RW(0);
ucharSPI_Write_Buf(ucharreg,uchar*pBuf,ucharbytes)
byte_ctr<
byte_ctr++)
SPI_RW(*pBuf++);
voidTX_Mode(void)
SPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS/*接收模块的地址*/,TX_ADR_WIDTH/*地址宽度5*/);
SPI_Write_Buf(WRITE_REG+RX_ADDR_P0/*通道0接收数据地址*/,TX_ADDRESS,TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD,/*写待发数据指令a0*/tx_buf,TX_PLOAD_WIDTH/*20*/);
SPI_RW_Reg(WRITE_REG+EN_AA,0x01);
//数据通道0应答允许
SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);
//接收数据通道0允许
SPI_RW_Reg(WRITE_REG+SETUP_RETR,0x1a);
//等待500+86us自动重发10次
SPI_RW_Reg(WRITE_REG+RF_CH,40);
SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);
//数据传输率1Mbps,发射功率0dBm
SPI_RW_Reg(WRITE_REG+CONFIG,0x0e);
//配置寄存器
CE=1;
voidcheckflag()
{sta=SPI_Read(STATUS);
//读状态寄存器
//if(RX_DR)
//{
//SPI_Read_Buf(RD_RX_PLOAD/*读取接收数据指令*/,rx_buf/*数组[20]*/,TX_PLOAD_WIDTH/*20*/);
//flag=1;
//}
if(MAX_RT)
SPI_RW_Reg(FLUSH_TX/*冲洗发送FIFO指令*/,0);
SPI_RW_Reg(WRITE_REG+STATUS,sta);
//清除中断
//以下是DS18B20的操作程序
//************************************************************************/
voiddelay1ms()
unsignedchari,j;
4;
for(j=0;
j<
33;
j++)
;
/*****************************************************
函数功能:
延时若干毫秒
入口参数:
n
***************************************************/
voiddelaynms(unsignedcharn)
unsignedchari;
n;
delay1ms();
将DS18B20传感器初始化,读取应答信号
出口参数:
flag
bitInit_DS18B20(void)
bitflag;
//储存DS18B20是否存在的标志,flag=0,表示存在;
flag=1,表示不存在
DQ=1;
//先将数据线拉高
for(time=0;
time<
2;
time++)//略微延时约6微秒
DQ=0;
//再将数据线从高拉低,要求保持480~960us
200;
time++)//略微延时约600微秒
//以向DS18B20发出一持续480~960us的低电平复位脉冲
//释放数据线(将数据线拉高)
10;
time++)
//延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲)
flag=DQ;
//让单片机检测是否输出了存在脉冲(DQ=0表示存在)
time++)//延时足够长时间,等待存在脉冲输出完毕
return(flag);
//返回检测成功标志
从DS18B20读取一个字节数据
dat
***************************************************/
unsignedcharReadOneChar(void)
unsignedchari=0;
unsignedchardat;
//储存读出的一个字节数据
for(i=0;
DQ=1;
//先将数据线拉高
_nop_();
//等待一个机器周期
DQ=0;
//单片机从DS18B20读书据时,将数据线从高拉低即启动读时序
//等待一个机器周期
DQ=1;
//将数据线"
人为"
拉高,为单片机检测DS18B20的输出电平作准备
for(time=0;
//延时约6us,使主机在15us内采样
dat>
>
=1;
if(DQ==1)
dat|=0x80;
//如果读到的数据是1,则将1存入dat
else
dat|=0x00;
//如果读到的数据是0,则将0存入dat
//将单片机检测到的电平信号DQ存入r[i]
;
//延时3us,两个读时序之间必须有大于1us的恢复期
}
return(dat);
//返回读出的十六进制数据
向DS18B20写入一个字节数据
WriteOneChar(unsignedchardat)
unsignedchari=0;
for(i=0;
i<
i++)
DQ=0;
//将数据线从高拉低时即启动写时序
DQ=dat&
0x01;
//利用与运算取出要写的某位二进制数据,
//并将其送到数据线上等待DS18B20采样
time++)
;
//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样
DQ=1;
//释放数据线
1;
//延时3us,两个写时序间至少需要1us的恢复期
dat>
//将dat中的各二进制位数据右移1位
//稍作延时,给硬件一点反应时间
做好读温度的准备
voidReadyReadTemp(void)
Init_DS18B20();
//将DS18B20初始化
WriteOneChar(0xCC);
//跳过读序号列号的操作
WriteOneChar(0x44);
//启动温度转换
delaynms(150);
//转换一次需要延时一段时间
Init_DS18B20();
//跳过读序号列号的操作
WriteOneChar(0xBE);
//读取温度寄存器,前两个分别是温度的低位和高位
voiddwend(void)
{ucharTL;
//储存暂存器的温度低位
ucharTH;
//储存暂存器的温度高位
TL=ReadOneChar();
//先读的是温度值低位
TH=ReadOneChar();
//接着读的是温度值高位
distance_data[0]=TH;
//测量结果的高8位
distance_data[1]=TL;
//放入16位的高8位
voidmain(void)
ucharxx;
init_io();
while
(1)
{
ReadyReadTemp();
dwend();
checkflag();
for(xx=0;
xx<
xx++)
tx_buf[xx]=distance_data[xx];
//发数据之前必须把要发送的数据装入它
TX_Mode();
//必须启动发送模块
delay_ms(5);
接收端程序:
ucharcodedigit[11]={"
0123456789-"
};
//定义字符数组显示数字
ucharcodeStr[]={"
RICHMCUDS18B20"
//说明显示的是温度
//unsignedcharcodeError[]={"
DS18B20ERROR"
//说明没有检测到DS18B20
//unsignedcharcodeError1[]={"
PLEASECHECK"
ucharcodeTemp[]={"
WENDU:
"
ucharcodeCent[]={"
Cent"
//温度单位
uchartm[2];
ucharflg=0;
//负温度标志和临时暂存变量
uchartltemp;
#defineTX_ADR_WIDTH5
#defineTX_PLOAD_WIDTH2
intcout;
sbitRS=P2^0;
//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;
//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;
//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;
//忙碌标志位,,将BF位定义为P0.7引脚
#defineRX_PW_P10x