本人親測成功可用,感興趣的可以試試,nRF24L01無線芯片和stc的51單片機構成
制作出來的實物圖如下:
3.jpg (2.15 MB, 下載次數: 144)
下載附件
2018-8-31 08:12 上傳
2.jpg (1.52 MB, 下載次數: 112)
下載附件
2018-8-31 08:12 上傳
1.jpg (476.55 KB, 下載次數: 136)
下載附件
2018-8-31 08:12 上傳
QQ圖片20180831075104.png (3.12 KB, 下載次數: 182)
下載附件
2018-8-31 07:51 上傳
0.jpg (57.16 KB, 下載次數: 133)
下載附件
2018-8-31 15:24 上傳
單片機源程序如下:
- #include<reg51.h>
- #define u8 unsigned char
- #define u16 unsigned int
- sfr IAP_DATA=0xe2;
- sfr IAP_ADDRH=0xe3;
- sfr IAP_ADDRL=0xe4;
- sfr IAP_CMD=0xe5;
- sfr IAP_TRIG=0xe6;
- sfr IAP_CONTR=0xe7;
- sfr AUXR=0x8e;
- sfr BRT=0x9c;
- sbit LED=P2^2;
- //sbit LED=P2^3;
- sbit CH1=P2^1;
- sbit CH2=P2^0;
- sbit CH3=P1^7;
- sbit CH4=P1^6;
- sbit CH5=P1^5;
- sbit CH6=P1^4;
- sbit CH7=P1^3;
- sbit CH8=P1^1;
- sbit CHB=P1^0;
- sbit CHC=P3^7;
- sbit CHD=P2^7;
- sbit CHE=P2^6;
- sbit MDO=P3^5;
- sbit SCK=P2^4;
- sbit CE=P2^5;
- sbit IRQ=P3^4;
- sbit MDI=P3^3;
- sbit CSN=P3^2;
- sfr P1M1=0x92;
- sfr P3M1=0xb2;
- sfr P2M1=0x96;
- u8 code random[100]={4,1,3,2,2,1,0,0,2,2,2,3,4,1,2,1,4,3,3,4,//隨機跳頻序列
- 2,0,2,2,3,1,2,3,2,2,2,4,2,4,0,3,4,2,3,1,
- 0,3,1,3,3,0,2,0,4,3,3,3,3,3,4,1,1,4,3,0,
- 1,0,3,2,3,2,3,3,4,4,1,3,0,0,3,1,3,3,3,0,
- 3,3,4,1,2,4,1,3,0,1,3,4,4,3,2,3,1,2,3,3};
- u16 timer1,timer2,timer3;
- u8 rx_num,receive;
-
- u8 rx[11]; //接收的11字節數據
- u8 tx[11];
- u8 m;
- u8 hopping_turn,hopping_num,hopping_count;
- //u8 missing_data[4];
- u8 address[5]={0xe7,0xe7,0xe7,0xe7,0xe7};
- u8 code address_0[5]={'L','O','V','E','!'};//使用LOVE作為對頻暗語
- u8 hopping[5]={10,35,60,85,110};
- bit first,restar;
- bit connecting,lose;
- bit jump_1,jump_2,jump_mode;
- u8 NRF_error;
- u16 CH_data[8]={0,1024,0,1024,0,1024};
- u16 data buff[8];
- u16 temp1,temp2;
- u8 t_output;
- u8 TX_power=3;
- bit LED_flash;
- bit out_control_change;
- u16 idata out_control_data[8];
- void Delay1ms() //@12.000MHz
- {
- unsigned char i, j;
- i = 12;
- j = 168;
- do
- {
- while (--j);
- } while (--i);
- }
- void delay_ms(u8 i)
- {
- while(i--)
- Delay1ms();
- }
- u8 EEPROM_read(u8 address)
- {
- IAP_CMD=0x01;
- IAP_ADDRH=0;
- IAP_ADDRL=address;
- IAP_TRIG=0x46;
- IAP_TRIG=0xb9;
- return IAP_DATA;
- }
- void EEPROM_write(u8 address,u8 byte)
- {
- IAP_CMD=0x02;
- IAP_DATA=byte;
- IAP_ADDRH=0;
- IAP_ADDRL=address;
- IAP_TRIG=0x46;
- IAP_TRIG=0xb9;
-
- }
- void EEPROM_clean(u8 address)
- {
- IAP_CMD=0x03;
- IAP_ADDRH=0;
- IAP_ADDRL=address;
- IAP_TRIG=0x46;
- IAP_TRIG=0xb9;
- }
- void DATA_read()
- {
- IAP_CONTR=0x82;
- if((EEPROM_read(0)!=0xe4)||(EEPROM_read(1)!=0xa5))
- {
- first=1;
- }
- else
- {
- hopping[0]=EEPROM_read(2);
- hopping[1]=EEPROM_read(3);
- hopping[2]=EEPROM_read(4);
- hopping[3]=EEPROM_read(5);
- hopping[4]=EEPROM_read(6);
- address[0]=EEPROM_read(7);
- address[1]=EEPROM_read(8);
- address[2]=EEPROM_read(9);
- address[3]=EEPROM_read(10);
- address[4]=EEPROM_read(11);
- }
-
- if((EEPROM_read(12)!=0xe4)||(EEPROM_read(13)!=0xa5))
- {
- out_control_data[0]=512;
- out_control_data[1]=512;
- out_control_data[2]=80;
- out_control_data[3]=512;
- out_control_data[4]=512;
- out_control_data[5]=512;
- out_control_data[6]=512;
- out_control_data[7]=512;
- }
- else
- {
-
- out_control_data[0]=EEPROM_read(14);
- out_control_data[0]<<=8;
- out_control_data[0]+=EEPROM_read(15);
- out_control_data[1]=EEPROM_read(16);
- out_control_data[1]<<=8;
- out_control_data[1]+=EEPROM_read(17);
- out_control_data[2]=EEPROM_read(18);
- out_control_data[2]<<=8;
- out_control_data[2]+=EEPROM_read(19);
- out_control_data[3]=EEPROM_read(20);
- out_control_data[3]<<=8;
- out_control_data[3]+=EEPROM_read(21);
- out_control_data[4]=EEPROM_read(22);
- out_control_data[4]<<=8;
- out_control_data[4]+=EEPROM_read(23);
- out_control_data[5]=EEPROM_read(24);
- out_control_data[5]<<=8;
- out_control_data[5]+=EEPROM_read(25);
- out_control_data[6]=EEPROM_read(26);
- out_control_data[6]<<=8;
- out_control_data[6]+=EEPROM_read(27);
- out_control_data[7]=EEPROM_read(28);
- out_control_data[7]<<=8;
- out_control_data[7]+=EEPROM_read(29);
- }
-
-
- IAP_CONTR=0;
- }
- void DATA_save()
- {
- IAP_CONTR=0x82;
- EEPROM_clean(0);
- EEPROM_write(0,0xe4);
- EEPROM_write(1,0xa5);
- EEPROM_write(2,hopping[0]);
- EEPROM_write(3,hopping[1]);
- EEPROM_write(4,hopping[2]);
- EEPROM_write(5,hopping[3]);
- EEPROM_write(6,hopping[4]);
- EEPROM_write(7,address[0]);
- EEPROM_write(8,address[1]);
- EEPROM_write(9,address[2]);
- EEPROM_write(10,address[3]);
- EEPROM_write(11,address[4]);
-
- if(out_control_change)
- {
- EEPROM_write(12,0xe4);
- EEPROM_write(13,0xa5);
-
- EEPROM_write(14,out_control_data[0]>>8);
- EEPROM_write(15,out_control_data[0]);
- EEPROM_write(16,out_control_data[1]>>8);
- EEPROM_write(17,out_control_data[1]);
- EEPROM_write(18,out_control_data[2]>>8);
- EEPROM_write(19,out_control_data[2]);
- EEPROM_write(20,out_control_data[3]>>8);
- EEPROM_write(21,out_control_data[3]);
- EEPROM_write(22,out_control_data[4]>>8);
- EEPROM_write(23,out_control_data[4]);
- EEPROM_write(24,out_control_data[5]>>8);
- EEPROM_write(25,out_control_data[5]);
- EEPROM_write(26,out_control_data[6]>>8);
- EEPROM_write(27,out_control_data[6]);
- EEPROM_write(28,out_control_data[7]>>8);
- EEPROM_write(29,out_control_data[7]);
- }
-
-
-
-
-
-
- IAP_CONTR=0;
- }
- /**************************************************************************/
- //NRF24L01
- u8 SPI(u8 byte)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- MDI=(byte&0x80);
- SCK=1;
- byte<<=1;
- byte|=MDO;
- SCK=0;
- }
- return byte;
- }
- void REG_write(u8 address,u8 command)
- {
- CSN=0;
- SPI(0x20+address);
- SPI(command);
- CSN=1;
- }
- void FIFO_write(u8 DATA_OUT[],u8 lengh)
- {
- u8 i;
- CSN=0;
- SPI(0xa0);
- for(i=0;i<lengh;i++)
- SPI(DATA_OUT[i]);
- CSN=1;
- }
- void FIFO_read(u8 DATA_IN[],u8 lengh) //讀取接收數據緩沖區
- {
- u8 i;
- CSN=0;
- SPI(0x61); //讀取命令
- for(i=0;i<lengh;i++)
- DATA_IN[i]=SPI(0);
- CSN=1;
- }
- void TX_address(u8 DATA_IN[])
- {
- CSN=0;
- SPI(0x20+0x10);
- SPI(DATA_IN[0]);
- SPI(DATA_IN[1]);
- SPI(DATA_IN[2]);
- SPI(DATA_IN[3]);
- SPI(DATA_IN[4]);
- CSN=1;
- }
- void RX_address(u8 DATA_IN[])
- {
- CSN=0;
- SPI(0x20+0x0a);
- SPI(DATA_IN[0]);
- SPI(DATA_IN[1]);
- SPI(DATA_IN[2]);
- SPI(DATA_IN[3]);
- SPI(DATA_IN[4]);
- CSN=1;
- }
- void RX_mode()
- {
- CE=0;
- REG_write(0x00,0x3b); //CRC,8 bit,Power on,RX
- CE=1;
- }
-
- void TX_mode()
- {
- CE=0;
- REG_write(0x00,0x0a);
- CE=1;
- }
- void NRF_power(u8 P) //發射功率設置 250k
- {
- CE=0;
- if(P==3)REG_write(0x06,0x27); //0db 修正之前注釋錯誤
- else if(P==2)REG_write(0x06,0x25); //-6db
- else if(P==1)REG_write(0x06,0x23); //-12db
- else if(P==0)REG_write(0x06,0x21); //-18db
- CE=1;
- }
- void NRF_size(u8 l)
- {
- CE=0;
- REG_write(0x11,l);
- CE=1;
- }
- void NRF_channel(u8 c)
- {
- CE=0;
- REG_write(0x05,c);
- CE=1;
- }
- void NRF_init()
- {
- CE=0;
- SCK=0;
- REG_write(0x01,0x00); //禁止 自動應答
- REG_write(0x02,0x01); //允許 P0信道
- REG_write(0x04,0x00); //禁止 自動重發
- RX_mode();
- NRF_channel(66);
- NRF_power(TX_power);
- NRF_size(11);
- RX_address(address);
- TX_address(address);
- }
- void NRF_test() //無線模塊終極測試
- {
- u8 reset_err=0;
- CE=0;
- SCK=0;
- CSN=0;
-
- if(SPI(0x20)!=0x0e){reset_err=1;}
- SPI(0x0a);
- CSN=1;
- CSN=0;
- SPI(0x00);
- if(SPI(0x00)!=0x0a){NRF_error|=0x02;}//MOSI bad
- CSN=1;
- REG_write(0x01,0x00);
- REG_write(0x04,0x00);
- REG_write(0x11,1);
-
- FIFO_write(tx,1);
- CE=1;
- delay_ms(2);
-
- CSN=0;
- if(SPI(0x00)!=0x2e){NRF_error|=0x04;}//CE bad
- CSN=1;
-
- if(IRQ)NRF_error|=0x18; //IRQ bad
- else
- {
- if(NRF_error&0x04==0)NRF_error|=0x10; //MISO bad
- }
- CE=1;
-
- if(reset_err&&NRF_error>1)NRF_error|=0x01;//CSN,CLK bad
-
- REG_write(0x07,0x20); //清除TX中斷信號
- }
- void data_check(int x,int max,int min)
- {
-
- if(x>max)x=max;
- if(x<min)x=min;
- }
- void initial()
- {
- u8 t;
-
- CH5=0; //如果CH5與CH6被短接,重新對碼
- Delay1ms();
- if(CH6==0) //新增修正通道6插上舵機不能用的BUG
- {
- P1M1=0x08; //插上舵機也會使CH6為0,所以將CH5設為推挽
- CH5=1;
- Delay1ms();
- if(CH6)restar=1; //如果CH6被拉高,說明5/6通道短接,啟動重新對碼
- }
-
- LED=0; //點亮指示燈再關閉,表示單片機正常工作
- delay_ms(100);
- P1M1=0xfb;
- P2M1=0xc7;
- P3M1=0x80; //將6通道輸出IO口配置為大電流推挽模式,保證正常驅動電調與舵機
- TMOD=0x11; //允許兩個定時器中斷
- IE=0x8a;
- IP=0x08;
- if(restar)first=1;
- DATA_read();
-
- data_check(out_control_data[0],1023,0);
- data_check(out_control_data[1],1023,0);
- data_check(out_control_data[2],1023,0);
- data_check(out_control_data[3],1023,0);
- data_check(out_control_data[4],1023,0);
- data_check(out_control_data[5],1023,0);
- data_check(out_control_data[6],1023,0);
- data_check(out_control_data[7],1023,0);
-
- NRF_test();
- if(NRF_error)
- {
- t=10;
- while(t)
- {
- LED=0; //模塊錯誤閃燈
- delay_ms(50);
- LED=1; //模塊錯誤閃燈
- delay_ms(50);
- t--;
- }
- }
-
- NRF_init();
-
-
- if(first)
- {
- NRF_power(0);
- NRF_channel(33);
- TX_address(address_0);
- RX_address(address_0);
- while(IRQ);
- FIFO_read(rx,11); //讀取接收數據
- CE=0;
- REG_write(0x07,0x40); //清除無線模塊中斷信號
- CE=1;
- if(rx[0]==0xa0)
- {
- hopping[0]=rx[1];
- hopping[1]=rx[2];
- hopping[2]=rx[3];
- hopping[3]=rx[4];
- hopping[4]=rx[5];
- address[0]=rx[6];
- address[1]=rx[7];
- address[2]=rx[8];
- address[3]=rx[9];
- address[4]=rx[10];
- }
-
- tx[0]='O',tx[1]='K';
- connecting=1;
- while(connecting)
- {
- TX_mode();
- NRF_channel(33);
- TX_address(address_0);
- RX_address(address_0);
- FIFO_write(tx,11);
- Delay1ms();
-
- RX_mode();
- NRF_channel(hopping[0]);
- TX_address(address);
- RX_address(address);
- while(1)
- {
- Delay1ms();
- if(IRQ==0)
- {
- FIFO_read(rx,11); //讀取接收數據
- CE=0;
- REG_write(0x07,0x40); //清除無線模塊中斷信號
- CE=1;
- connecting=0;break;
- }
- t++;if(t>100){t=0;break;}
- }
- }
- DATA_save();
- RX_address(address);
- TX_address(address);
- NRF_power(3);
- }
-
- }
-
- main()
- {
- delay_ms(200);delay_ms(200);//開機延時以避過電源波動
-
- initial();
- PCON |= 0x80; //使能波特率倍速位SMOD
- SCON = 0x50; //8位數據,可變波特率
- AUXR |= 0x04; //獨立波特率發生器時鐘為Fosc,即1T
- BRT = 0xF3; //設定獨立波特率發生器重裝值
- AUXR |= 0x01; //串口1選擇獨立波特率發生器為波特率發生器
- AUXR |= 0x10;
-
-
- TR0=1; //打開定時器
-
- NRF_channel(hopping[0]);
-
-
- while(IRQ);
- TR1=1;
- lose=1;
- LED=1;
- while(1)
- {
- while(IRQ&lose);
- if(lose)
- {
- jump_1=0;jump_2=0;hopping_count=0;//收到有效信號后刷新跳頻器
- receive++;timer1=0;timer3=0;m=0;
-
- FIFO_read(rx,11); //讀取接收數據
- CE=0;
- REG_write(0x07,0x40); //清除無線模塊中斷信號
- CE=1;
-
- TX_mode();
- tx[0]=rx_num;
- tx[1]=0;
- tx[2]=0;
- tx[3]=0;
- tx[4]=0;
- FIFO_write(tx,11);
- Delay1ms();
- RX_mode();
-
- if(jump_mode)
- {
- jump_mode=0;
- hopping_turn=random[hopping_num];
- }
- hopping_turn++;
- if(hopping_turn>4)hopping_turn=0;
- NRF_channel(hopping[hopping_turn]);
-
- if(rx[0]==0xa0)
- {
- LED_flash=1,LED=0;
- buff[0]=rx[1];
- buff[0]<<=2;
- buff[0]+=rx[2]>>6;
- buff[1]=rx[2]&0x3f;
- buff[1]<<=4;
- buff[1]+=rx[3]>>4;
- buff[2]=rx[3]&0x0f;
- buff[2]<<=6;
- buff[2]+=rx[4]>>2;
- buff[3]=rx[4]&0x03;
- buff[3]<<=8;
- buff[3]+=rx[5];
- buff[4]=rx[6];
- buff[4]<<=2;
- buff[4]+=rx[7]>>6;
- buff[5]=rx[7]&0x3f;
- buff[5]<<=4;
- buff[5]+=rx[8]>>4;
- buff[6]=rx[8]&0x0f;
- buff[6]<<=6;
- buff[6]+=rx[9]>>2;
- buff[7]=rx[9]&0x03;
- buff[7]<<=8;
- buff[7]+=rx[10];
-
-
- data_check(buff[0],1023,0);
- data_check(buff[1],1023,0);
- data_check(buff[2],1023,0);
- data_check(buff[3],1023,0);
- data_check(buff[4],1023,0);
- data_check(buff[5],1023,0);
- data_check(buff[6],1023,0);
- data_check(buff[7],1023,0);
-
- out_control_data[0]=buff[0];
- out_control_data[1]=buff[1];
- out_control_data[2]=buff[2];
- out_control_data[3]=buff[3];
- out_control_data[4]=buff[4];
- out_control_data[5]=buff[5];
- out_control_data[6]=buff[6];
- out_control_data[7]=buff[7];
-
- out_control_change=1;
- DATA_save();
- out_control_change=0;
-
- }
- else if(rx[0]==0xa1)
- {
- buff[0]=rx[1];
- buff[0]<<=2;
- buff[0]+=rx[2]>>6;
- buff[1]=rx[2]&0x3f;
- buff[1]<<=4;
- buff[1]+=rx[3]>>4;
- buff[2]=rx[3]&0x0f;
- buff[2]<<=6;
- buff[2]+=rx[4]>>2;
- buff[3]=rx[4]&0x03;
- buff[3]<<=8;
- buff[3]+=rx[5];
- buff[4]=rx[6];
- buff[4]<<=2;
- buff[4]+=rx[7]>>6;
- buff[5]=rx[7]&0x3f;
- buff[5]<<=4;
- buff[5]+=rx[8]>>4;
- buff[6]=rx[8]&0x0f;
- buff[6]<<=6;
- buff[6]+=rx[9]>>2;
- buff[7]=rx[9]&0x03;
- buff[7]<<=8;
- buff[7]+=rx[10];
-
-
- data_check(buff[0],1023,0);
- data_check(buff[1],1023,0);
- data_check(buff[2],1023,0);
- data_check(buff[3],1023,0);
- data_check(buff[4],1023,0);
- data_check(buff[5],1023,0);
- data_check(buff[6],1023,0);
- data_check(buff[7],1023,0);
-
- CH_data[0]=buff[0];
- CH_data[1]=buff[1];
- CH_data[2]=buff[2];
- CH_data[3]=buff[3];
- CH_data[4]=buff[4];
- CH_data[5]=buff[5];
- CH_data[6]=buff[6];
- CH_data[7]=buff[7];
- }
-
-
- }
- else
- {
- hopping_count++;
- if(hopping_count>5)jump_mode=1;
-
- if(jump_mode)
- {
- hopping_num++;
- if(hopping_num>99)hopping_num=0;
- NRF_channel(hopping[random[hopping_num]]);
- lose=1;
- }
- else
- {
- hopping_turn++;
- if(hopping_turn>4)hopping_turn=0;
- NRF_channel(hopping[hopping_turn]);
- lose=1;
- }
-
- }
-
- }
-
- }
- void et0()interrupt 1 //跳頻定時器 3ms
- {
- TL0=0x47;TH0=0xf4;
- timer1++;
- if(timer1>333) //每秒統計有效信號,小于20個點亮LED示警,表示信號微弱
- {
- timer1=333;
- rx_num=0;LED=0;
- }
- else LED=1;
-
- timer2++;
- if(timer2>333)
- {
- timer2=0;
- rx_num=receive;
- receive=0;
- }
-
- timer3++;
- if(timer3>666)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
蘿莉遙控.rar
(236.02 KB, 下載次數: 741)
2018-8-31 07:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|