找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2347|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)用藍(lán)牙控制小車(chē)的舵機(jī)一些問(wèn)題,求大神解答

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

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


  3.         //HJ-4WD小車(chē)驅(qū)動(dòng)接線定義
  4. #define Left_moto_go      {P1_4=1,P1_5=0,P1_6=1,P1_7=0;}  //左邊兩個(gè)電機(jī)向前走
  5. #define Left_moto_back    {P1_4=0,P1_5=1,P1_6=0,P1_7=1;}  //左邊兩個(gè)電機(jī)向后轉(zhuǎn)
  6. #define Left_moto_Stop    {P1_4=0,P1_5=0,P1_6=0,P1_7=0;}  //左邊兩個(gè)電機(jī)停轉(zhuǎn)                     
  7. #define Right_moto_go     {P1_0=1,P1_1=0,P1_2=1,P1_3=0;}        //右邊兩個(gè)電機(jī)向前走
  8. #define Right_moto_back   {P1_0=0,P1_1=1,P1_2=0,P1_3=1;}        //右邊兩個(gè)電機(jī)向后走
  9. #define Right_moto_Stop   {P1_0=0,P1_1=0,P1_2=0,P1_3=0;}        //右邊兩個(gè)電機(jī)停轉(zhuǎn)   

  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[] = "收到指令,舵機(jī)歸位!\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;//用來(lái)測(cè)試的LED
  33.         
  34.         
  35.         uchar  i=0;
  36.         uchar  dat=0;
  37.   uchar  buff[5]=0; //接收緩沖字節(jié)

  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舵機(jī)歸位,產(chǎn)生約,1.9MS 信號(hào)
  43.         uchar push_val_left2=11;//2舵機(jī)歸位,產(chǎn)生約,1.2MS 信號(hào)
  44.         uchar push_val_left3=15;//3舵機(jī)歸位,產(chǎn)生約,1.6MS 信號(hào)
  45.         uint flag1=1;
  46.         uint timer=0;
  47. /************************************************************************/        
  48. //延時(shí)函數(shù)        
  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()//舵機(jī)初始位置定義
  56. {
  57.     push_val_left1=18;           
  58.           push_val_left2=11;
  59.           push_val_left3=15;
  60. }




  61. /************************************************************************/
  62. /*                    PWM信號(hào)產(chǎn)生控制舵機(jī)                               */
  63. /************************************************************************/
  64. /*                                                                      */
  65. /*調(diào)節(jié)push_val_left的值改變電機(jī)轉(zhuǎn)速,占空比            */
  66.                 void pwm_Servomoto1(void)
  67. {  
  68.   if(pwm_val_left1<=push_val_left1)//1號(hào)舵機(jī)控制
  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號(hào)舵機(jī)控制
  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)//三號(hào)舵機(jī)控制
  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;//三個(gè)舵機(jī)歸位后,定時(shí)器0關(guān)閉
  99.         }
  100.         if(pwm_val_left3>=200)
  101.         pwm_val_left3=0;
  102. }
  103.                




  104. void guiwei()//三個(gè)舵機(jī)歸位函數(shù)
  105. {
  106.           TR0=1;//打開(kāi)T0定時(shí)器,后面會(huì)考慮增加延時(shí)函數(shù),確保舵機(jī)歸位完成
  107. }



  108. /************************************************************************/
  109. //字符串發(fā)送函數(shù)
  110.           void send_str( )
  111.                    // 傳送字串
  112.     {
  113.             unsigned char i = 0;
  114.             while(str[i] != '\0')
  115.            {
  116.                 SBUF = str[i];
  117.                 while(!TI);                                // 等特?cái)?shù)據(jù)傳送
  118.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  119.                 i++;                                        // 下一個(gè)字符
  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);                                // 等特?cái)?shù)據(jù)傳送
  131.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  132.                 i++;                                        // 下一個(gè)字符
  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);                                // 等特?cái)?shù)據(jù)傳送
  143.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  144.                 i++;                                        // 下一個(gè)字符
  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);                                // 等特?cái)?shù)據(jù)傳送
  156.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  157.                 i++;                                        // 下一個(gè)字符
  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);                                // 等特?cái)?shù)據(jù)傳送
  168.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  169.                 i++;                                        // 下一個(gè)字符
  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);                                // 等特?cái)?shù)據(jù)傳送
  182.                 TI = 0;                                        // 清除數(shù)據(jù)傳送標(biāo)志
  183.                 i++;                                        // 下一個(gè)字符
  184.            }        
  185.     }                        
  186. /************************************************************************/
  187. //前速前進(jìn)
  188.      void  run(void)
  189. {

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

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

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

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

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

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

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

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

  220.     if(RI)                         //是否接收中斷
  221.     {
  222.        RI=0;
  223.        dat=SBUF;
  224.        if(dat=='O'&&(i==0)) //接收數(shù)據(jù)第一幀
  225.          {
  226.             buff[i]=dat;
  227.             flag=1;        //開(kāi)始接收數(shù)據(jù)
  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')        //第一個(gè)字節(jié)為O,第二個(gè)字節(jié)為N,第三個(gè)字節(jié)為控制碼
  242.                 switch(buff[2])
  243.              {
  244.                       case up :                                                    // 前進(jìn)
  245.                           send_str( );
  246.                           run();
  247.                           break;
  248.                       case down:                                                // 后退
  249.                            send_str1( );
  250.                           backrun();
  251.                           break;
  252.                       case left:                                                // 左轉(zhuǎn)
  253.                            send_str3( );
  254.                           leftrun();
  255.                           break;
  256.                       case right:                                                // 右轉(zhuǎn)
  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定時(shí)
  275.          TL0=(65536-10000)%256;
  276.         timer++;//定時(shí)器100US為準(zhǔn)。在這個(gè)基礎(chǔ)上延時(shí),在后續(xù)增加延時(shí)確保舵機(jī)歸位完成。
  277.           LED=~LED;        
  278.                 if(flag1==1)//三個(gè)舵機(jī)分別歸位的函數(shù)
  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. /*--主函數(shù)--*/
  298.         void main(void)
  299. {
  300.         
  301.         TMOD=0x01;
  302.         IE|=0x82;
  303.         TH0=(65536-100)/256;          //100US定時(shí)
  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;       //開(kāi)串口中斷  
  315.     EA=1;         //打開(kāi)總中斷
  316.     TR0=0;        //關(guān)閉定時(shí)器0,在藍(lán)牙發(fā)出對(duì)應(yīng)的調(diào)用指令后開(kāi)啟。
  317.     Sevro_moto_pwm1=0;
  318.     Sevro_moto_pwm2=0;
  319.     Sevro_moto_pwm3=0;
  320.                  motoinit();       //舵機(jī)的歸位數(shù)值(分別產(chǎn)生數(shù)個(gè)100us的高脈沖)
  321.                  LED=1;
  322.            while(1)                                                        /*無(wú)限循環(huán)*/
  323.         {
  324.                
  325.         }        

  326. }
復(fù)制代碼



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

使用道具 舉報(bào)

沙發(fā)
ID:900662 發(fā)表于 2021-4-13 16:22 | 只看該作者
大哥們,,有沒(méi)有啥51單片機(jī)的好書(shū)推薦一下我康康也可以、
回復(fù)

使用道具 舉報(bào)

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

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

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

這么做還是不行,后來(lái)多次測(cè)試,我又換了T2定時(shí)器做波特率發(fā)生器,然后T1產(chǎn)生PWM波形,最終發(fā)現(xiàn)中斷只進(jìn)了一次,舵機(jī)1的PWM輸出口一直保持的是高電平,好像是硬件沒(méi)有清零溢出的標(biāo)志位,最后沒(méi)辦法了,我又買(mǎi)了一塊單片機(jī)單獨(dú)控制三個(gè)舵機(jī),
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表