標(biāo)題:
分享一個(gè)nrf24l01單向傳輸溫度和土壤濕度的單片機(jī)程序源碼
[打印本頁]
作者:
1986654946
時(shí)間:
2019-5-21 11:16
標(biāo)題:
分享一個(gè)nrf24l01單向傳輸溫度和土壤濕度的單片機(jī)程序源碼
V(VQ]NF@7)E}O{GD098WR`P.png
(45.86 KB, 下載次數(shù): 41)
下載附件
2019-5-21 11:15 上傳
單片機(jī)源程序如下:
// Define SPI pins
#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/****************************/
#define LCDIO P0 //1602數(shù)據(jù)口
/*
sbit rs=P2^6; //1602數(shù)據(jù)命令選擇引腳
sbit rd=P2^5; //讀寫選擇
sbit lcden=P2^7; //1602選通引腳
*/
sbit rs=P2^5; //1602數(shù)據(jù)命令選擇引腳
sbit rd=P2^6; //讀寫選擇
sbit lcden=P2^7; //1602選通引腳
sbit key=P2^2;
sbit beep=P2^4;
uchar xiao,ge,shi,bai;
float f_temp; //浮點(diǎn)型溫度值
long int tvalue;//溫度值
uchar tflag;
uchar code table[]= {"T: TH:30 "}; //每行顯示16個(gè)字符
uchar code table1[]= {"S: "};
uchar data disdata[5];
uchar a,b;
/****************************/
/***************************************************/
#define TX_ADR_WIDTH 5 // 5???????/????
#define TX_PLOAD_WIDTH 5 // ??????????
sbit LED = P2^3;
uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // ??????????
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
sbit RX_DR = sta^6;
sbit TX_DS = sta^5;
sbit MAX_RT = sta^4;
sbit CE = P1^5;
sbit CSN= P1^0;
sbit SCK= P1^4;
sbit MOSI= P1^1;
sbit MISO= P1^3;
sbit IRQ = P1^2;
/*sbit CE = P3^3;
sbit CSN= P2^4;
sbit SCK= P2^0;
sbit MOSI= P2^2;
sbit MISO= P2^1;
sbit IRQ = P2^3;*/
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
//--??SPI???? IO--//
/*sbit MOSIO = P3^4;
sbit R_CLK = P3^5;
sbit S_CLK = P3^6;*/
void blink(char i);
//--??????--//
/**************************************************
??: init_io()
??:
???IO
/**************************************************/
void init_io(void)
{
CE = 0; // ??
CSN = 1; // SPI??
SCK = 0; // SPI????
IRQ = 1; // ????
LED = 1; // ?????
}
/**************************************************/
/**************************************************
??:delay_ms()
??:
??x??
/**************************************************/
void delay_ms(uchar x)
{
uchar i, j;
i = 0;
for(i=0; i<x; i++)
{
j = 250;
while(--j);
j = 250;
while(--j);
}
}
/**************************************************/
/**************************************************
??:SPI_RW()
??:
??SPI??,???????nRF24L01,???nRF24L01
?????
/**************************************************/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0; i<8; i++) // ??8?
{
MOSI = (byte & 0x80); // byte??????MOSI
byte <<= 1; // ?????????
SCK = 1; // ??SCK,nRF24L01?MOSI??1???,???MISO??1???
byte |= MISO; // ?MISO?byte???
SCK = 0; // SCK??
}
return(byte); // ????????
}
/**************************************************/
/**************************************************
??:SPI_RW_Reg()
??:
???value?reg???
/**************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN??,??????
status = SPI_RW(reg); // ?????,???????
SPI_RW(value); // ??????????
CSN = 1; // CSN??,??????
return(status); // ???????
}
/**************************************************/
/**************************************************
??:SPI_Read()
??:
?reg???????
/**************************************************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;
//blink(4);
CSN = 0; // CSN??,??????
SPI_RW(reg); // ?????
reg_val = SPI_RW(0); // ??????????
//delay_ms(200);
CSN = 1; // CSN??,??????
return(reg_val); // ???????
}
/**************************************************/
/**************************************************
??:SPI_Read_Buf()
??:
?reg?????bytes???,??????????
?????/????
/**************************************************/
uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN??,??????
status = SPI_RW(reg); // ?????,???????
for(i=0; i<bytes; i++)
pBuf[i] = SPI_RW(0); // ?????nRF24L01??
CSN = 1; // CSN??,??????
return(status); // ???????
}
/**************************************************/
/**************************************************
??:SPI_Write_Buf()
??:
?pBuf?????????nRF24L01,???????
????????/????
/**************************************************/
uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes)
{
uchar status, i;
CSN = 0; // CSN??,??????
status = SPI_RW(reg); // ?????,???????
for(i=0; i<bytes; i++)
SPI_RW(pBuf[i]); // ??????nRF24L01
CSN = 1; // CSN??,??????
return(status); // ???????
}
/**************************************************/
/**************************************************
??:RX_Mode()
??:
??????nRF24L01?????,????????????
/**************************************************/
void RX_Mode(void)
{
CE = 0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // ????????0??????????????
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // ??????0????
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // ??????0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // ??????0x40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // ????0???????????????
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // ?????1Mbps,????0dBm,????????
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC??,16?CRC??,??,????
delay_ms(150);
CE = 1; // ??CE??????
}
/**************************************************/
/**************************************************
??:TX_Mode()
??:
??????nRF24L01?????,(CE=1????10us),
130us?????,???????,??????????
?????????
/**************************************************/
void TX_Mode(uchar * BUF)
{
CE = 0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // ??????
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // ????????,????0?????????
SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH); // ?????TX FIFO
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, 0x0a); // ????????250us+86us,????10?
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // ??????0x40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // ?????1Mbps,????0dBm,????????
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC??,16?CRC??,??
delay_ms(150);
CE = 1;
}
/**************************************************/
/**************************************************
??:Check_ACK()
??:
??????????????,?????????
?????
/**************************************************/
uchar Check_ACK(bit clear)
{
while(IRQ);
sta = SPI_RW(NOP); // ???????
if(TX_DS)
{
//blink(3);
}
//blink(5);
if(MAX_RT)
if(clear) // ????TX FIFO,???????MAX_RT???????
SPI_RW(FLUSH_TX);
SPI_RW_Reg(WRITE_REG + STATUS, sta); // ??TX_DS?MAX_RT????
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}
/**************************************************/
/**************************************************
??:CheckButtons()
??:
????????,??????????
/**************************************************/
void CheckButtons()
{
P3 |= 0x00;
if(!(P3 & 0x01)) // ??P3^0??
{
delay_ms(20);
if(!(P3 & 0x01)) // ??P3^0??
{
TX_BUF[0] = ~DATA; // ??????
//TX_BUF[0] = 0xff; // ??????
TX_Mode(TX_BUF); // ?nRF24L01????????????
//LED = ~DATA; // ????LED??
Check_ACK(0); // ??????,??TX FIFO
LED = 1; // ??LED
RX_Mode(); // ???????
while(!(P3 & 0x01));
DATA <<= 1;
if(!DATA)
DATA = 0x01;
}
}
}
/**************************************************/
/*void blink(char i)
{
while(i--)
{
LED = 1;
delay_ms(50);
LED = 0;
delay_ms(50);
}
}*/
/***********************
1602
***********************/
void delay(uint z) //短延時(shí)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) //1602寫命令子程序
{
rs=0; //RS是數(shù)據(jù)命令選擇短,高電平寫數(shù)據(jù),低電平寫命令
rd=0; //RD是讀寫選擇短,高電平讀,低電平寫
lcden=0; //1602選通端,高電平選通,低電平禁止
LCDIO=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date) //1602寫數(shù)據(jù)子程序
{
rs=1; //RS是數(shù)據(jù)命令選擇短,高電平寫數(shù)據(jù),低電平寫命令
rd=0; //RD是讀寫選擇短,高電平讀,低電平寫
lcden=0; //1602選通端,高電平選通,低電平禁止
LCDIO=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init() //1602初始化程序
{
uchar num;
lcden=0;
write_com(0x38); //0011 1000B,功能模式設(shè)置,設(shè)置為8為數(shù)據(jù)口,兩行顯示,5*7點(diǎn)陣
write_com(0x0c); //0000 1011B,顯示開及光標(biāo)設(shè)置,關(guān)顯示,顯示光標(biāo),光標(biāo)閃爍
write_com(0x06); //0000 0110B,顯示光標(biāo)移動(dòng)設(shè)置,讀或?qū)懸粋(gè)字符,地址指針減一且光標(biāo)減一,寫一個(gè)字符屏幕顯示不移動(dòng)
write_com(0x01); //0000 0001B,顯示清屏,數(shù)據(jù)指針和所有顯示清屏
write_com(0x80); //1000 000B,關(guān)閉顯示
delay(5);
write_com(0x80); //1000 000B,設(shè)置為2行顯示,寫入第一行字符的地址,第一行地址是00-2F
for(num=0;num<16;num++)
{
write_date(table[num]); //寫入第一行數(shù)據(jù)
delay(5);
}
write_com(0x80+0x40); //1100 0000B,設(shè)置為2行顯示,寫入第二行字符的地址,第而行地址是40-67
for(num=0;num<16;num++) //寫入第二行數(shù)據(jù)
{
write_date(table1[num]);//寫入第二行數(shù)據(jù)
delay(5);
}
}
void ds1820disp()//溫度值顯示
{ uchar flagdat;
disdata[0]=tvalue/1000+0x30;//百位數(shù)
disdata[1]=tvalue%1000/100+0x30;//十位數(shù)
disdata[2]=tvalue%100/10+0x30;//個(gè)位數(shù)
disdata[3]=tvalue%10+0x30;//小數(shù)位
if(tflag==0)
flagdat=0x2b;//正溫度不顯示符號(hào)
else
flagdat=0x2d;//負(fù)溫度顯示負(fù)號(hào):-
if(disdata[0]==0x30)
{disdata[0]=0x20;//如果百位為0,不顯示
if(disdata[1]==0x30)
{disdata[1]=0x20;//如果百位為0,十位為0也不顯示
}
}
write_com(0x80+2); //1100 0000B,設(shè)置為2行顯示,寫入第二行字符的地址,第而行地址是40-67
write_date(flagdat);//顯示符號(hào)位
write_com(0x80+3);
write_date(disdata[0]);//顯示百位
write_com(0x80+4);
write_date(disdata[1]);//顯示十位
write_com(0x80+5);
write_date(disdata[2]);//顯示個(gè)位
write_com(0x80+6);
write_date(0x2e);//顯示小數(shù)點(diǎn)
write_com(0x80+7);
write_date(disdata[3]);//顯示小數(shù)位
write_com(0x80+8);
write_date('C');
}
void ADdisp()
{
long int shidu;
shidu=RX_BUF[3];
xiao=((shidu)*50*20/255)%10+0x30;
ge=((shidu)*50*20/255)%100/10+0x30;
shi=((shidu)*50*20/255)%1000/100+0x30;
bai=((shidu)*50*20/255)/1000+0x30;
if(bai==0x30)
{bai=0x20;//如果百位為0,不顯示
if(shi==0x30)
{shi=0x20;//如果百位為0,十位為0也不顯示
}
}
write_com(0x80+0x45);
write_date(0x2e);//顯示小數(shù)點(diǎn)
write_com(0x80+0x46);
write_date(xiao);//顯示小數(shù)位
write_com(0x80+0x44);
write_date(ge);//顯示個(gè)位
write_com(0x80+0x43);
write_date(shi);//顯示十位
write_com(0x80+0x42);
write_date(bai);//顯示百位
write_com(0x80+0x47);
write_date('%');
}
read_temp()/*讀取溫度值并轉(zhuǎn)換*/
{
a=RX_BUF[1];
b=RX_BUF[2];
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{tvalue=~tvalue+1;
tflag=1;
}
f_temp=tvalue*(0.0625);// 溫度在寄存器中為12位,分辨率為0.0625
tvalue=f_temp*10+0.5;//乘以10表示小數(shù)點(diǎn)后面只取1位,加0.5時(shí)四舍五入
return(tvalue);
}
/**************************************************
??:main()
??:
???
/**************************************************/
void baojing()
{
if(tvalue>=280)
{
beep=1;
write_com(0x80+0x4e);
write_date('!');
write_com(0x80+0x4f);
write_date('!');
}
else
{
beep=0;
write_com(0x80+0x4e);
write_date(0x20);
write_com(0x80+0x4f);
write_date(0x20);
}
}
void main(void)
{
LED=1;
beep=0;
init_io(); // ???IO
init();
RX_Mode(); // ???????
while(1)
{
sta = SPI_Read(STATUS); // ??????
//delay_ms(200);
if(RX_DR) // ?????????
{
SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH); // ?RX FIFO????
flag = 1;
}
SPI_RW_Reg(WRITE_REG + STATUS, sta); // ??RX_DS????
if(flag) // ????
{
if(RX_BUF[0] == 1)
{ beep=0;
LED=~LED;
read_temp();
ds1820disp();//顯示
baojing();
}
if(key==0)
{
ADdisp();
}
flag = 0; // ???
}
}
}
復(fù)制代碼
所有資料51hei提供下載:
NRF24L01測溫測濕.rar
(105.22 KB, 下載次數(shù): 36)
2019-5-21 11:14 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
ccczzz
時(shí)間:
2020-4-5 17:08
感謝分享,最近正在做NRF24L01相關(guān)設(shè)計(jì),值得參考!贊!
作者:
執(zhí)筆待君歸
時(shí)間:
2021-3-26 21:49
我還是沒搞定這個(gè),唉
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1