久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6482|回復: 4
收起左側

2.4G遙控小車設計 超聲波數據回傳 舵機轉向 OLED顯示 STC8A8K64S4單片機程序+電路

  [復制鏈接]
ID:404207 發表于 2018-12-28 20:22 | 顯示全部樓層 |閱讀模式
在上一次用開發板做小車后  繼續深入研究  把開發板換成了PCB  遙控器用兩個模擬量搖桿,達到了玩小車的樂趣 , 又在原有的基礎上增加了超聲波數據回傳,實現了數據收發,而且程序也有了很大的優化 ,速度變得更快了點,最重要的還是用了PCB ,買一些元器件就可以自己做電路,特別適合學生DIY,我也是用腐刻做板的,所以不用擔心很復雜。直接附上圖片吧。

制作出來的實物圖如下:
QQ圖片20181228201117.jpg QQ圖片20181228200123.jpg

Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
96C]DBFSG~5EBK{Z%K{D@IO.png (0ABNU4}8YB_Z%}P@}@0RCO.png

nRF24L01無線發射檢測:
1、將nRF24L01模塊按照正確方向插到J11端子上;
2、MINI USB連接線給開發板通電下載程序,下載軟件中內部IRC時鐘選擇11.0592MHZ;
3、下載程序后,開發板藍色指示燈會不停閃爍,表示無線發送正常;
4、此時,如果有下發接收程序的開發板,則可以觀察到有表示接收到的紅色指示燈閃爍。
注:該實驗需要配合接收實驗進行。

nRF24L01無線接收實驗:
1、將nRF24L01模塊按照正確方向插到J11端子上;
2、MINI USB連接線給開發板通電下載程序,下載軟件中內部IRC時鐘選擇11.0592MHZ;
3、下載程序后,開發板紅色指示燈會常亮,表示沒有接收到無線信號;
4、此時,如果有下發發送程序的開發板,則可以觀察到該接收板上的紅色指示燈閃爍。
注:該實驗需要配合發送實驗進行。

