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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機3個定時器驅動機器人PWM無刷直流電機進行編程運動 源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:358930 發(fā)表于 2019-1-16 18:52 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
買了幾個機器人PWM無刷直流電機,內部有驅動器,所有功能都可以單片編程IO口控制,弄了個簡單程序先動行一下,有1602液晶顯示器,可同時驅動4路PWM信號,用了3個定時器

制作出來的實物圖如下:


單片機程序源碼:
  1. #include"reg52.h"
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. //sfr T2MOD =0xC9;  //定時器中斷2TMOD必須定義
  5. /*-----------------------PWM定義---------------------------*/
  6. sbit RS = P2^6 ;
  7. sbit RW = P2^5 ;
  8. sbit EN = P2^7 ;

  9. sbit STA7 = P0^7;

  10. uchar PWM_T=0;//PWM脈沖周期PWM_T(max)=256*中斷定時時間(1ms)


  11. //PWM物理地址通道定義,物理地址根據(jù)需要自由定義
  12. sbit PWM_IO0 = P1^0;//接電機NO.1
  13. sbit PWM_IO1 = P1^1;//接電機NO.2
  14. sbit PWM_IO2 = P1^2;//接電機NO.3
  15. sbit PWM_IO3 = P1^3;//接電機NO.4


  16. //PWM脈沖占空比
  17. uint PWM_IO0_ZKB=20;  //脈沖占空比,0~255,=0時輸出最大
  18. uint PWM_IO1_ZKB=20;
  19. uint PWM_IO2_ZKB=20;
  20. uint PWM_IO3_ZKB=20;


  21. /*---------------------------------------------------------*/


  22. sbit s0 = P3^6; //按s0減小占空比
  23. sbit s1 = P3^7;//按s1增加占空比


  24. sbit RL = P3^5;//按健 正反轉
  25. sbit RUN_STOP = P3^4;//按健啟動與停止


  26. sbit RL1 = P3^3;//輸出 正反轉
  27. sbit RUN_STOP1 = P3^2;//輸出 啟動與停止


  28. uint KG;//開關
  29. uint FX;//方向




  30. void Delay1ms(uint a)                //@11.0592MHz
  31. {
  32.         unsigned char i, j;


  33.       
  34.         i = 2;
  35.         j = 199;
  36.         do
  37.         {
  38.                 while (--j);
  39.         } while (--i);
  40. }






  41. /*---------------定時器2初始化-------------------*/
  42. void timer2_init()//定時器2初始化
  43. {
  44.         RCAP2H=0xff;  //16位計數(shù)器,定時39us
  45.         RCAP2L=0xdc;  //X=0xffdc=65500;T=(65536-X)*機器周期(11.0592MHz,1.085us)
  46.         //TH2=RCAP2H;     //會自動重裝
  47.         //TL2=RCAP2L;
  48.         T2CON=0;
  49.         T2MOD=0;
  50.         EA=1;
  51.         ET2=1;
  52.         TR2=1;
  53. }


  54. /*--------------定時器2中斷服務程序----------------------------*/
  55. void timer2() interrupt 5
  56. {      
  57.         TF2=0; //注意:定時器2必須由軟件對溢出標志位清零,
  58.                //這里與定時器0和定時器1不同
  59.         //PWM處理
  60.            PWM_T++;
  61.         if(PWM_T == 255)//取到最大值
  62.         {PWM_T = PWM_IO0 = PWM_IO1 = PWM_IO2 = PWM_IO3 = 0;}        //所有通道脈沖拉至低電平
  63.       
  64.         //通道脈沖電平拉高
  65.         if(PWM_T == PWM_IO0_ZKB)  //通道0脈沖得高電平
  66.                 PWM_IO0 = 1;      
  67.       
  68.         if(PWM_T == PWM_IO1_ZKB)  //通道1脈沖得高電平
  69.                 PWM_IO1 = 1;
  70.       
  71.         if(PWM_T == PWM_IO2_ZKB)  //通道2脈沖得高電平
  72.         PWM_IO2 = 1;
  73.                
  74.         if(PWM_T == PWM_IO3_ZKB)  //通道3脈沖得高電平
  75.                 PWM_IO3 = 1;      
  76. }
  77. /**
  78. * 等待繁忙標志
  79. */
  80. void wait(void)
  81. {
  82.         P0 = 0xFF;
  83.       
  84.         do
  85.         {
  86.                 RS = 0;
  87.                 RW = 1;
  88.                 EN = 0;
  89.                 EN = 1;
  90.         }while (STA7 == 1);
  91.         EN = 0;
  92. }


  93. /**
  94. * 寫數(shù)據(jù)
  95. */
  96. void w_dat(uint dat)
  97. {
  98.         wait();
  99.         EN = 0;
  100.         P0 = dat;
  101.         RS = 1;
  102.         RW = 0;
  103.         EN = 1;
  104.         EN = 0;
  105. }


  106. /**
  107. * 寫命令
  108. */
  109. void w_cmd(uint cmd)
  110. {
  111.         wait();
  112.         EN = 0;
  113.         P0 = cmd;
  114.         RS = 0;
  115.         RW = 0;
  116.         EN = 1;
  117.         EN = 0;
  118. }


  119. /**
  120. * 發(fā)送字符串到LCD
  121. */
  122. void write_zfc(uchar *p)//定義一個帶指針的函數(shù)?(字符串)
  123. {
  124.         while(*p!=0)//不能用";"
  125.         w_dat(*p++);
  126. }


  127. /**
  128. * 初始化1602
  129. */
  130. void Init_LCD1602(void)
  131. {
  132.         w_cmd(0x38);  // 16*2顯示,5*7點陣,8位數(shù)據(jù)接口
  133.         w_cmd(0x0C);  // 顯示器開、光標開、光標允許閃爍
  134.         w_cmd(0x06);  // 文字不動,光標自動右移
  135.         w_cmd(0x01);  // 清屏
  136. }


  137. void KEY()//
  138.   {
  139.   if(s0==0) //按s0減小占空比
  140.                 {
  141.                 while(!s0);//等待
  142.                         {
  143.                               
  144.                                         PWM_IO0_ZKB = PWM_IO0_ZKB-1;  
  145.                                         PWM_IO1_ZKB = PWM_IO1_ZKB-1;
  146.                                         PWM_IO2_ZKB = PWM_IO2_ZKB-1;
  147.                                         PWM_IO3_ZKB = PWM_IO3_ZKB-1;                              
  148.                        
  149.                         }
  150.                         if(PWM_IO0_ZKB<=20)PWM_IO0_ZKB=20;//太小不能啟動
  151.                        
  152.                        
  153.                 }
  154.                 if(s1==0)  //按s1增加占空比
  155.                 {
  156.                         while(!s1);//等待
  157.                         {                       
  158.                                         PWM_IO0_ZKB = PWM_IO0_ZKB+1;  
  159.                                         PWM_IO1_ZKB = PWM_IO1_ZKB+1;
  160.                                         PWM_IO2_ZKB = PWM_IO2_ZKB+1;
  161.                                         PWM_IO3_ZKB = PWM_IO3_ZKB+1;                                       
  162.                                                                
  163.                         }
  164.                         if(PWM_IO0_ZKB>100)PWM_IO0_ZKB=100;//太大不能啟動                       
  165.                 }

  166.           if(RL==0)  //按RL
  167.                 {
  168.                         Delay1ms(2);
  169.                         if(RL==0)  //按RL
  170.                  while(!RL);//等待按健松手
  171.                  RL1=~RL1;//取反(=1正轉,=0反轉)
  172.                 }
  173.            if(RUN_STOP==0)  //按啟停
  174.                 {
  175.                        
  176.                         Delay1ms(2);
  177.                         if(RUN_STOP==0)  //按啟停
  178.                        
  179.                  while(!RUN_STOP);//等待按健松手
  180.                  RUN_STOP1=~RUN_STOP1;//取反(=1啟動,=0停止)                                       
  181.                 }


  182.   }
  183. /*------------------------------------------------
  184.                     定時器初始化子程序
  185. ------------------------------------------------*/
  186. void Init_Timer1(void)
  187. {
  188. TMOD |= 0x10;          //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響
  189. TH1=0x00;              //給定初值,這里使用定時器最大值從0開始計數(shù)一直到65535溢出
  190. TL1=0x00;
  191. EA=1;            //總中斷打開
  192. ET1=1;           //定時器中斷打開
  193. TR1=1;           //定時器開關打開
  194. }
  195. /*------------------------------------------------
  196.                     定時器初始化子程序
  197. ------------------------------------------------*/
  198. void Init_Timer0(void)
  199. {
  200. TMOD |= 0x01;          //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響                     
  201. TH0=0x00;              //給定初值,這里使用定時器最大值從0開始計數(shù)一直到65535溢出
  202. TL0=0x00;
  203. EA=1;            //總中斷打開
  204. ET0=1;           //定時器中斷打開
  205. TR0=1;           //定時器開關打開
  206. }


  207. void PIAY(void)////顯示運行狀態(tài)
  208. {
  209. if(RUN_STOP1==1)
  210.                 {
  211.     w_cmd(0xC0);//LCD1602顯示地址為第一排第一個
  212.                 write_zfc("RUN");      
  213.                 }      
  214.                 else
  215.                 {
  216.     w_cmd(0xC0);//LCD1602顯示地址為第一排第一個
  217.                 write_zfc("OFF");
  218.                 }      
  219. if(RL1==0)
  220.                 {
  221.     w_cmd(0xC0+4);//LCD1602顯示地址為第一排第一個
  222.                 write_zfc("<<--");                       
  223.                 }      
  224.                 else
  225.                 {
  226.     w_cmd(0xC0+4);//LCD1602顯示地址為第一排第一個
  227.                 write_zfc("-->>");
  228.                 }      
  229.         }
  230. /*------------主函數(shù)---------------*/
  231. void main()
  232. {
  233.         timer2_init();//定時器2初始化
  234.   Init_LCD1602();   //LCD1602初始化
  235.         Init_Timer0();//定時器0初始化
  236.         Init_Timer1();//定時器1初始化
  237.       
  238.         RL1=1;//初始化=1,開機電機正轉
  239.         RUN_STOP1=1;//初始化=1,開機電機轉動
  240.                
  241.         while(1)
  242.         {
  243.              KEY();//按健掃描      
  244.                  PIAY();//顯示運行狀態(tài)
  245.                         
  246.                  
  247.                 w_cmd(0x80);//LCD1602顯示地址為第一排第一個
  248.                 write_zfc("PWM:");               
  249.                 //w_dat(PWM_IO0_ZKB/1000+0x30);
  250.                 w_dat(PWM_IO0_ZKB%1000/100+0x30);
  251.                 w_dat(PWM_IO0_ZKB%100/10+0x30);
  252.                 w_dat(PWM_IO0_ZKB%10+0x30);
  253.                 //write_zfc(" KHz");
  254.                
  255.                
  256.                 w_cmd(0xc0+9);//LCD1602顯示地址為第一排第一個
  257.                 write_zfc("FX:");
  258.                
  259.                 //w_dat(PWM_IO0_ZKB/1000+0x30);
  260.                 w_dat(FX%1000/100+0x30);
  261.                 w_dat(FX%100/10+0x30);
  262.                 w_dat(FX%10+0x30);
  263.                
  264.                 w_cmd(0x80+9);//LCD1602顯示地址為第一排第一個
  265.                 write_zfc("KG:");
  266.                
  267.                 //w_dat(PWM_IO0_ZKB/1000+0x30);
  268.                 w_dat(KG%1000/100+0x30);
  269.                 w_dat(KG%100/10+0x30);
  270.                 w_dat(KG%10+0x30);
  271.                
  272.         }
  273. }
  274. /*------------------------------------------------
  275.                  定時器中斷子程序
  276. ------------------------------------------------*/
  277. void Timer1_isr(void) interrupt 3 using 1
  278. {
  279. TH1=0x00;                 //重新賦值
  280. TL1=0x00;
  281.         FX++;//運行方向調節(jié)
  282.         if(FX>30)
  283.         {
  284.         FX=0;
  285.         //RUN_STOP1=~RUN_STOP1;//取反(=1啟動,=0停止)
  286.   省去幾多行…………
復制代碼

全部資料51hei下載地址:
1602顯并STC89機器人電機PWM控器OK3.zip (54.21 KB, 下載次數(shù): 84)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發(fā)
ID:614355 發(fā)表于 2019-9-21 11:21 | 只看該作者
很詳細的程序
回復

使用道具 舉報

板凳
ID:521117 發(fā)表于 2019-9-27 22:21 | 只看該作者
學習學習
回復

使用道具 舉報

地板
ID:921641 發(fā)表于 2021-10-24 10:15 | 只看該作者
樓主你好,我用的是STC89C58RD單片機,在使用3個定時器中斷功能時,發(fā)現(xiàn)通過中斷控制引腳輸出高低電平會出現(xiàn)紊亂的情況;
比如定時器0是50毫秒中斷,定時器1是10毫秒中斷,定時器2是1毫秒中斷
然后第一個燈用定時器0控制是中斷20次,亮滅交替,也就是每1秒交替閃爍;
第二個燈用定時器1控制是中斷50次,亮滅交替,也就是每500毫秒交替閃爍;
第三個燈用定時器2控制,是中斷100次,亮滅交替,也就是100毫秒交替閃爍。
然而實際下載到單片機運行時,發(fā)現(xiàn)第1個燈竟然比第二個燈閃爍還要快!!
而且第三個燈閃爍的頻率遠高于100毫秒,我把計數(shù)變量提高100倍才差不多。
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线观看成人免费视频 | 天天夜天天操 | 日韩色图视频 | 国产激情视频在线观看 | 日韩精品视频在线 | 久草福利| 99re在线视频精品 | 美日韩视频 | 亚洲综合日韩精品欧美综合区 | 亚洲天堂中文字幕 | 亚洲免费在线视频 | 天天天天天天操 | 久久久久亚洲精品 | 久久精品亚洲精品国产欧美kt∨ | 亚洲日本中文 | 日韩在线一区二区三区 | 请别相信他免费喜剧电影在线观看 | 日韩电影中文字幕 | 成人av网页 | 亚洲一区二区中文字幕 | 国产成人福利在线观看 | 天天精品在线 | 国产成人一区二 | 欧美综合精品 | 欧美激情亚洲激情 | h视频在线免费观看 | 亚洲一区二区在线播放 | 高清视频一区二区三区 | 日韩高清国产一区在线 | 欧美一区成人 | 黄网址在线观看 | 日韩在线一区二区 | 日韩国产精品一区二区三区 | 精品视频在线观看 | 国产欧美一区二区三区在线看 | 日日骚视频 | 成人精品福利 | 国产一区| av中文字幕在线 | www.久草.com | 国产精品国产成人国产三级 |