|
這個(gè)是我寫的程序,大部分是網(wǎng)上找的程序,用的是15單片機(jī),然后兩個(gè)MCU通過NRF24L01通信,但不知道為什么就是通信不了,就接收不到數(shù)據(jù)。有沒有大佬找找我的問題。
單片機(jī)源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #define TX_ADR_WIDTH 5 //5字節(jié)寬度的發(fā)送/接收地址
- #define TX_PLOAD_WIDTH 4//數(shù)據(jù)通道有效數(shù)據(jù)寬度
- #define uchar unsigned char
- #define uint unsigned int
- #define out P0
- uchar code lcd1602[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
- uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定義一個(gè)靜態(tài)發(fā)送地址
- uchar RX_BUF[TX_PLOAD_WIDTH];
- uchar TX_BUF[TX_PLOAD_WIDTH];
- uchar flag;
- 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^4;
- sbit SCK = P1^2;
- sbit MOSI = P1^1;
- sbit MISO = P1^3;
- sbit IRQ = P1^0;*/
- sbit CE = P2^4;
- sbit CSN = P2^0;
- sbit SCK = P2^3;
- sbit MOSI = P2^1;
- sbit MISO = P3^3;
- sbit IRQ = P2^2;
- //SPI要使用的IO
- sbit MOSIO=P3^4;
- sbit R_CLK=P3^5;
- sbit S_CLK=P3^6;
- //SPI(NFR24L01)命令
- #define RFAD_REG 0x00 //定義讀命令以注冊(cè)
- #define WRITE_REG 0x20 //定義要寫的命令
- #define RD_RX_PLOAD 0x61 //定義RX有效負(fù)載寄存器地址
- #define WR_TX_PLOAD 0xA0 //定義TX有效負(fù)載寄存器地址
- #define FLUSH_TX 0xE1 //定義刷新 Tx寄存器命令
- #define FLUSH_RX 0xE2 //定義刷新 Rx寄存器命令
- #define REUSE_TX_PL 0xE3 //定義重復(fù)TX負(fù)載寄存器命令
- #define NOP 0xFF //定義無操作
- //SPI(NRF24L01)寄存器
- #define CONFIG 0x00 //配置寄存器地址
- #define EN_AA 0x01 //“啟用自動(dòng)確認(rèn)”的注冊(cè)地址
- #define EN_RXADDR 0x02 //'Enabled RX addresses'寄存器地址
- #define SETUP_AW 0x03 //“設(shè)置地址寬度”寄存器地址
- #define SETUP_RETR 0x04 //“自動(dòng)設(shè)置。Retrans的寄存器地址
- #define RF_CH 0x05 // '射頻信道'寄存器地址
- #define RF_SETUP 0x06 //射頻設(shè)置寄存器地址
- #define STATUS 0x07 // 狀態(tài)寄存器地址
- #define OBSERVE_TX 0x08 //“收到Tx”寄存器地址
- #define CD 0x09 //"載波檢測(cè)'寄存器地址
- #define RX_ADDR_P0 0x0A //RX地址0管道的寄存器地址
- #define RX_ADDR_P1 0x0B //RX地址1管道的寄存器地址
- #define RX_ADDR_P2 0x0C //RX地址2管道的寄存器地址
- #define RX_ADDR_P3 0x0D //RX地址3管道的寄存器地址
- #define RX_ADDR_P4 0x0E //RX地址4管道的寄存器地址
- #define RX_ADDR_P5 0x0F //RX地址5管道的寄存器地址
- #define TX_ADDR 0x10 //“Tx address”的寄存器地址
- #define RX_PW_P0 0x11 //"RX有效載荷寬度,0管'寄存器地址
- #define RX_PE_P1 0x12 //"RX有效載荷寬度,1管'寄存器地址
- #define RX_PE_P2 0x13 //"RX有效載荷寬度,2管'寄存器地址
- #define RX_PE_P3 0x14 //"RX有效載荷寬度,3管'寄存器地址
- #define RX_PE_P4 0x15 //"RX有效載荷寬度,4管'寄存器地址
- #define RX_PE_P5 0x16 //"RX有效載荷寬度,5管'寄存器地址
- #define FIFO_STATUS 0x17 //“FIFO狀態(tài)寄存器”的寄存器地址
- void delay500ms(void);
- void lcd_initial (void); //LCD1602初始化
- void write_data(uchar dat); //寫數(shù)據(jù)函數(shù)
- void check_busy (void); //忙檢測(cè)
- void write_command (uchar com); //寫命令函數(shù)
- void string (uchar ad,uchar *s);//字符寫入,(字符開始地址,字符)
- void delay100ms(void); //延時(shí)100MS
- void delay10ms(void); //延時(shí)10MS
- void delay1ms(void); //延時(shí)1ms
- uchar ajlb(uchar x); //按鍵濾波
- uchar JCAJ(void); //檢測(cè)按鍵按下
- uchar HC08JS = 0;
- bit flag1 = 0;
- sbit E=P2^5;
- sbit RW=P2^6;
- sbit RS=P2^7;
- sbit FMQ=P1^2;
- sbit BG=P2^4;
- sbit DQ=P1^0;
- sbit K1=P1^3;
- sbit K2=P1^4;
- sbit K3=P1^5;
- sbit K4=P1^6;
- sfr AUXR = 0x8E;
- sfr T2H = 0xd6;
- sfr T2L = 0xd7;
- void lcd_initial (void) //LCD1602初始化
- {
- write_command(0x38);//寫入0x38(命令6):兩行顯示,5X7點(diǎn)陣,8位數(shù)據(jù)接口
- _nop_(); //空操作
- write_command(0x0C);//寫入0x38(命令4):開整體顯示,光標(biāo)關(guān),無閃爍
- _nop_(); //空操作
- write_command(0x04);//寫入0x38(命令3):
- _nop_(); //空操作
- write_command(0x01);//寫入0x38(命令1):清屏
- delay1ms();
- }
- void check_busy (void)//忙檢測(cè)
- {
- uchar dt;
- do
- {
- dt=0xff; //dt為變量單元,初值為0xff
- E=0;
- RS=0;
- RW=1;
- E=1;
- dt=out; //out為L(zhǎng)CD數(shù)據(jù)口,將out的狀態(tài)送入dt
- }
- while(dt&0x80); //如果忙標(biāo)志位BF=1,繼續(xù)循環(huán)檢測(cè),等待BF=0
- E=0; //BF=0,LCD不忙,結(jié)束檢測(cè)
- }
- void write_command (uchar com)//寫命令函數(shù)
- {
- check_busy();
- E=0;
- RS=0; //RS與E同時(shí)為零時(shí)。才可以寫入命令
- RW=0;
- out=com; //將命令com寫入數(shù)據(jù)口
- E=1; //寫入命令時(shí),E為上升沿,所以E開始為0
- _nop_();
- E=0; //E由高變低,LCD開始執(zhí)行命令
- delay1ms();
- }
- void write_data(uchar dat) //寫數(shù)據(jù)函數(shù)
- {
- check_busy();
- E=0;
- RS=1;
- RW=0;
- out=dat;
- E=1;
- _nop_();
- E=0;
- delay1ms();
- }
- void string (uchar ad,uchar *s)
- {
- write_command(ad);
- while(*s>0)
- {
- write_data(*s++); //輸出字符串,且指針加一
- delay1ms();
- }
- }
- void string1(uchar ad,uchar a)
- {uchar b=0,c=0;
- write_command(ad);
- ad=ad+0x01;
- b=a/10;
- b=lcd1602[b];
- write_data(b);
- c=a%10;
- c=lcd1602[c];
- write_data(c);
-
- }
- void lcd_xs(uchar a)
- {
- if(a==0)
- {string(0x83,"->NRF24L01");
- string(0xC5,"HC-08");
- }
- else if(a==1)
- {string(0x83,"->HC-08");
- string(0xC5,"EV1527");
- }
- else if(a==2)
- {string(0x83,"->EV1527");
- string(0xC5,"NRF24L01");
- }
- }
- void delay5us(void) //誤差 0us
- {
- unsigned char a;
- for(a=12;a>0;a--);
- }
- void delay5(uchar n) //延時(shí)5us程序
- {
- do
- {
- delay5us();
- n--;
- }
- while(n);
- }
- void delay1ms(void) //誤差 0us
- {
- unsigned char a,b;
- for(b=222;b>0;b--)
- for(a=12;a>0;a--);
- }
- void delay10ms(void) //誤差 -0.000000000001us
- {
- unsigned char a,b;
- for(b=202;b>0;b--)
- for(a=147;a>0;a--);
- }
- void delay50ms(void) //誤差 -0.000000000003us
- {
- unsigned char a,b,c;
- for(c=6;c>0;c--)
- for(b=116;b>0;b--)
- for(a=214;a>0;a--);
- }
- void delay100ms(void) //誤差 -0.000000000006us
- {
- unsigned char a,b,c;
- for(c=246;c>0;c--)
- for(b=116;b>0;b--)
- for(a=9;a>0;a--);
- }
- //////////////////////////////////////////////////////DS18B20程序開頭
- void init_ds18b20(void) //18B20初始化
- {
- uchar x=0;
- DQ=0;
- delay5(120);
- DQ=1;
- delay5(16);
- delay5(80);
- }
- uchar readbyte(void) //讀取1字節(jié)數(shù)據(jù)
- {
- uchar i=0;
- uchar date=0;
- for(i=8;i>0;i--)
- {
- DQ=0;
- delay5(1);
- DQ=1;
- date>>=1;
- if(DQ)
- date|=0x80;
- delay5(11);
- }
- return(date);
- }
- void writebyte(uchar dat) //寫1B函數(shù)
- {
- uchar i=0;
- for(i=8;i>0;i--)
- {
- DQ=0;
- DQ=dat&0x01;
- delay5(12);
- DQ=1;
- dat>>=1;
- delay5(5);
- }
- }
- uchar retemp(void) //讀取溫度
- {
- uchar a,b,tt;
- uint t;
- init_ds18b20();
- writebyte(0xcc);
- writebyte(0x44);
- init_ds18b20();
- writebyte(0xcc);
- writebyte(0xBE);
- a=readbyte();
- b=readbyte();
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
-
- return(tt);
- }
- ////////////////////////////////////////////DS18B20程序結(jié)尾
- //NFR24L01發(fā)送
- void init_io (void) //2401初始化
- {
- CE =0; //待機(jī)
- CSN=1; //SPI禁止
- SCK=0; //SPI時(shí)鐘置低
- IRQ=1; //中斷復(fù)位
- }
- uchar SPI_RW(uchar byte) //根據(jù)spi協(xié)議,寫一節(jié)數(shù)據(jù)到2401,同時(shí)讀出一節(jié)數(shù)據(jù)
- {
- uchar i;
- for(i=0;i<8;i++) //循環(huán)8次
- {
- MOSI=(byte&0x80); //byte最高位輸出到MOSI
- byte<<=1; //低一位移到最高位
- SCK=1;
- byte |=MISO; //讀MSIO到byte最低位
- SCK=0;
- }
- return(byte); //發(fā)回讀出的一字節(jié)
- }
- uchar SPI_RW_Reg(uchar reg, uchar value) //寫數(shù)據(jù)value到reg寄存器
- {
- uchar status;
- CSN = 0; // CSN置低,開始傳輸數(shù)據(jù)
- status = SPI_RW(reg); // 選擇寄存器,同時(shí)返回狀態(tài)字
- SPI_RW(value); // 然后寫數(shù)據(jù)到該寄存器
- CSN = 1; // CSN拉高,結(jié)束數(shù)據(jù)傳輸
- return(status); // 返回狀態(tài)寄存器
- }
- uchar SPI_Read(uchar reg) //從reg寄存器讀一字節(jié)
- {
- uchar reg_val;
- CSN=0; //CSN置低,開始傳輸數(shù)據(jù)
- SPI_RW(reg);
- reg_val=SPI_RW(0);
- CSN=1;
- return(reg_val);
- }
- uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes) //從reg寄存器讀出bytes個(gè)字節(jié),通常用來讀取接收通道數(shù)據(jù)或接收/發(fā)送地址
- {
- uchar status,i;
- CSN=0;
- status=SPI_RW(reg);
- for(i=0;i<bytes;i++)
- pBuf[i]=SPI_RW(0);
- CSN=1;
- return(status);
- }
- uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) //把pBuf緩存中的數(shù)據(jù)寫入到nRF24L01,通常用來寫入發(fā)射通道數(shù)據(jù)或接收/發(fā)送地址
- {
- uchar status, i;
- CSN = 0; // CSN置低,開始傳輸數(shù)據(jù)
- status = SPI_RW(reg); // 選擇寄存器,同時(shí)返回狀態(tài)字
- for(i=0; i<bytes; i++)
- SPI_RW(pBuf[i]); // 逐個(gè)字節(jié)寫入nRF24L01
- CSN = 1; // CSN拉高,結(jié)束數(shù)據(jù)傳輸
- return(status); // 返回狀態(tài)寄存器
- }
- void RX_Mode(void) //這個(gè)函數(shù)設(shè)置nRF24L01為接收模式,等待接收發(fā)送設(shè)備的數(shù)據(jù)包
- {
- CE = 0;
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 接收設(shè)備接收通道0使用和發(fā)送設(shè)備相同的發(fā)送地址
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自動(dòng)應(yīng)答
- 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選擇和發(fā)送通道相同有效數(shù)據(jù)寬度
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 數(shù)據(jù)傳輸率1Mbps,發(fā)射功率0dBm,低噪聲放大器增益
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校驗(yàn),上電,接收模式
- CE = 1; // 拉高CE啟動(dòng)接收設(shè)備
- }
- void TX_Mode(uchar * BUF)
- {
- CE = 0;
- SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 寫入發(fā)送地址
- SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 為了應(yīng)答接收設(shè)備,接收通道0地址和發(fā)送地址相同
- SPI_Write_Buf(WR_TX_PLOAD, BUF, TX_PLOAD_WIDTH); // 寫數(shù)據(jù)包到TX FIFO
- SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自動(dòng)應(yīng)答
- SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
- SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a); // 自動(dòng)重發(fā)延時(shí)等待250us+86us,自動(dòng)重發(fā)10次
- SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 選擇射頻通道0x40
- SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 數(shù)據(jù)傳輸率1Mbps,發(fā)射功率0dBm,低噪聲放大器增益
- SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // CRC使能,16位CRC校驗(yàn),上電
- CE = 1;
- }
- uchar Check_ACK(bit clear) //檢查接收設(shè)備有無接收到數(shù)據(jù)包,設(shè)定沒有收到應(yīng)答信號(hào)是否重發(fā)
- {
- while(IRQ);
- sta = SPI_RW(NOP); // 返回狀態(tài)寄存器
- if(MAX_RT)
- if(clear) // 是否清除TX FIFO,沒有清除在復(fù)位MAX_RT中斷標(biāo)志后重發(fā)
- SPI_RW(FLUSH_TX);
- SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中斷標(biāo)志
- IRQ = 1;
- if(TX_DS)
- return(0x00);
- else
- return(0xff);
- }
- void NRF24L01_CX(void) //NRF24L01程序執(zhí)行
- {uchar b=1,temp,a=0,temp1=0x00;
- FMQ=1;
- lcd_initial(); //調(diào)用lcd初始化
- string(0x80,"24L01TXD:");
- string(0xc0,"RXD:");
- init_io();
- while(b)
- {
- temp=retemp();
- string1(0x8A,temp);
- TX_BUF[0] = ~temp; // 數(shù)據(jù)送到緩存
- TX_Mode(TX_BUF); // 把nRF24L01設(shè)置為發(fā)送模式并發(fā)送數(shù)據(jù)
- //IRQ=0;
- a=JCAJ();
- if(a==4)
- b=0;
- Check_ACK(1); // 等待發(fā)送完畢,清除TX FIFO
- RX_Mode(); // 設(shè)置為接收模式
- sta = SPI_Read(STATUS); // 讀狀態(tài)寄存器
- if(RX_DR) // 判斷是否接受到數(shù)據(jù)
- {
- SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, TX_PLOAD_WIDTH); // 從RX FIFO讀出數(shù)據(jù)
- flag = 1;
- }
- SPI_RW_Reg(WRITE_REG + STATUS, sta); // 清除RX_DS中斷標(biāo)志
- if(flag) // 接受完成
- {
- flag = 0; // 清標(biāo)志
- temp1 = RX_BUF[0]; // 數(shù)據(jù)送到temp1
- }
- string1(0xCA,temp1);
- delay50ms();
- a=JCAJ();
- if(a==4)
- b=0;
- }
-
- }uchar JCAJ(void) //檢測(cè)按鍵按下
- {
- uchar x=0,y=0;
- if(K1==0)
- {y=1;
- x=ajlb(y);
- return x;
- }
- else if(K2==0)
- {y=2;
- x=ajlb(y);
- return x;
- }
- else if(K3==0)
- {y=3;
- x=ajlb(y);
- return x;
- }
- else if(K4==0)
- {y=4;
- x=ajlb(y);
- return x;
- }
- return x;
- }
- uchar ajlb(uchar x) //按鍵濾波
- {
- delay10ms();
- if(x==1)
- {
- if(K1==0)
- {return x;}
- else
- {x=0;
- return x;}
- }
- else if(x==2)
- {
- if(K2==0)
- {return x;}
- else
- {x=0;
- return x;}
- }
- else if(x==3)
- {
- if(K3==0)
- {return x;}
- else
- {x=0;
- return x;}
- }
- else if(x==4)
- {
- if(K4==0)
- {return x;}
- else
- {x=0;
- return x;}
- }
- return x;
- }
- void main ()
- {
-
- NRF24L01_CX();
- }
復(fù)制代碼 |
|