單片機源程序如下:
  1. /****************************************Copyright (c)****************************************************
  2. **                                       
  3. **                                 
  4. **
  5. **--------------File Info---------------------------------------------------------------------------------
  6. ** File name:                       
  7. ** Last modified Date:         
  8. ** Last Version:                  
  9. ** Descriptions:                                                       
  10. **--------------------------------------------------------------------------------------------------------
  11. ** Created by:                        FiYu
  12. ** Created date:                2018-2-1
  13. ** Version:                            1.0
  14. ** Descriptions:                nRF24L01無線發射程序(硬件SPI)                                       
  15. **--------------------------------------------------------------------------------------------------------
  16. ** Modified by:                        FiYu
  17. ** Modified date:                               
  18. ** Version:                                  
  19. ** Descriptions:               
  20. ** Rechecked by:                               
  21. **********************************************************************************************************/
  22. /****-----請閱讀ReadMe.txt進行實驗-----***********/


  23. #include        "STC8.H"
  24. #include "oled.h"
  25. #include  "intrins.h"
  26. #include  "delay.h"
  27. #include  "ADC.h"
  28. #include "NRF24L01.h"
  29. #include "timer.h"
  30.   bit ZF,CJ=0;
  31.         bit kaiqi=0;       
  32.         sbit Rled=P0^7;
  33.         sbit Gled=P0^6;
  34.         sbit Bled=P0^5;
  35. extern bit TIM,JS ;
  36. extern bit LEDK;         
  37. extern uint8  RxPayload[6];   //無線接收緩存
  38. extern uint8  TxPayload[6];   //無線發送緩存
  39. extern uint8 S2;
  40. void moter(uint8 zf,uint8 SD)        ;                                   //  電機驅動函數
  41. void CSZX(uint16 y);
  42. void INT0_init();                //外部中斷0的初始化配置       
  43. void INT1_init();
  44. void led(bit x,bit y,bit z);
  45. void OLEDXS(void);
  46. void INT0_int (void) interrupt 0               
  47. {               
  48.      
  49.                 delay_ms(150);
  50.         if(P3^2==0)
  51.                 {
  52.                         kaiqi=~kaiqi;
  53.                 }
  54.        
  55.         }

  56. void INT1_int (void) interrupt 2               
  57. {               
  58.                 delay_ms(150);
  59.           if(P3^3==0){CJ=~CJ;}               
  60. }

  61. /***************************************************************************
  62. * 描  述 : 主函數
  63. * 入  參 : 無
  64. * 返回值 : 無
  65. **************************************************************************/
  66. int main()         
  67. {   
  68.                 uint16 n1=0;
  69.     bit M1=1;       
  70.                 TxPayload[0] = 0x5A;
  71.                 TxPayload[3] = 0xA5;
  72.                 OLED_Init() ;  
  73.                 delay_ms(20);                               
  74.                  OLEDXS();
  75.                 Init_NRF24L01_MA();                  //初始化
  76.                 Set_TxMode_MA();                                                  //配置nRF24L01為發送模式       
  77.           delay_ms(20);
  78.                 INT0_init();
  79.           INT1_init();
  80.     Timer1Init();
  81.                 EA=1;
  82.                 ADC_config();

  83.   while(1)
  84.   {
  85.         if(CJ==0&&kaiqi==0){led(1,1,1); led(0,1,1);Set_TxMode_MA();              //第0模式    發送停止不接受
  86.             while(CJ==0&&kaiqi==0){
  87.                         ADC1();                                //讀取AD的值
  88.                         ADC2();               
  89.                         if(kaiqi==0&&LEDK==1)
  90.                         {
  91.                                 Rled=~Rled;                                                
  92.                                 TxPayload[0] = 0x5A;       
  93.                                 TxPayload[1] = 50;       
  94.                                 TxPayload[2] = 50;       
  95.                                 TxPayload[3] = 0xA5;       
  96.                                 TxPayload[4] = 0;       
  97.                                 NRF24L01_TxPacket_MA(TxPayload);            //發送校驗碼
  98.                                 NRF24L01_TxPacket_MA(TxPayload+1);          //發送數據               
  99.                                 NRF24L01_TxPacket_MA(TxPayload+2);    //發送數據
  100.                                 NRF24L01_TxPacket_MA(TxPayload+3);    //發送校驗碼
  101.                                 NRF24L01_TxPacket_MA(TxPayload+4);    //發送啟動標志位

  102.                                 LEDK=0;
  103.                         }       
  104.                 }
  105.         }
  106.                        
  107. if(kaiqi==0&&CJ==1){led(1,0,1);                 //第1模式  接收和發送停止信號
  108.         while(CJ==1&&kaiqi==0){
  109.                         if(JS==1){Set_TxMode_MA();  
  110.             while(JS){        led(1,0,1);       
  111.                         ADC1();                                //讀取AD的值
  112.                         ADC2();               
  113.                         TxPayload[1] = 50;       
  114.                         TxPayload[2] = 50;                               
  115.                         TxPayload[4] = 1;       
  116.           
  117.                         NRF24L01_TxPacket_MA(TxPayload);            //發送校驗碼
  118.                         NRF24L01_TxPacket_MA(TxPayload+1);          //發送數據               
  119.                         NRF24L01_TxPacket_MA(TxPayload+2);    //發送數據
  120.                         NRF24L01_TxPacket_MA(TxPayload+3);    //發送校驗碼
  121.                         NRF24L01_TxPacket_MA(TxPayload+4);    //發送啟動標志位
  122.                         CSZX(70+20*TxPayload[1]/50);          //使控制超聲波的舵機轉到中間位置
  123.                                
  124.                                 if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45);   //用OLED顯示控制電機的PWM值  這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
  125.                                          else if(TxPayload[2]<52)   moter(2,0);              //防止AD波動造成誤啟動
  126.                                                                 else  moter(1,(TxPayload[2]-52)*80/45);                                //正轉PWM值                       
  127.                 }
  128.         }                       
  129.                          if(JS==0){        Set_RxMode_MA();
  130.                         while(!JS){
  131.                   if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK)          //如果接收成功
  132.                         {
  133.                         if(RxPayload[0] == 0x04)                                                                     //檢驗校驗碼
  134.                         {                               
  135.                         while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK));                                //等待接收數據
  136.                          while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK));                                //等待接收數據
  137.                                 while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK));                        //檢驗校驗碼
  138.                         }
  139.                
  140.                         if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 )                 //符合校驗碼的值 ,則中間的數據是正確的,不然亂碼,錯位的數據就不對
  141.                                 {
  142.                                 n1= RxPayload[1]*256+RxPayload[2];
  143.                                         if(n1>=4000) LCD_P8x16Str(64, 6,"---.-");
  144.                                 if(n1/1000==0) OLED_ShowChar(64,6,' ');
  145.                                          else OLED_ShowChar(64,6,' '+16+n1/1000);
  146.                                                                 OLED_ShowChar(72,6,' '+16+n1%1000/100);
  147.                                                                 OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
  148.                                                                 OLED_ShowChar(88,6,'.');       
  149.                                                                 OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
  150.                                                                 RxPayload[0] = 0;
  151.                                                                 RxPayload[1] = 0;
  152.                                                                 RxPayload[2] = 0;
  153.                                                                 RxPayload[3] = 0;                               
  154.                                                                 }
  155.                                                         }
  156.                                                 }
  157.                                         }
  158.                                 }
  159.                         }
  160.        
  161. if(kaiqi==1&&CJ==0){ led(1,1,1);    led(1,1,0);         //第二模式  只發送不接收
  162.     Set_TxMode_MA();
  163. while(CJ==0&&kaiqi==1){
  164.                         ADC1();                                //讀取AD的值
  165.                         ADC2();                    
  166.                         TxPayload[4] =2;          
  167.                         NRF24L01_TxPacket_MA(TxPayload);            //發送校驗碼
  168.                         NRF24L01_TxPacket_MA(TxPayload+1);          //發送數據               
  169.                         NRF24L01_TxPacket_MA(TxPayload+2);    //發送數據
  170.                         NRF24L01_TxPacket_MA(TxPayload+3);    //發送校驗碼
  171.                         NRF24L01_TxPacket_MA(TxPayload+4);    //發送啟動標志位
  172.        
  173.                         CSZX(70+20*TxPayload[1]/50);          //使控制超聲波的舵機轉到中間位置               
  174.                                 if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45);   //用OLED顯示控制電機的PWM值  這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
  175.                                          else if(TxPayload[2]<52)   moter(2,0);              //防止AD波動造成誤啟動
  176.                                                                 else  moter(1,(TxPayload[2]-52)*80/45);                                //正轉PWM值               
  177.                 }
  178.         }

  179. if(kaiqi==1&&CJ==1){led(1,1,1);}
  180. //if(kaiqi==1&&CJ==1){led(1,1,1);                 //第3模式  接收和發送
  181. //        while(CJ==1&&kaiqi==1){       
  182. //               
  183. //                        if(JS==1){Set_TxMode_MA();
  184. //            while(JS){led(0,0,0);
  185. //                        TxPayload[4] = 3;       
  186. //                        ADC1();                                //讀取AD的值
  187. //                        ADC2();                            
  188. //                        NRF24L01_TxPacket_MA(TxPayload);            //發送校驗碼
  189. //                        NRF24L01_TxPacket_MA(TxPayload+1);          //發送數據               
  190. //                        NRF24L01_TxPacket_MA(TxPayload+2);    //發送數據
  191. //                        NRF24L01_TxPacket_MA(TxPayload+3);    //發送校驗碼
  192. //                        NRF24L01_TxPacket_MA(TxPayload+4);    //發送啟動標志位
  193. //                        CSZX(70+20*TxPayload[1]/50);          //使控制超聲波的舵機轉到中間位置
  194. //                       
  195. //                                if(TxPayload[2]<48)moter(0,(49-TxPayload[2])*80/45);   //用OLED顯示控制電機的PWM值  這里最大是80,可以修改到90以上,但不能是100,因為AD的波動值會直接超過一百
  196. //                                         else if(TxPayload[2]<52)   moter(2,0);              //防止AD波動造成誤啟動
  197. //                                                                else  moter(1,(TxPayload[2]-52)*80/45);                                //正轉PWM值               
  198. //                }               
  199. //                       
  200. //                        if(JS==0){        Set_RxMode_MA();        led(1,1,1);
  201. //                        while(!JS){       
  202. //                  if(NRF24L01_RxPacket_MA(RxPayload) == RX_OK)          //如果接收成功
  203. //                        {
  204. //                        if(RxPayload[0] == 0x04)                                                                     //檢驗校驗碼
  205. //                        {                               
  206. //                        while( !(NRF24L01_RxPacket_MA(RxPayload+1)==RX_OK));                                //等待接收數據
  207. //                         while( !(NRF24L01_RxPacket_MA(RxPayload+2)==RX_OK));                                //等待接收數據
  208. //                                while( !(NRF24L01_RxPacket_MA(RxPayload+3)==RX_OK));                        //檢驗校驗碼
  209. //                        }
  210. //               
  211. //                        if(RxPayload[0] == 0x04 && RxPayload[3] == 0x05 )                 //符合校驗碼的值 ,則中間的數據是正確的,不然亂碼,錯位的數據就不對
  212. //                                {
  213. //                                n1= RxPayload[1]*256+RxPayload[2];
  214. //                                        if(n1>=5500) LCD_P8x16Str(56, 6,"---.-");
  215. //                                if(n1/1000==0) OLED_ShowChar(64,6,' ');
  216. //                                         else OLED_ShowChar(64,6,' '+16+n1/1000);
  217. //                                                                OLED_ShowChar(72,6,' '+16+n1%1000/100);
  218. //                                                                OLED_ShowChar(80,6,' '+16+n1%1000%100/10);
  219. //                                                                OLED_ShowChar(88,6,'.');       
  220. //                                                                OLED_ShowChar(96,6,' '+16+n1%1000%100%10);
  221. //                                                                RxPayload[0] = 0;
  222. //                                                                RxPayload[1] = 0;
  223. //                                                                RxPayload[2] = 0;
  224. //                                                                RxPayload[3] = 0;                               
  225. //                                                                }
  226. //                                                        }
  227. //                                                }
  228. //                                        }
  229. //                                }
  230. //                        }
  231. //                }

  232.         }
  233. }



  234. void led(bit x,bit y,bit z)
  235. {
  236.   Rled=x;
  237.         Gled=y;
  238.         Bled=z;
  239. }
  240. void OLEDXS(void)
  241. {                uint8 i;
  242.                 LCD_P8x16Str(56, 2,"X:");       //2.4G模塊用了SPI,所以OLED用IIC顯示
  243.                 LCD_P8x16Str(0, 2,"Y:");
  244.                 for(i=0;i<8;i++)        //遙控小車——發射
  245.            {
  246.                    LCD_P16x16Ch(i*16,0,i);                   
  247.                  };
  248.                  
  249.                          for(i=8;i<11;i++)
  250.            {
  251.                    LCD_P16x16Ch(i*16-16*8,4,i);        //轉向角           控制小車轉向的舵機
  252.                  };
  253.                  
  254.                  LCD_P8x16Str(48, 4,":");
  255.                 LCD_P8x16Str(80, 4,"'C");
  256.           LCD_P8x16Str(0, 6,"PWMY:");
  257.                 LCD_P8x16Str(104, 6,"CM");       
  258. }


  259. void moter(uint8 zf,uint8 SD)                                           //  電機驅動函數  
  260. {   uint8 sudu,i;
  261.            sudu=SD;
  262.           ZF=zf;
  263.           
  264.                 OLED_ShowChar(40,6, ' '+16+sudu%100/10);
  265.                 OLED_ShowChar(48,6, ' '+16+sudu%100%10);
  266.        
  267.                         if(zf<1)                           
  268.                         {
  269.                                 for(i=13;i<15;i++)  //反轉
  270.                                  {
  271.                                         LCD_P16x16Ch(i*16-16*7,2,i);                   
  272.                                  }           
  273.                         }
  274.                                 else if(zf<2)      //正轉
  275.                                         {
  276.                                                 for(i=11;i<13;i++)
  277.                                          {
  278.                                                 LCD_P16x16Ch(i*16-16*5,2,i);                   
  279.                                          };  
  280.                                  }
  281.                                            else {
  282.                                                                          for(i=15;i<17;i++)  //停轉
  283.                                                                  {
  284.                                                                         LCD_P16x16Ch(i*16-16*9,2,i);                   
  285.                                                                  }
  286.                                                  }
  287.                                
  288.    
  289.                  
  290. }
  291. void CSZX(uint16 y)                  //超聲波初值顯示函數  ,沒加可屏蔽
  292. {               
  293.                 uint8 yy;
  294.            yy=y;       
  295.             
  296.                 OLED_ShowChar(56,4,' '+16+yy/100);
  297.                 OLED_ShowChar(64,4,' '+16+yy%100/10);
  298.                 OLED_ShowChar(72,4,' '+16+yy%100%10);
  299.                                
  300. }
  301. void INT0_init()                //外部中斷0的初始化配置       
  302. {
  303.         IE0  = 0;               //將INT0中斷請求標志位清"0"
  304.         EX0 = 1;               //使能INT0中斷允許位
  305.         IT0 = 1;                   //選擇INT0為上升沿或下降沿觸發方式          1為下降沿,0為上升沿

  306. }

  307. void INT1_init()
  308. {
  309.                                                                                 //外部中斷1的初始化配置
  310.         IE1  = 0;                //將INT1中斷請求標志位清"0"
  311.         EX1 = 1;                //使能INT1中斷允許位
  312.         IT1 = 1;                      //選擇INT1為下降沿觸發方式           1為下降沿,0為上升沿                  
  313. }
