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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2347|回復: 3
打印 上一主題 下一主題
收起左側

51單片機用藍牙控制小車的舵機一些問題,求大神解答

[復制鏈接]
跳轉到指定樓層
樓主
ID:900662 發表于 2021-4-12 19:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我想做一個用藍牙控制小車的舵機,但是遇到很多問題
1.我看到說是51單片機里面t0和t1定時器是可以同時工作的,又查到小車的藍牙波特率是用T1做的(T1的ET0=0,沒有開中斷允許位),然后我就自己寫了個T0定時器產生pwm控制舵機的程序,單獨打開并且下載進去之后,舵機可以正常使用,但是我移植到藍牙控制小車的大程序之后,我將TR0置0,然后通過藍牙寫入一個字符串,調用舵機函數,舵機函數中把TR0打開,但是進不了T0的中斷函數,藍牙也失效。這是什么問題,有時候我用藍牙控制小車的時候前進后退的時候,舵機也會轉,我不知道怎么辦了,用T2做波特率發生器,用T1做PWM能行嗎?不知道是舵機會影響單片機,還是T0和T1沖突,還是我用藍牙調用函數開T0中斷的問題。程序如下,求大神解答。

單片機源程序如下:
  1. #include<AT89x51.H>
  2. #include <intrins.h>


  3.         //HJ-4WD小車驅動接線定義
  4. #define Left_moto_go      {P1_4=1,P1_5=0,P1_6=1,P1_7=0;}  //左邊兩個電機向前走
  5. #define Left_moto_back    {P1_4=0,P1_5=1,P1_6=0,P1_7=1;}  //左邊兩個電機向后轉
  6. #define Left_moto_Stop    {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}  //左邊兩個電機停轉                     
  7. #define Right_moto_go     {P1_0=1,P1_1=0,P1_2=1,P1_3=0;}        //右邊兩個電機向前走
  8. #define Right_moto_back   {P1_0=0,P1_1=1,P1_2=0,P1_3=1;}        //右邊兩個電機向后走
  9. #define Right_moto_Stop   {P1_0=0,P1_1=0,P1_2=0,P1_3=0;}        //右邊兩個電機停轉   

  10. #define left     'C'
  11. #define right    'D'
  12. #define up       'A'
  13. #define down     'B'
  14. #define stop     'F'
  15. #define guiwei1  '1'

  16.         #define uchar unsigned char
  17.         #define ulong unsigned long
  18.         #define uint  unsigned int
  19.                
  20.         char code str[] =  "收到指令,向前!\n";
  21.         char code str1[] = "收到指令,向后!\n";
  22.         char code str2[] = "收到指令,向左!\n";
  23.         char code str3[] = "收到指令,向右!\n";
  24.         char code str4[] = "收到指令,停止!\n";
  25.         char code str5[] = "收到指令,舵機歸位!\n";

  26.         bit  flag_REC=0;
  27.         bit  flag    =0;  
  28.         
  29.                 sbit Sevro_moto_pwm1=P2^7;           //左右
  30.         sbit Sevro_moto_pwm2=P2^1;    //伸縮
  31.         sbit Sevro_moto_pwm3=P2^2;    //上下
  32.         sbit LED=P2^0;//用來測試的LED
  33.         
  34.         
  35.         uchar  i=0;
  36.         uchar  dat=0;
  37.   uchar  buff[5]=0; //接收緩沖字節

  38.         
  39.   uchar pwm_val_left1=0;//變量定義
  40.         uchar pwm_val_left2=0;//變量定義
  41.         uchar pwm_val_left3=0;//變量定義
  42.         uchar push_val_left1=18;//1舵機歸位,產生約,1.9MS 信號
  43.         uchar push_val_left2=11;//2舵機歸位,產生約,1.2MS 信號
  44.         uchar push_val_left3=15;//3舵機歸位,產生約,1.6MS 信號
  45.         uint flag1=1;
  46.         uint timer=0;
  47. /************************************************************************/        
  48. //延時函數        
  49.    void delay(unsigned int k)
  50. {   
  51.      unsigned int x,y;
  52.          for(x=0;x<k;x++)
  53.            for(y=0;y<2000;y++);
  54. }


  55. void motoinit()//舵機初始位置定義
  56. {
  57.     push_val_left1=18;           
  58.           push_val_left2=11;
  59.           push_val_left3=15;
  60. }




  61. /************************************************************************/
  62. /*                    PWM信號產生控制舵機                               */
  63. /************************************************************************/
  64. /*                                                                      */
  65. /*調節push_val_left的值改變電機轉速,占空比            */
  66.                 void pwm_Servomoto1(void)
  67. {  
  68.   if(pwm_val_left1<=push_val_left1)//1號舵機控制
  69.                Sevro_moto_pwm1=1;

  70.         else
  71.         {                          
  72.                Sevro_moto_pwm1=0;
  73.                      flag1++;
  74.         }
  75.         if(pwm_val_left1>=200)
  76.         pwm_val_left1=0;
  77. }
  78.                 void pwm_Servomoto2(void)
  79. {
  80.         if(pwm_val_left2<=push_val_left2)//2號舵機控制
  81.                Sevro_moto_pwm2=1;
  82.         else
  83.         {
  84.                         Sevro_moto_pwm2=0;
  85.                 flag1++;
  86.         }               
  87.         if(pwm_val_left2>=200)
  88.         pwm_val_left2=0;
  89. }
  90.                 void pwm_Servomoto3(void)//三號舵機控制
  91.                 {
  92. if(pwm_val_left3<=push_val_left3)
  93.                Sevro_moto_pwm3=1;
  94.         else
  95.         {               
  96.                Sevro_moto_pwm3=0;
  97.                      flag1=1;
  98.                      TR=0;//三個舵機歸位后,定時器0關閉
  99.         }
  100.         if(pwm_val_left3>=200)
  101.         pwm_val_left3=0;
  102. }
  103.                




  104. void guiwei()//三個舵機歸位函數
  105. {
  106.           TR0=1;//打開T0定時器,后面會考慮增加延時函數,確保舵機歸位完成
  107. }



  108. /************************************************************************/
  109. //字符串發送函數
  110.           void send_str( )
  111.                    // 傳送字串
  112.     {
  113.             unsigned char i = 0;
  114.             while(str[i] != '\0')
  115.            {
  116.                 SBUF = str[i];
  117.                 while(!TI);                                // 等特數據傳送
  118.                 TI = 0;                                        // 清除數據傳送標志
  119.                 i++;                                        // 下一個字符
  120.            }        
  121.     }
  122.         
  123.                   void send_str1( )
  124.                    // 傳送字串
  125.     {
  126.             unsigned char i = 0;
  127.             while(str1[i] != '\0')
  128.            {
  129.                 SBUF = str1[i];
  130.                 while(!TI);                                // 等特數據傳送
  131.                 TI = 0;                                        // 清除數據傳送標志
  132.                 i++;                                        // 下一個字符
  133.            }        
  134.     }        

  135.                           void send_str2( )
  136.                    // 傳送字串
  137.     {
  138.             unsigned char i = 0;
  139.             while(str2[i] != '\0')
  140.            {
  141.                 SBUF = str2[i];
  142.                 while(!TI);                                // 等特數據傳送
  143.                 TI = 0;                                        // 清除數據傳送標志
  144.                 i++;                                        // 下一個字符
  145.            }        
  146.     }        
  147.                     
  148.                           void send_str3()
  149.                    // 傳送字串
  150.     {
  151.             unsigned char i = 0;
  152.             while(str3[i] != '\0')
  153.            {
  154.                 SBUF = str3[i];
  155.                 while(!TI);                                // 等特數據傳送
  156.                 TI = 0;                                        // 清除數據傳送標志
  157.                 i++;                                        // 下一個字符
  158.            }        
  159.     }        

  160.               void send_str4()
  161.                    // 傳送字串
  162.     {
  163.             unsigned char i = 0;
  164.             while(str4[i] != '\0')
  165.            {
  166.                 SBUF = str4[i];
  167.                 while(!TI);                                // 等特數據傳送
  168.                 TI = 0;                                        // 清除數據傳送標志
  169.                 i++;                                        // 下一個字符
  170.            }        
  171.     }        
  172.                     
  173.         
  174.               void send_str5()
  175.                    // 傳送字串
  176.     {
  177.             unsigned char i = 0;
  178.             while(str4[i] != '\0')
  179.            {
  180.                 SBUF = str5[i];
  181.                 while(!TI);                                // 等特數據傳送
  182.                 TI = 0;                                        // 清除數據傳送標志
  183.                 i++;                                        // 下一個字符
  184.            }        
  185.     }                        
  186. /************************************************************************/
  187. //前速前進
  188.      void  run(void)
  189. {

  190.          Left_moto_go;   //左電機往前走
  191.          Right_moto_go;  //右電機往前走
  192. }

  193. //前速后退
  194.      void  backrun(void)
  195. {

  196.          Left_moto_back ;   //左電機往前走
  197.          Right_moto_back ;  //右電機往前走
  198. }

  199. //左轉
  200.      void  leftrun(void)
  201. {

  202.          Left_moto_back ;   //左電機往前走
  203.          Right_moto_go ;  //右電機往前走
  204. }

  205. //右轉
  206.      void  rightrun(void)
  207. {

  208.          Left_moto_go;   //左電機往前走
  209.          Right_moto_back;  //右電機往前走
  210. }
  211. //STOP
  212.      void  stoprun(void)
  213. {

  214.          Left_moto_Stop ;   //左電機往前走
  215.          Right_moto_Stop ;  //右電機往前走
  216. }
  217. /************************************************************************/
  218. void sint() interrupt 4          //中斷接收3個字節
  219. {

  220.     if(RI)                         //是否接收中斷
  221.     {
  222.        RI=0;
  223.        dat=SBUF;
  224.        if(dat=='O'&&(i==0)) //接收數據第一幀
  225.          {
  226.             buff[i]=dat;
  227.             flag=1;        //開始接收數據
  228.          }
  229.        else
  230.       if(flag==1)
  231.      {
  232.       i++;
  233.       buff[i]=dat;
  234.       if(i>=2)
  235.       {i=0;flag=0;flag_REC=1 ;}  // 停止接收
  236.      }
  237.          }
  238.                   if(flag_REC==1)                                    //
  239.            {
  240.                 flag_REC=0;
  241.                 if(buff[0]=='O'&&buff[1]=='N')        //第一個字節為O,第二個字節為N,第三個字節為控制碼
  242.                 switch(buff[2])
  243.              {
  244.                       case up :                                                    // 前進
  245.                           send_str( );
  246.                           run();
  247.                           break;
  248.                       case down:                                                // 后退
  249.                            send_str1( );
  250.                           backrun();
  251.                           break;
  252.                       case left:                                                // 左轉
  253.                            send_str3( );
  254.                           leftrun();
  255.                           break;
  256.                       case right:                                                // 右轉
  257.                           send_str2( );
  258.                           rightrun();
  259.                           break;
  260.                       case stop:                                                // 停止
  261.                            send_str4( );
  262.                           stoprun();
  263.                           break;
  264.                                         case guiwei1:                                                // 停止
  265.                            send_str5( );
  266. //                                        LED=~LED;
  267.                           guiwei();
  268.                           break;

  269.              }                                         
  270.          }
  271. }
  272.          void time1()interrupt 1
  273. {        
  274.    TH0=(65536-10000)/256;          //100US定時
  275.          TL0=(65536-10000)%256;
  276.         timer++;//定時器100US為準。在這個基礎上延時,在后續增加延時確保舵機歸位完成。
  277.           LED=~LED;        
  278.                 if(flag1==1)//三個舵機分別歸位的函數
  279.                 {
  280.                pwm_val_left1++;
  281.          pwm_Servomoto1();
  282. //                        LED=0;
  283.                 }         

  284.     if(flag1==2)
  285.                 {
  286.                         pwm_val_left2++;
  287.                   pwm_Servomoto2();                        
  288.                 }
  289.      else
  290.                  {
  291.       pwm_val_left3++;
  292.                   pwm_Servomoto3();
  293.         }
  294. }
  295.         
  296. /*********************************************************************/                 
  297. /*--主函數--*/
  298.         void main(void)
  299. {
  300.         
  301.         TMOD=0x01;
  302.         IE|=0x82;
  303.         TH0=(65536-100)/256;          //100US定時
  304.         TL0=(65536-100)%256;
  305.         ET0=1;
  306.         TR0=1;
  307.         
  308.           TMOD=0x20;  
  309.     TH1=0xFd;                     //11.0592M晶振,9600波特率
  310.     TL1=0xFd;
  311.     SCON=0x50;  
  312.     PCON=0x00;                 
  313.     TR1=1;
  314.     ES=1;       //開串口中斷  
  315.     EA=1;         //打開總中斷
  316.     TR0=0;        //關閉定時器0,在藍牙發出對應的調用指令后開啟。
  317.     Sevro_moto_pwm1=0;
  318.     Sevro_moto_pwm2=0;
  319.     Sevro_moto_pwm3=0;
  320.                  motoinit();       //舵機的歸位數值(分別產生數個100us的高脈沖)
  321.                  LED=1;
  322.            while(1)                                                        /*無限循環*/
  323.         {
  324.                
  325.         }        

  326. }
