在上一次用開發板做小車后 繼續深入研究 把開發板換成了PCB 遙控器用兩個模擬量搖桿,達到了玩小車的樂趣 , 又在原有的基礎上增加了超聲波數據回傳,實現了數據收發,而且程序也有了很大的優化 ,速度變得更快了點,最重要的還是用了PCB ,買一些元器件就可以自己做電路,特別適合學生DIY,我也是用腐刻做板的,所以不用擔心很復雜。直接附上圖片吧。
制作出來的實物圖如下:
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
nRF24L01無線發射檢測:
1、將nRF24L01模塊按照正確方向插到J11端子上;
2、MINI USB連接線給開發板通電下載程序,下載軟件中內部IRC時鐘選擇11.0592MHZ;
3、下載程序后,開發板藍色指示燈會不停閃爍,表示無線發送正常;
4、此時,如果有下發接收程序的開發板,則可以觀察到有表示接收到的紅色指示燈閃爍。
注:該實驗需要配合接收實驗進行。
nRF24L01無線接收實驗:
1、將nRF24L01模塊按照正確方向插到J11端子上;
2、MINI USB連接線給開發板通電下載程序,下載軟件中內部IRC時鐘選擇11.0592MHZ;
3、下載程序后,開發板紅色指示燈會常亮,表示沒有接收到無線信號;
4、此時,如果有下發發送程序的開發板,則可以觀察到該接收板上的紅色指示燈閃爍。
注:該實驗需要配合發送實驗進行。
單片機源程序如下:
- /****************************************Copyright (c)****************************************************
- **
- **
- **
- **--------------File Info---------------------------------------------------------------------------------
- ** File name:
- ** Last modified Date:
- ** Last Version:
- ** Descriptions:
- **--------------------------------------------------------------------------------------------------------
- ** Created by: FiYu
- ** Created date: 2018-2-1
- ** Version: 1.0
- ** Descriptions: nRF24L01無線發射程序(硬件SPI)
- **--------------------------------------------------------------------------------------------------------
- ** Modified by: FiYu
- ** Modified date:
- ** Version:
- ** Descriptions:
- ** Rechecked by:
- **********************************************************************************************************/
- /****-----請閱讀ReadMe.txt進行實驗-----***********/
- #include "STC8.H"
- #include "oled.h"
- #include "intrins.h"
- #include "delay.h"
- #include "ADC.h"
- #include "NRF24L01.h"
- #include "timer.h"
- bit ZF,CJ=0;
- bit kaiqi=0;
- sbit Rled=P0^7;
- sbit Gled=P0^6;
- sbit Bled=P0^5;
- extern bit TIM,JS ;
- extern bit LEDK;
- extern uint8 RxPayload[6]; //無線接收緩存
- extern uint8 TxPayload[6]; //無線發送緩存
- extern uint8 S2;
- void moter(uint8 zf,uint8 SD) ; // 電機驅動函數
- void CSZX(uint16 y);
- void INT0_init(); //外部中斷0的初始化配置
- void INT1_init();
- void led(bit x,bit y,bit z);
- void OLEDXS(void);
- void INT0_int (void) interrupt 0
- {
-
- delay_ms(150);
- if(P3^2==0)
- {
- kaiqi=~kaiqi;
- }
-
- }
- void INT1_int (void) interrupt 2
- {
- delay_ms(150);
- if(P3^3==0){CJ=~CJ;}
- }
- /***************************************************************************
- * 描 述 : 主函數
- * 入 參 : 無
- * 返回值 : 無
- **************************************************************************/
- int main()
- {
- uint16 n1=0;
- bit M1=1;
- TxPayload[0] = 0x5A;
- TxPayload[3] = 0xA5;
- OLED_Init() ;
- delay_ms(20);
- OLEDXS();
- Init_NRF24L01_MA(); //初始化
- Set_TxMode_MA(); //配置nRF24L01為發送模式
- delay_ms(20);
- INT0_init();
- INT1_init();
- Timer1Init();
- EA=1;
- ADC_config();
- while(1)
- {
- if(CJ==0&&kaiqi==0){led(1,1,1); led(0,1,1);Set_TxMode_MA(); //第0模式 發送停止不接受
- while(CJ==0&&kaiqi==0){
- ADC1(); //讀取AD的值
- ADC2();
- if(kaiqi==0&&LEDK==1)
- {
- Rled=~Rled;
- TxPayload[0] = 0x5A;
- TxPayload[1] = 50;
- TxPayload[2] = 50;
- TxPayload[3] = 0xA5;
- TxPayload[4] = 0;
- NRF24L01_TxPacket_MA(TxPayload); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+1); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+2); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+3); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+4); //發送啟動標志位
- LEDK=0;
- }
- }
- }
-
- if(kaiqi==0&&CJ==1){led(1,0,1); //第1模式 接收和發送停止信號
- while(CJ==1&&kaiqi==0){
- if(JS==1){Set_TxMode_MA();
- while(JS){ led(1,0,1);
- ADC1(); //讀取AD的值
- ADC2();
- TxPayload[1] = 50;
- TxPayload[2] = 50;
- TxPayload[4] = 1;
-
- NRF24L01_TxPacket_MA(TxPayload); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+1); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+2); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+3); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+4); //發送啟動標志位
- CSZX(70+20*TxPayload[1]/50); //使控制超聲波的舵機轉到中間位置
-
- if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED顯示控制電機的PWM值 這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
- else if(TxPayload[2]<52) moter(2,0); //防止AD波動造成誤啟動
- else moter(1,(TxPayload[2]-52)*80/45); //正轉PWM值
- }
- }
- if(JS==0){ Set_RxMode_MA();
- while(!JS){
- if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK) //如果接收成功
- {
- if(RxPayload[0] == 0x04) //檢驗校驗碼
- {
- while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK)); //等待接收數據
- while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK)); //等待接收數據
- while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK)); //檢驗校驗碼
- }
-
- if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 ) //符合校驗碼的值 ,則中間的數據是正確的,不然亂碼,錯位的數據就不對
- {
- n1= RxPayload[1]*256+RxPayload[2];
- if(n1>=4000) LCD_P8x16Str(64, 6,"---.-");
- if(n1/1000==0) OLED_ShowChar(64,6,' ');
- else OLED_ShowChar(64,6,' '+16+n1/1000);
- OLED_ShowChar(72,6,' '+16+n1%1000/100);
- OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
- OLED_ShowChar(88,6,'.');
- OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
- RxPayload[0] = 0;
- RxPayload[1] = 0;
- RxPayload[2] = 0;
- RxPayload[3] = 0;
- }
- }
- }
- }
- }
- }
-
- if(kaiqi==1&&CJ==0){ led(1,1,1); led(1,1,0); //第二模式 只發送不接收
- Set_TxMode_MA();
- while(CJ==0&&kaiqi==1){
- ADC1(); //讀取AD的值
- ADC2();
- TxPayload[4] =2;
- NRF24L01_TxPacket_MA(TxPayload); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+1); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+2); //發送數據
- NRF24L01_TxPacket_MA(TxPayload+3); //發送校驗碼
- NRF24L01_TxPacket_MA(TxPayload+4); //發送啟動標志位
-
- CSZX(70+20*TxPayload[1]/50); //使控制超聲波的舵機轉到中間位置
- if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED顯示控制電機的PWM值 這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
- else if(TxPayload[2]<52) moter(2,0); //防止AD波動造成誤啟動
- else moter(1,(TxPayload[2]-52)*80/45); //正轉PWM值
- }
- }
- if(kaiqi==1&&CJ==1){led(1,1,1);}
- //if(kaiqi==1&&CJ==1){led(1,1,1); //第3模式 接收和發送
- // while(CJ==1&&kaiqi==1){
- //
- // if(JS==1){Set_TxMode_MA();
- // while(JS){led(0,0,0);
- // TxPayload[4] = 3;
- // ADC1(); //讀取AD的值
- // ADC2();
- // NRF24L01_TxPacket_MA(TxPayload); //發送校驗碼
- // NRF24L01_TxPacket_MA(TxPayload+1); //發送數據
- // NRF24L01_TxPacket_MA(TxPayload+2); //發送數據
- // NRF24L01_TxPacket_MA(TxPayload+3); //發送校驗碼
- // NRF24L01_TxPacket_MA(TxPayload+4); //發送啟動標志位
- // CSZX(70+20*TxPayload[1]/50); //使控制超聲波的舵機轉到中間位置
- //
- // if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45); //用OLED顯示控制電機的PWM值 這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
- // else if(TxPayload[2]<52) moter(2,0); //防止AD波動造成誤啟動
- // else moter(1,(TxPayload[2]-52)*80/45); //正轉PWM值
- // }
- //
- // if(JS==0){ Set_RxMode_MA(); led(1,1,1);
- // while(!JS){
- // if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK) //如果接收成功
- // {
- // if(RxPayload[0] == 0x04) //檢驗校驗碼
- // {
- // while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK)); //等待接收數據
- // while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK)); //等待接收數據
- // while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK)); //檢驗校驗碼
- // }
- //
- // if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 ) //符合校驗碼的值 ,則中間的數據是正確的,不然亂碼,錯位的數據就不對
- // {
- // n1= RxPayload[1]*256+RxPayload[2];
- // if(n1>=5500) LCD_P8x16Str(56, 6,"---.-");
- // if(n1/1000==0) OLED_ShowChar(64,6,' ');
- // else OLED_ShowChar(64,6,' '+16+n1/1000);
- // OLED_ShowChar(72,6,' '+16+n1%1000/100);
- // OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
- // OLED_ShowChar(88,6,'.');
- // OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
- // RxPayload[0] = 0;
- // RxPayload[1] = 0;
- // RxPayload[2] = 0;
- // RxPayload[3] = 0;
- // }
- // }
- // }
- // }
- // }
- // }
- // }
- }
- }
- void led(bit x,bit y,bit z)
- {
- Rled=x;
- Gled=y;
- Bled=z;
- }
- void OLEDXS(void)
- { uint8 i;
- LCD_P8x16Str(56, 2,"X:"); //2.4G模塊用了SPI,所以OLED用IIC顯示
- LCD_P8x16Str(0, 2,"Y:");
- for(i=0;i<8;i++) //遙控小車——發射
- {
- LCD_P16x16Ch(i*16,0,i);
- };
-
- for(i=8;i<11;i++)
- {
- LCD_P16x16Ch(i*16-16*8,4,i); //轉向角 控制小車轉向的舵機
- };
-
- LCD_P8x16Str(48, 4,":");
- LCD_P8x16Str(80, 4,"'C");
- LCD_P8x16Str(0, 6,"PWMY:");
- LCD_P8x16Str(104, 6,"CM");
- }
- void moter(uint8 zf,uint8 SD) // 電機驅動函數
- { uint8 sudu,i;
- sudu=SD;
- ZF=zf;
-
- OLED_ShowChar(40,6, ' '+16+sudu%100/10);
- OLED_ShowChar(48,6, ' '+16+sudu%100%10);
-
- if(zf<1)
- {
- for(i=13;i<15;i++) //反轉
- {
- LCD_P16x16Ch(i*16-16*7,2,i);
- }
- }
- else if(zf<2) //正轉
- {
- for(i=11;i<13;i++)
- {
- LCD_P16x16Ch(i*16-16*5,2,i);
- };
- }
- else {
- for(i=15;i<17;i++) //停轉
- {
- LCD_P16x16Ch(i*16-16*9,2,i);
- }
- }
-
-
-
- }
- void CSZX(uint16 y) //超聲波初值顯示函數 ,沒加可屏蔽
- {
- uint8 yy;
- yy=y;
-
- OLED_ShowChar(56,4,' '+16+yy/100);
- OLED_ShowChar(64,4,' '+16+yy%100/10);
- OLED_ShowChar(72,4,' '+16+yy%100%10);
-
- }
- void INT0_init() //外部中斷0的初始化配置
- {
- IE0 = 0; //將INT0中斷請求標志位清"0"
- EX0 = 1; //使能INT0中斷允許位
- IT0 = 1; //選擇INT0為上升沿或下降沿觸發方式 1為下降沿,0為上升沿
- }
- void INT1_init()
- {
- //外部中斷1的初始化配置
- IE1 = 0; //將INT1中斷請求標志位清"0"
- EX1 = 1; //使能INT1中斷允許位
- IT1 = 1; //選擇INT1為下降沿觸發方式 1為下降沿,0為上升沿
- }
復制代碼
所有資料51hei提供下載:
PCB 圖.zip
(55.86 KB, 下載次數: 77)
2018-12-28 20:21 上傳
點擊文件名下載附件
遙控小車PCB版.zip
(4.38 MB, 下載次數: 107)
2018-12-28 20:16 上傳
點擊文件名下載附件
|