Ⅰ 51單片機和DS18B20溫度感測器、LCD1602液晶顯示,NRF24L01無線傳輸模塊 的無線溫度監測系統的收發程序
/******************************無線溫度發送***********************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define TX_ADDR_WITDH 5//發送地址寬度設置為5個位元組
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 5
#define RX_DATA_WITDH 5
/******************************************************************
// nRF24L01指令格式:
*******************************************************************/
#define R_REGISTER 0x00 // 讀寄存器
#define W_REGISTER 0x20 // 寫寄存器
#define R_RX_PLOAD 0x61 // 讀RX FIFO有效數據,1-32位元組,當讀數據完成後,數據被清除,應用於接收模式
#define W_TX_PLOAD 0xA0 // 寫TX FIFO有效數據,1-32位元組,寫操作從位元組0開始,應用於發射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,應用於發射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,應用於接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效數據,當CE為高過程中,數據包被不斷的重新發射
#define NOP 0xFF // 空操作,可以用來讀狀態寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // 「自動應答」功能寄存
#define EN_RX_ADDR 0x02 // 接收通道使能寄存器
#define SETUP_AW 0x03 // 地址寬度設置寄存器
#define SETUP_RETR 0x04 // 自動重發設置寄存器
#define RF_CH 0x05 // 射頻通道頻率設置寄存器
#define RF_SETUP 0x06 // 射頻設置寄存器
#define STATUS 0x07 // 狀態寄存器
#define OBSERVE_TX 0x08 // 發送檢測寄存器
#define CD 0x09 // 載波檢測寄存器
#define RX_ADDR_P0 0x0A // 數據通道0接收地址寄存器
#define RX_ADDR_P1 0x0B // 數據通道1接收地址寄存器
#define RX_ADDR_P2 0x0C // 數據通道2接收地址寄存器
#define RX_ADDR_P3 0x0D // 數據通道3接收地址寄存器
#define RX_ADDR_P4 0x0E // 數據通道4接收地址寄存器
#define RX_ADDR_P5 0x0F // 數據通道5接收地址寄存器
#define TX_ADDR 0x10 // 發送地址寄存器
#define RX_PW_P0 0x11 // 數據通道0有效數據寬度設置寄存器
#define RX_PW_P1 0x12 // 數據通道1有效數據寬度設置寄存器
#define RX_PW_P2 0x13 // 數據通道2有效數據寬度設置寄存器
#define RX_PW_P3 0x14 // 數據通道3有效數據寬度設置寄存器
#define RX_PW_P4 0x15 // 數據通道4有效數據寬度設置寄存器
#define RX_PW_P5 0x16 // 數據通道5有效數據寬度設置寄存器
#define FIFO_STATUS 0x17 // FIFO狀態寄存器
//*********************************************************************************
uchar sta; // 狀態變數
#define RX_DR (sta & 0x40) // 接收成功中斷標志
#define TX_DS (sta & 0x20) // 發射成功中斷標志
#define MAX_RT (sta & 0x10) // 重發溢出中斷標志
sbit CE=P1^5;
sbit IRQ=P1^0;
sbit CSN=P1^4;
sbit MOSI=P1^2;
sbit MISO=P1^1;
sbit SCK=P1^3;
//sbit key=P1^0;
sbit LED=P0^0;
sbit DQ=P1^6;
uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
//uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x00};
uchar RX_Buffer[RX_DATA_WITDH];
uchar Temp_Value[]={0x00,0x00};
uchar Temp=0;
uchar Display_Digit[]={0,0,0,0};
bit DS18B20_IS_OK=1;
uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//decimal fraction
void _delay_tus(uint x)
{
while(--x);
}
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<120;i++);
}
/**************************************************/
/*函數功能:DS18B20初始化*/
/*入口參數:無 */
/*出口函數:status */
/**************************************************/
uchar DS18B20_Init(void)
{
uchar status;
DQ=1;
_delay_tus(10);
DQ=0;
_delay_tus(90);
DQ=1;
_delay_tus(8);
status=DQ;
_delay_tus(100);
DQ=1;
return status;
}
/**************************************************/
/*函數功能:從DS18B20讀取一位元組*/
/*入口參數:無 */
/*出口函數:dat(返回讀取到數據) */
/**************************************************/
uchar Read_One_Byte(void)
{
uchar i,dat=0;
DQ=1;
_nop_();
for(i=8;i>0;i--)
{
DQ=0;
dat>>=1;
DQ=1;
_nop_();_nop_();
if(DQ)
dat|=0x80;
_delay_tus(30);
DQ=1;
}
return dat;
}
/**************************************************/
/*函數功能:向DS18B20寫一位元組*/
/*入口參數:dat(把dat寫入DS18B20) */
/*出口函數:無 */
/**************************************************/
void Write_One_Byte(uchar dat)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
_delay_tus(5);
DQ=1;
dat>>=1;
}
}
/**************************************************/
/*函數功能:從DS18B20讀取數據(數據)*/
/*入口參數:無 */
/*出口函數:無 */
/**************************************************/
void Read_Temp(void)
{
uchar ng=0;
if(DS18B20_Init()==1)
DS18B20_IS_OK=0;
else
{
Write_One_Byte(0xcc);
Write_One_Byte(0x44);
DS18B20_Init();
Write_One_Byte(0xcc);
Write_One_Byte(0xbe);
Temp_Value[0]=Read_One_Byte();
Temp_Value[1]=Read_One_Byte();
DS18B20_IS_OK=1;
}
if((Temp_Value[1]&0xf8)==0xf8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng=1;
}
Display_Digit[0]=df_tab[Temp_Value[0]&0x0f];
Temp=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
Display_Digit[3]=Temp/100;
Display_Digit[2]=Temp%100/10;
Display_Digit[1]=Temp%10;
}
/**************************************************/
/*函數功能:從DS18B20讀取數據轉換成ASCII碼寫入液晶 */
/*模塊 */
/*入口參數:無 */
/*出口函數:無 */
/**************************************************/
/*void Display_Temperature(void)
{
uchar ng=0;
if((Temp_Value[1]&0xf8)==0xf8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng=1;
}
Display_Digit[0]=df_tab[Temp_Value[0]&0x0f];
Temp=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
Display_Digit[3]=Temp/100;
Display_Digit[2]=Temp%100/10;
Display_Digit[1]=Temp%10;
}
Display_LINE1[13]=0x43;
Display_LINE1[12]=0xdf;
Display_LINE1[11]=Display_Digit[0]+'0';
Display_LINE1[10]='.';
Display_LINE1[9]=Display_Digit[1]+'0';
Display_LINE1[8]=Display_Digit[2]+'0';
Display_LINE1[7]=Display_Digit[3]+'0';
if(Display_Digit[3]==0)
Display_LINE1[7]=' ';
if(Display_Digit[2]==0&&Display_Digit[3]==0)
Display_LINE1[8]=' ';
if(ng)
{
if(Display_LINE1[8]==' ')
Display_LINE1[8]='-';
else if(Display_LINE1[7]==' ')
Display_LINE1[7]='-';
else
Display_LINE1[6]='-';
}
LCD_POS(0);
Show_String(Display_LINE0);
LCD_POS(0x40);
Show_String(Display_LINE1);
}
void main(void)
{
Init_LCD();
Read_Temp();
_delay_ms(1000);
while(1)
{
Read_Temp();
if(DS18B20_IS_OK)
Display_Temperature();
_delay_ms(200);
}
}*/
/*nRF24L01初始化*/
void nRF24L01_Init(void)
{
_delay_us(2000);
CE=0;//待機模式Ⅰ
CSN=1;
SCK=0;
IRQ=1;
}
/*SPI時序函數*/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)//一位元組8位循環8次寫入
{
if(byte&0x80)//如果數據最高位是1//當訪問多位元組寄存器時首先要讀/寫的是最低位元組的高位?
MOSI=1;//向NRF24L01寫1
else //否則寫0
MOSI=0;
byte<<=1;//低一位移到最高位
SCK=1;//SCK拉高,寫入一位數據,同時讀取一位數據
if(MISO)
byte|=0x01;
SCK=0;//SCK拉低
}
return byte;//返回讀取一位元組
}
/*SPI寫寄存器一位元組函數*/
/*reg:寄存器地址*/
/*value:一位元組(值)*/
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;//返回狀態
CSN=0;//SPI片選
status=SPI_RW(reg);//寫入寄存器地址,同時讀取狀態
SPI_RW(value);//寫入一位元組
CSN=1;//
return status;//返回狀態
}
/*SPI*/
uchar SPI_R_byte(uchar reg)
{
uchar reg_value;
CSN=0;//SPI片選
SPI_RW(reg);//寫入地址
reg_value=SPI_RW(0);//讀取寄存器的值
CSN=1;
return reg_value;//返回讀取的值
}
/*SPI讀取RXFIFO寄存器數據*/
/*reg:寄存器地址*/
/**Dat_Buffer:用來存讀取的數據*/
/*DLen:數據長度*/
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI片選
status=SPI_RW(reg);//寫入寄存器地址,同時狀態
for(i=0;i<Dlen;i++)
{
Dat_Buffer[i]=SPI_RW(0);//存儲數據
}
CSN=1;
return status;
}
/*SPI向TXFIFO寄存器寫入數據*/
/*reg:寫入寄存器地址*/
/*TX_Dat_Buffer:存放需要發送的數據*/
/*Dlen:數據長度*/
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;//SPI片選,啟動時序
status=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer[i]);//發送數據
}
CSN=1;
return status;
}
/*設置發送模式*/
void nRF24L01_Set_TX_Mode(uchar *TX_Data)
{
CE=0;//待機(寫寄存器之前一定要進入待機模式或掉電模式)
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);/*寫寄存器指令+接收節點地址+地址寬度*/
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);/*為了接收設備應答信號,接收通道0地址與發送地址相同*/
SPI_W_DBuffer(W_TX_PLOAD,TX_Data,TX_DATA_WITDH);/*寫有效數據地址+有效數據+有效數據寬度*/
SPI_W_Reg(W_REGISTER+EN_AA,0x01);/*接收通道0自動應答*/
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);/*使能接收通道0*/
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);/*自動重發延時250US+86US,重發10次*/
//SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
SPI_W_Reg(W_REGISTER+RF_CH,0x40);/*(2400+40)MHZ選擇射頻通道0X40*/
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);/*1Mbps速率,發射功率:0DBM,低雜訊放大器增益*/
SPI_W_Reg(W_REGISTER+CONFIG,0x0e);/*發送模式,上電,16位CRC校驗,CRC使能*/
CE=1;//啟動發射
_delay_ms(5);/*CE高電平持續時間最少10US以上*/
}
uchar Check_Rec(void)
{
uchar status;
sta=SPI_R_byte(R_REGISTER+STATUS);
if(RX_DR)
{
CE=0;
SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
status=1;
}
SPI_W_Reg(W_REGISTER+STATUS,0xff);
return status;
}
/*檢測應答信號*/
uchar Check_Ack(void)
{
sta=SPI_R_byte(R_REGISTER+STATUS);/*讀取寄存狀態*/
if(TX_DS||MAX_RT)/*如果TX_DS或MAX_RT為1,則清除中斷和清除TX_FIFO寄存器的值*/
{
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_TX);
CSN=1;
return 0;
}
else
return 1;
}
void main(void)
{
uchar i;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
nRF24L01_Init();
Read_Temp();
_delay_ms(1000);
while(1)
{
Read_Temp();
if(DS18B20_IS_OK)
{
for(i=0;i<TX_DATA_WITDH-4;i++)//減1是因為最後一位為結束標志
{
LED=~LED;
nRF24L01_Set_TX_Mode(&Display_Digit[i]);
_delay_ms(100);
while(Check_Ack());
//LED=0;
}
}
}
}
/******************************無線溫度接收***********************/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define TX_ADDR_WITDH 5//發送地址寬度設置為5個位元組
#define RX_ADDR_WITDH 5
#define TX_DATA_WITDH 5
#define RX_DATA_WITDH 5
/******************************************************************
// nRF24L01指令格式:
*******************************************************************/
#define R_REGISTER 0x00 // 讀寄存器
#define W_REGISTER 0x20 // 寫寄存器
#define R_RX_PLOAD 0x61 // 讀RX FIFO有效數據,1-32位元組,當讀數據完成後,數據被清除,應用於接收模式
#define W_TX_PLOAD 0xA0 // 寫TX FIFO有效數據,1-32位元組,寫操作從位元組0開始,應用於發射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,應用於發射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,應用於接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效數據,當CE為高過程中,數據包被不斷的重新發射
#define NOP 0xFF // 空操作,可以用來讀狀態寄存器
/******************************************************************
// nRF24L01寄存器地址
*******************************************************************/
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // 「自動應答」功能寄存器
#define EN_RX_ADDR 0x02 // 接收通道使能寄存器
#define SETUP_AW 0x03 // 地址寬度設置寄存器
#define SETUP_RETR 0x04 // 自動重發設置寄存器
#define RF_CH 0x05 // 射頻通道頻率設置寄存器
#define RF_SETUP 0x06 // 射頻設置寄存器
#define STATUS 0x07 // 狀態寄存器
#define OBSERVE_TX 0x08 // 發送檢測寄存器
#define CD 0x09 // 載波檢測寄存器
#define RX_ADDR_P0 0x0A // 數據通道0接收地址寄存器
#define RX_ADDR_P1 0x0B // 數據通道1接收地址寄存器
#define RX_ADDR_P2 0x0C // 數據通道2接收地址寄存器
#define RX_ADDR_P3 0x0D // 數據通道3接收地址寄存器
#define RX_ADDR_P4 0x0E // 數據通道4接收地址寄存器
#define RX_ADDR_P5 0x0F // 數據通道5接收地址寄存器
#define TX_ADDR 0x10 // 發送地址寄存器
#define RX_PW_P0 0x11 // 數據通道0有效數據寬度設置寄存器
#define RX_PW_P1 0x12 // 數據通道1有效數據寬度設置寄存器
#define RX_PW_P2 0x13 // 數據通道2有效數據寬度設置寄存器
#define RX_PW_P3 0x14 // 數據通道3有效數據寬度設置寄存器
#define RX_PW_P4 0x15 // 數據通道4有效數據寬度設置寄存器
#define RX_PW_P5 0x16 // 數據通道5有效數據寬度設置寄存器
#define FIFO_STATUS 0x17 // FIFO狀態寄存器
//*********************************************************************************
uchar sta; // 狀態變數
#define RX_DR (sta & 0x40) // 接收成功中斷標志
#define TX_DS (sta & 0x20) // 發射成功中斷標志
#define MAX_RT (sta & 0x10) // 重發溢出中斷標志
sbit CE=P1^5; //RX/TX模式選擇端
sbit IRQ=P1^0; //可屏蔽中斷端
sbit CSN=P1^4; //SPI片選端//就是SS
sbit MOSI=P1^2;//SPI主機輸出從機輸入端
sbit MISO=P1^1;//SPI主機輸出從機輸出端
sbit SCK=P1^3;//SPI時鍾端
sbit LED=P0^0;
sbit key=P2^0;
sbit LCD_RS=P2^2;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^0;
uchar code TX_Addr[]={0x34,0x43,0x10,0x10,0x01};
uchar code TX_Buffer[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar RX_Buffer[RX_DATA_WITDH];
uchar code Display_LINE0[]={" FROM NRF24L01:"};
uchar Display_LINE1[]={" TEMP: "};
void _delay_us(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<12;i++);
}
void _delay_ms(uint x)
{
uint i,j;
for (j=0;j<x;j++)
for (i=0;i<120;i++);
}
bit LCD_Busy(void)//測忙
{
bit LCD_Status;//返回值變數
LCD_RS=0;//讀取狀態
LCD_RW=1;
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_Status=(bit)(P3&0x80);
LCD_EN=0;
return LCD_Status;
}
void LCD_Write_Command(uchar cmd)//寫指令
{
//while(LCD_Busy());
LCD_RS=0;//
LCD_RW=0;
LCD_EN=0;
_nop_();_nop_();
P3=cmd;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=0;
}
void LCD_Write_Data(uchar dat)//寫數據
{
//while(LCD_Busy());//每次寫數據操作之前均需要檢測忙信號
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P3=dat;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=1;
_nop_();_nop_();_nop_();_nop_();
LCD_EN=0;
}
void Init_LCD(void)//液晶初始化
{
_delay_ms(15);//延時15MS
LCD_Write_Command(0x38);
_delay_ms(5);
LCD_Write_Command(0x38);
_delay_ms(5);
LCD_Write_Command(0x38);//以後每次寫指令操作之前均需要檢測忙信號
//while(LCD_Busy());
_delay_ms(5);
LCD_Write_Command(0x01);//清屏
//while(LCD_Busy());
_delay_ms(5);
LCD_Write_Command(0x38);//設置16*2顯示,5*7點陣,8位數據介面
_delay_ms(5);
//while(LCD_Busy());
LCD_Write_Command(0x0c);//開顯示,不顯示游標
_delay_ms(5);
//while(LCD_Busy());
LCD_Write_Command(0x06);//當讀或寫一個字元後地址指針加一,且游標加一
}
void LCD_POS(uchar pos)//字元顯示位置
{
LCD_Write_Command(0x80|pos);
}
void Show_String(uchar *str)//顯示字元串
{
while(*str!='\0')
LCD_Write_Data(*str++);
}
void nRF24L01_Init(void)
{
_delay_us(2000);
CE=0;
CSN=1;
SCK=0;
IRQ=1;
}
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
if(byte&0x80)
MOSI=1;
else
MOSI=0;
byte<<=1;
SCK=1;
if(MISO)
byte|=0x01;
SCK=0;
}
return byte;
}
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return status;
}
uchar SPI_R_byte(uchar reg)
{
uchar status;
CSN=0;
SPI_RW(reg);
status=SPI_RW(0);
CSN=1;
return status;
}
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
Dat_Buffer[i]=SPI_RW(0);
}
CSN=1;
return reg_value;
}
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar reg_value,i;
CSN=0;
reg_value=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
SPI_RW(TX_Dat_Buffer[i]);
}
CSN=1;
return reg_value;
}
void nRF24L01_Set_RX_Mode(void)
{
CE=0;//待機
//SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,TX_Addr,TX_ADDR_WITDH);
SPI_W_Reg(W_REGISTER+EN_AA,0x01);
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);
//SPI_W_Reg(W_REGISTER+SETUP_RETR,0x0a);
SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);
SPI_W_Reg(W_REGISTER+RF_CH,0x40);
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);
SPI_W_Reg(W_REGISTER+CONFIG,0x0f);
CE=1;
_delay_ms(5);
}
uchar nRF24L01_RX_Data(void)
{
//uchar i,status;
sta=SPI_R_byte(R_REGISTER+STATUS);
if(RX_DR)
{
CE=0;
SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_DATA_WITDH);
//P3=RX_Buffer[0];
SPI_W_Reg(W_REGISTER+STATUS,0xff);
CSN=0;
SPI_RW(FLUSH_RX);
CSN=1;
return 1;
}
else
return 0;
}
void main(void)
{
uchar i,RX_Temp_Value[RX_DATA_WITDH];//ng;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
Init_LCD();
nRF24L01_Init();
_delay_us(1000);
LCD_POS(0);
Show_String(Display_LINE0);
while(1)
{
nRF24L01_Set_RX_Mode();
//_delay_ms(100);
if(nRF24L01_RX_Data())
{
for(i=0;i<RX_DATA_WITDH;i++)
{
RX_Temp_Value[i]=RX_Buffer[i];
LED=~LED;
}
}
Display_LINE1[7]=RX_Temp_Value[3]+'0';
Display_LINE1[8]=RX_Temp_Value[2]+'0';
Display_LINE1[9]=RX_Temp_Value[1]+'0';
Display_LINE1[10]='.';
Display_LINE1[11]=RX_Temp_Value[0]+'0';
Display_LINE1[12]=0xdf;
Display_LINE1[13]=0x43;
if(RX_Temp_Value[3]==0)
Display_LINE1[7]=' ';
/*if(RX_Temp_Value[2]==0&&RX_Temp_Value[3]==0)
Display_LINE1[8]=' ';
if(ng)
{
if(Display_LINE1[8]==' ')
Display_LINE1[8]='-';
else if(Display_LINE1[7]==' ')
Display_LINE1[7]='-';
else
Display_LINE1[6]='-';*/
LCD_POS(0x40);
Show_String(Display_LINE1);
}
}
已通過測試的,希望能幫助到你!
Ⅱ nrf24L01隻能接收到一次數據
拜託,串口通信怎麼能用while來做
要進中斷進行數據處理啊,寫個標志位,在接收中斷結束前置位,然後在外部的while里判斷這個標志位都可以
你在主循環里清除中斷標志是不能清除串口緩沖數據的,這樣就導致下次發送的數據無法接收,因為接受緩沖區是滿的,這個要對緩沖區進行讀取操作後才會清除.你還是把datasheet文件好好看看吧,接收數據後要對緩沖寄存器進行讀取操作來清除數據
Ⅲ nRF24l01無線模塊 程序里有個頭文件:#include<api.h> 誰知道,麻煩給下。
// BYTE type definition
#ifndef _BYTE_DEF_
#define _BYTE_DEF_
typedef unsigned char BYTE;
#endif /* _BYTE_DEF_ */
// Define interface to nRF24L01
/*#ifndef _SPI_PIN_DEF_
#define _SPI_PIN_DEF_
// Define SPI pins
/*sbit SCK = P0^0; // Master Out, Slave In pin (output)
sbit MISO = P0^1; // Master In, Slave Out pin (input)
sbit MOSI = P0^2; // Serial Clock pin, (output)
sbit CSN = P0^3; // Slave Select pin, (output to CSN, nRF24L01)
// Define CE & IRQ pins
sbit CE = P0^4; // Chip Enable pin signal (output)
sbit IRQ = P0^5; // Interrupt signal, from nRF24L01 (input)
#endif*/
// Macro to read SPI Interrupt flag
//#define WAIT_SPIF (!(SPI0CN & 0x80)) // SPI interrupt flag(礐 platform dependent)
// Declare SW/HW SPI modes
//#define SW_MODE 0x00
//#define HW_MODE 0x01
// Define nRF24L01 interrupt flag's
//#define MAX_RT 0x10 // Max #of TX retrans interrupt
//#define TX_DS 0x20 // TX data sent interrupt
//#define RX_DR 0x40 // RX data received
//#define SPI_CFG 0x40 // SPI Configuration register value
//#define SPI_CTR 0x01 // SPI Control register values
//#define SPI_CLK 0x00 // SYSCLK/2*(SPI_CLK+1) == > 12MHz / 2 = 6MHz
//#define SPI0E 0x02 // SPI Enable in XBR0 register
//****************************************************************//
// 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
//***************************************************************//
// FUNCTION's PROTOTYPES //
/****************************************************************
void SPI_Init(BYTE Mode); // Init HW or SW SPI
BYTE SPI_RW(BYTE byte); // Single SPI read/write
BYTE SPI_Read(BYTE reg); // Read one byte from nRF24L01
BYTE SPI_RW_Reg(BYTE reg, BYTE byte); // Write one byte to register 'reg'
BYTE SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes); // Writes multiply bytes to one register
BYTE SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes); // Read multiply bytes from one register
//*****************************************************************/
Ⅳ 求一個簡單的用51單片機控制NRF24L01發送數據的程序代碼 郵箱[email protected]
以前做過的一個proteus模擬,匯編。4 位共陰,段選P0,位選 P2.0~P2.3 。P3.0開始鍵,P3.1停止鍵,P3.3計步輸入。
;0~9999計數
STRT EQU P3.0
STP EQU P3.1
ORG 0000H
LJMP MAIN
ORG 0013H ;INT1入口
LJMP EX1INT
ORG 0100H ;主程序開始地址
MAIN: MOV 20H,#00H;千
MOV 21H,#00H;百
MOV 22H,#00H;十
MOV 23H,#00H;個
SETB EA ;開總中斷
k1: LCALL DISP ;調顯示子程序
JB STRT,K2
LCALL DISP
JNB STRT,$-3
AJMP START
k2: JB STP,K1
LCALL DISP
JNB STP,STOP
AJMP K1
DISP: MOV R1,#20H ;顯示偏移量
MOV R2,#04H ;顯示位數
MOV DPTR,#TABLE ;數碼管字元
MOV A,#0FEH ;位選數據
DISP1: MOV B,A
MOV P2,A ;位選
MOV A,@R1
MOVC A,@A+DPTR ;取字元碼
MOV P0,A ;送出顯示
MOV R3,#80H ;短暫延時
DJNZ R3,$
INC R1 ;指向下一位要顯示的數據
MOV A,B ;取位選數據
RL A ;指向下一位
DJNZ R2,DISP1;4位沒顯示完則繼續
RET
START: SETB EX1
SETB IT1
AJMP K1
STOP: CLR EX1
CLR IT1
AJMP K2
EX1INT: MOV R0,#23H ;個位地址
INC @R0 ;個位數加1
CJNE @R0,#0AH,IRET ;個位不為10,跳轉
MOV @R0,#00H ;個位為10,則清0
DEC R0 ;指向十位
INC @R0 ;十位加1
CJNE @R0,#0AH,IRET ;十位不為10,跳轉
MOV @R0,#00H ;十位為10,則清0
DEC R0 ;指向百位
INC @R0 ;百倍加1
CJNE @R0,#0AH,IRET ;百倍不為10,跳轉
MOV @R0,#00H ;十位為10,則清0
DEC R0 ;指向千位
INC @R0 ;千位加1
CJNE @R0,#0AH,IRET ;千位不為10,跳轉
MOV @R0,#00H
IRET: RETI
DELAY: MOV R4,#10H ;延時子程序
DJNZ R4,$
RET
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;數碼管字元表,共陰
END
Ⅳ NRF24L01無線通信,SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);中的WRITE_REG + RX_PW_P0意思是
你好:
SPI_RW_Reg(WRITE_REG+RX_PW_P0, TX_PLOAD_WIDTH),這個函數的意思是寫寄存器的值,其中WRITE_REG是寄存器地址基址,RX_PW_P0是寄存器地址的偏移量,也就是指定到了RX_PW_P0這個寄存器,第二個參數TX_PLOAD_WIDTH就是要寫入的值,這三個形參都是程序一開始經過宏定義的,當用到時會進行替換。
順便說一下,在我的網路空間里有nrf24l01p的程序和教程,不懂的可以參考一下。
希望我的回答能幫助到你。
Ⅵ 單片機nrf24l01無線模塊程序
你好:
stc52、pic16f877a、arm9、linux驅動程序的nrf常式我都有。
根據你說的四個按鍵做遙控車的程序相當簡單,配置好nrf後,在main函數里一直掃描鍵盤是否按下就行,類似如下:
然後在接收端判斷為何數據,做出相應的動作即可。
希望我的回答能幫助到你。
Ⅶ 誰能幫忙提供 51單片機與 NRF24L01 的接收和發射的匯編程序,不勝感激,謝謝!
只有C寫的
Ⅷ nrf24l01接收程序有延時就不行了。。跪求原因
可能是你的單片機型號不一樣把,所以內部分頻不一樣,是1T的還是12T的看一下數據手冊,本來延時函數是可以調節的,也是可有可無的,當然必須結合實際的晶元時序圖來規劃,如果加了延時函數不行的話,簡單,去掉就是了。也可以把50改小點試試看,比方說30,20,10等等。