復制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:900662 發表于 2021-4-13 16:22 | 只看該作者
大哥們,,有沒有啥51單片機的好書推薦一下我康康也可以、
回復

使用道具 舉報

板凳
ID:65956 發表于 2021-4-15 08:17 | 只看該作者
TMOD=0x01;和TMOD=0x20;  這個要改成TMOD|=0x01;和TMOD|=0x20;  就不會互相影響到各自的定時器配置了

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:900662 發表于 2021-4-15 19:03 | 只看該作者
aking991 發表于 2021-4-15 08:17
TMOD=0x01;和TMOD=0x20;  這個要改成TMOD|=0x01;和TMOD|=0x20;  就不會互相影響到各自的定時器配置了

這么做還是不行,后來多次測試,我又換了T2定時器做波特率發生器,然后T1產生PWM波形,最終發現中斷只進了一次,舵機1的PWM輸出口一直保持的是高電平,好像是硬件沒有清零溢出的標志位,最后沒辦法了,我又買了一塊單片機單獨控制三個舵機,
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区在线视频 | 国产精品久久久久久一级毛片 | 毛片一区| 一区二区三区四区在线视频 | 国产精品一码二码三码在线 | 日韩国产精品一区二区三区 | 国产极品粉嫩美女呻吟在线看人 | 国产精品久久久久久久久久久久 | 亚洲精品电影网在线观看 | 精品一区二区三区中文字幕 | 欧美精品一区二区三区在线播放 | 美女视频黄的 | 精品啪啪 | www.夜夜骑.com| 亚洲一区在线免费观看 | 精品久久久久久久久久 | 久久伦理电影 | 亚洲视频二区 | 在线免费观看黄色av | 久久久不卡网国产精品一区 | 日韩一区二区在线播放 | 国产精品成人品 | 新91视频网 | 国产精品久久久久久中文字 | 男女网站在线观看 | 丝袜一区二区三区 | 亚洲精品视频在线播放 | 亚欧精品一区 | 狠狠干美女 | 毛片99| 国产在线精品一区二区 | 一级片在线视频 | 欧美一区二区大片 | av网站在线播放 | 日韩在线中文 | 91大神在线资源观看无广告 | 黄视频在线网站 | 视频一区在线 | 日韩在线免费观看视频 | 蜜桃在线视频 | 成人国产一区二区三区精品麻豆 |