欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3760|回復: 8
收起左側

單片機控制PS2手柄程序,貌似PWM和串口沖突了

[復制鏈接]
ID:445766 發表于 2018-12-13 16:41 | 顯示全部樓層 |閱讀模式
大佬們,求助啊。
背景:PS2手柄與STC89C52RC串口發送數據,89C52驅動74HC595,74HC595驅動兩個L293D。目的:PS2控制四個馬達,PWM無級調速(PS手柄按鍵加減占空比實現)。
問題:用定時器產生PWM控制馬達轉速時,PWM周期設置貌似有問題,周期7秒左右,改TH0和TL0小于500手柄就無法通訊。
純新手,只要能給我指出問題,隨便噴。。。另,若是能幫我解決調通,耐心指導我一下相關知識,可給報酬20R,我知道不多,但是畢竟有點窮。。。
代碼如下(暫時為4種占空比):
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. #define  uchar unsigned char
  4. #define  uint  unsigned int



  5. //#define Self_Define_ISP_Download_Command 0x3D
  6. //sfr IAP_CONTR=0xE7;

  7. sbit  DATA=P0^0;
  8. sbit  CMND=P0^1;
  9. sbit  ATT=P0^2;
  10. sbit  CLK=P0^3;

  11. uchar code scan[9]={0x01,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  12. uchar  out[9];            

  13. uchar time;
  14. double count=0;        //定義占空比
  15. bit PWM=0;   
  16. int mid_TH0,mid_TL0;
  17. sbit sck=P1^0;
  18. sbit ser=P1^1;
  19. sbit rck=P1^2;


  20. sbit EN1=P1^3;          //ic2          M4
  21. sbit EN2=P1^4;          //ic2          M3
  22. sbit EN3=P1^5;          //ic1          M2
  23. sbit EN4=P1^6;          //ic1          M1

  24. uchar code Tab[]={0x99,0x66};

  25. void timer0_init();                //定時器0初始化
  26. /************函數聲明**************/
  27. void delayxms(uint z); //延時
  28. /********************************************************************
  29. * 名稱 : void delayms(uint xms)
  30. * 功能 : 延時
  31. * 輸入 : 有
  32. * 輸出 : 無
  33. ***********************************************************************/
  34. void delayms(uint xms)
  35. {
  36.    uint i,j;
  37.    for(i=xms;i>0;i--)
  38.       for(j=1700;j>0;j--);
  39. }
  40. /********************************************************************
  41. * 名稱 : Com_Init()
  42. * 功能 : 初始化串口程序,晶振11.0592, 波特率9600
  43. * 輸入 : 無
  44. * 輸出 : 無
  45. ***********************************************************************/
  46. void Com_Init()
  47. {

  48.         TMOD &=        0x0F;
  49.         TMOD |= 0x20;
  50. /************ps2*************/               
  51.     PCON = 0x00;  //波特率不加倍
  52.     SCON = 0x50;  //配置串口工作模式,使能串口接收中斷,等價于SM0=0,SM1=1,REN=1
  53.         TH1 = 0xFd;
  54.     TL1 = 0xFd;
  55.     TR1 = 1;
  56.           EA=1;          //總中斷開關
  57.         ES=1;          //串口中斷開關
  58.         ET1=0;          //定時器1中斷開關
  59. //        IP=0x10;
  60. /**************燒寫***********/        
  61. //        SM0=0;
  62. //        SM1=1;
  63. //        REN=1;                        
  64. }

  65. void input(uchar dat)
  66. {
  67.         uchar i;
  68.         for(i=0;i<8;i++)
  69.         {
  70.                 if((dat<<i)&0x80)
  71.                 {
  72.                         ser=1;
  73.                 }
  74.                 else
  75.                 {
  76.                         ser=0;
  77.                 }
  78.                 sck=0;
  79.                 sck=1;
  80.         }
  81. }

  82. void output()
  83. {
  84.         rck=0;
  85.         rck=1;
  86.         rck=0;
  87. }


  88. void delay(uint n)  //delay(x)=(2.5+x)us;
  89. {
  90.         uint i;
  91.         for(i=0;i<n;i++) _nop_();      
  92. //                _nop_();//每個_nop_();大概0.1微秒        
  93. }
  94. uchar scanout(uchar command)//手柄
  95. {
  96.     uchar i,j=1;
  97.         uchar res=0;
  98.     for(i=0;i<=7;i++)     //逐位接收     
  99.     {
  100.          if(command&0x01)
  101.         CMND=1;
  102.      else
  103.         CMND=0;
  104.      command=command>>1;
  105.                  _nop_();        
  106.                 _nop_();
  107.      CLK=0;
  108.      delay(10);
  109.          if(DATA) res=res+j;
  110.      j=j<<1;
  111.          CLK=1;
  112.          delay(3);                 
  113.     }
  114.     CMND=1;
  115.     return res;        
  116. }
  117. void Read_PS2(void)//手柄讀取程序
  118. {
  119.          uchar i;
  120.      ATT=0;
  121.          for(i=0;i<9;i++)        //掃描按鍵
  122.         {
  123.          out[i]=scanout(scan[i]);        
  124.                  }
  125.      ATT=1;                     
  126.          
  127. }                                             


  128. void main()
  129. {
  130.         IP=0x10;
  131.         Com_Init();
  132.         timer0_init();
  133.         
  134.         EN1=0;          //M4         FR
  135.         EN2=0;          //M3         RR
  136.         EN3=0;          //M2         FL
  137.         EN4=0;          //M1         RL

  138.         while(1)
  139.         {
  140.         Read_PS2();
  141.         delayms(10);        
  142.         if(out[3]==0xEF)//上,PS2手柄按鍵
  143.         {
  144.                 count=100;
  145.                 EN1=PWM;          //M4
  146.                 EN2=PWM;          //M3
  147.                 EN3=PWM;          //M2
  148.                 EN4=PWM;          //M1
  149.                 input(Tab[1] );
  150.                 output();
  151.         }
  152.         else if(out[3]==0xBF)//下
  153.         {
  154.                 count=60;
  155.                 EN1=PWM;          //M4
  156.                 EN2=PWM;          //M3
  157.                 EN3=PWM;          //M2
  158.                 EN4=PWM;          //M1
  159.                 input(Tab[1] );
  160.                 output();
  161.         }
  162.         else if(out[3]==0x7F)//左
  163.         {
  164.                 count=30;
  165.                 EN1=PWM;          //M4
  166.                 EN2=PWM;          //M3
  167.                 EN3=PWM;          //M2
  168.                 EN4=PWM;          //M1
  169.                 input(Tab[1] );
  170.                 output();
  171.         }
  172.         else if(out[3]==0xDF)//右
  173.         {
  174.                 count=10;
  175.                 EN1=PWM;          //M4
  176.                 EN2=PWM;          //M3
  177.                 EN3=PWM;          //M2
  178.                 EN4=PWM;          //M1
  179.                 input(Tab[1] );
  180.                 output();
  181.         }
  182.         else if(out[4]==0xFB)//停
  183.         {
  184.                                         EN1=0;          //M4
  185.                 EN2=0;          //M3
  186.                 EN3=0;          //M2
  187.                 EN4=0;          //M1
  188.                 input(Tab[0] );
  189.                 output();
  190.         }
  191.         else{
  192.                 EN1=0;          //M4        FR
  193.                 EN2=0;          //M3          RR
  194.                 EN3=0;          //M2         FL
  195.                 EN4=0;          //M1         RL
  196.         }

  197.         }
  198. }

  199. /****************延時處理**********************/
  200. void delayxms(uint z) //延時xms程序
  201. {
  202.     uint x,y;
  203.         for(y=z;x>0;x--)
  204.                 for(y=110;y>0;y--);
  205. }

  206. void timer0_init()
  207. {
  208.   TMOD&=0xF0;
  209.   TMOD|=0x01;
  210.   mid_TH0=(65536-500)/256;                        
  211.   mid_TL0=(65536-500)%256;               
  212.   TR0=1;
  213.   ET0=1;
  214.   EA=1;
  215. }

  216. /**************定時0中斷處理******************/
  217. void timer0_int() interrupt 1
  218. {
  219.   TMOD&=0xF0;  
  220.   TMOD|=0x01;         
  221.   TR0=0;    //設置定時器初值期間,關閉定時器
  222.   TH0=mid_TH0;
  223.   TL0=mid_TL0;
  224.   TR0=1;
  225.          
  226.   time++;
  227.   if(time<count)          //count為占空比
  228.   {
  229.         PWM=1;           //輸出高電平
  230.   }
  231.   else
  232.         PWM=0;        
  233.   if(time>=100)
  234.   {
  235.         time=0;
  236.   }
  237. }
  238. void Com_Int() interrupt 4
  239. {
  240. if(RI==1)
  241.     {
  242.                 RI=0;
  243.         }
  244. }
復制代碼


評分

參與人數 1黑幣 +12 收起 理由
通天塔 + 12

查看全部評分

回復

使用道具 舉報

無效樓層,該帖已經被刪除
ID:445766 發表于 2018-12-13 16:49 | 顯示全部樓層
mid_TH0=(65536-500)/256;
設置500及以上時,可通過手柄實現四種占空比,但是每個PWM周期大約有7秒。
200-500有時可以有時不行,200以下操縱手柄完全無反應。
猜測應該是串口和PWM沖突,但是查找百度解決方法都不可用。
回復

使用道具 舉報

ID:445766 發表于 2018-12-13 17:38 | 顯示全部樓層
  mid_TH0=(65536-500)/256;                        
  mid_TL0=(65536-500)%256;
按照這個設置,頻率應該很高啊,但是實際驅動電機周期約為7秒。
而且設置為500以下時,PS2手柄操縱會失效,猜測是和PWM沖突。
但是按照百度解決方法還不能解決。
回復

使用道具 舉報

ID:275479 發表于 2018-12-13 18:12 | 顯示全部樓層
定時器頻繁中斷,導致按鍵無法正常掃描了,用其他芯片,自動產生PWM波的那種,就不需要頻繁進入中斷了
回復

使用道具 舉報

ID:275479 發表于 2018-12-13 18:14 | 顯示全部樓層
或者把波特率跳高一些試試
回復

使用道具 舉報

ID:445766 發表于 2018-12-14 08:36 | 顯示全部樓層
通天塔 發表于 2018-12-13 18:12
定時器頻繁中斷,導致按鍵無法正常掃描了,用其他芯片,自動產生PWM波的那種,就不需要頻繁進入中斷了

大佬,問題是定時器頻繁中斷應該保證PWM輸出無誤啊,現在PWM周期很長,不符合道理啊
回復

使用道具 舉報

ID:275479 發表于 2018-12-14 09:17 | 顯示全部樓層
初學者小白 發表于 2018-12-14 08:36
大佬,問題是定時器頻繁中斷應該保證PWM輸出無誤啊,現在PWM周期很長,不符合道理啊

void timer0_int() interrupt 1
{
  TMOD&=0xF0;  
  TMOD|=0x01;         
  TR0=0;    //設置定時器初值期間,關閉定時器
  TH0=mid_TH0;
  TL0=mid_TL0;
  TR0=1;
         
  time++;
  if(time<count)          //count為占空比
  {
        PWM=1;           //輸出高電平
  }
  else
        PWM=0;        
  if(time>=100)
  {
        time=0;
  }
}
你考慮以下多長時間就進這么一次中斷,200*200us的話,大約4MS就要進一次中斷
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表