復制代碼
0.png
所有資料51hei提供下載:
PCB 圖.zip (55.86 KB, 下載次數: 77)
遙控小車PCB版.zip (4.38 MB, 下載次數: 107)




評分

參與人數 2黑幣 +65 收起 理由
shineyunze978 + 15 贊一個!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:243748 發表于 2019-2-24 20:57 來自觸屏版 | 顯示全部樓層
好資料,希望能用得七
回復

使用道具 舉報

ID:260743 發表于 2019-4-28 15:44 | 顯示全部樓層
PCB封裝庫不全,根本打不開,文件大小才5KB
回復

使用道具 舉報

ID:310993 發表于 2021-3-30 01:41 | 顯示全部樓層
15932885***@是高手玩家!編程水平較高!電路板設計也很到位!細節也做的比較到位!只是習慣了51編程,變量名稱太隨意,說明及關鍵理解性說明,太少有點可惜了!系統分析師可能會認為,這種習慣不適合做大型程序!但做玩家那是高手!
回復

使用道具 舉報

ID:417804 發表于 2021-12-3 16:31 | 顯示全部樓層
請問小車底盤是從哪里弄的啊?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一区二区三区在线免费观看 | 丁香综合 | 欧美激情国产精品 | 日韩第一页| 91黄在线观看 | 中文字幕欧美一区 | 国产成人精品免费视频大全最热 | 日韩成人精品视频 | 九九亚洲 | 成人伊人 | 亚洲免费一区二区 | 一本色道精品久久一区二区三区 | 色视频成人在线观看免 | 2018国产大陆天天弄 | 人人干人人超 | 亚洲精品www久久久久久广东 | 一区二区免费在线 | av网站免费| 久久精品亚洲国产奇米99 | 欧美色性| 久久伊人在 | 久久er精品 | aaa天堂 | 成人亚洲在线 | 超碰日本| 国产成人精品久久 | 亚洲天堂色 | 欧美日韩一 | 日韩欧美国产精品 | 国产精品美女久久久久久免费 | 久久精品一区二区 | 国内精品久久久久久久影视简单 | 草草草网站 | 色资源在线视频 | 成人无遮挡毛片免费看 | 欧美一区二区免费 | 国产精品视频999 | 91香蕉| 91久久精品国产 | 精品久久久久久久人人人人传媒 | 成人在线视 |