Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 14801|回復: 21
打印 上一主題 下一主題

89S51控制多個伺服馬達 C程式 請教

[複製鏈接]
跳轉到指定樓層
1#
發表於 2012-7-27 15:15:23 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
之前在網路上找到的程式如下~
基本上控制一顆沒有問題,想請教我該怎麼修改程式,才能透過不同的按鍵,去控制不同顆伺服馬達轉動..
譬如:
P1_0 ,P1_1,P1_2 控制第一顆 左轉 中間 右轉
P1_3 ,P1_4,P1_5 控制地二顆 左轉 中間 右轉
以此類推....希望能控制 5顆

謝謝~
--------------
#include <AT89X51.H>
unsigned int dutytime=20000; //65536-45536就是責任週期
unsigned int ton=4400; //高電位比例=50%
unsigned int toff=35600; //低電位比例=50%
unsigned int temp; //給計時器工作用

void timer0_initialize(void)  //初始化計時器0
{
    EA=0; //關閉中斷功能(所有中斷副程式失效)
    IE|=0x02; //開啟計時器中斷功能
    TMOD|=0x01; //設定計時器模式
    temp=65536-dutytime; //設定中斷一次的時間(預設是dutytime)
    TH0=temp/256; //填入高八位
    TL0=temp%256; //填入低八位
    TR0=1; //啟動計時器
    EA=1; //開啟中斷功能(中斷副程式可以執行)
}

void timer0_isr(void) interrupt 1 //使用計時器中斷副程式產生PWM
{
    if(P2_0==0)
    {
    TR0=0;
    temp=65536-toff;
    TH0=temp/256;
    TL0=temp%256;
    TR0=1;
    P2_0=0;
    }
    else
    {
    TR0=0;
    temp=65536-ton;
    TH0=temp/256;
    TL0=temp%256;
    TR0=1;
    P2_0=1;
    }
}
void main(void) //主程式開始

{
timer0_initialize();

    while(1)
{

if(P1_0==0)
{
ton=5500;
toff=40000-ton;
}
if(P1_1==0)
{
ton=3550;
toff=40000-ton;
}
if(P1_2==0)
{
ton=1500;  
toff=40000-ton;
}
}
}
nichal 該用戶已被刪除
2#
發表於 2012-7-27 18:23:12 | 只看該作者
參考一下這種切換方式吧
http://www.wretch.cc/blog/chipware/17881146

按鍵的部份如果要簡單一點
只要多宣告幾個變數(如ton1, toff1, ton2, toff2....)
判斷式複製貼上就可以了
祝您順利~~
3#
 樓主| 發表於 2012-7-30 17:07:52 | 只看該作者
To Nichal:
謝謝您的回覆~

我有參考您的方式,修改了一下,但因為IC不同,所以有幾個地方
不知道改的對不對,可是基本上4個都有PWM訊號,有幾個問題如下
再麻煩您費心~程式如下~Xtal=24MHz

1.修改每一個P2_0,P2_1....的ANGLE,Dutycycle就會隨著改變

#include <AT89X51.H>
#define SERVO1_PWM P2_0=1
#define SERVO2_PWM P2_1=1
#define SERVO3_PWM P2_2=1
#define SERVO4_PWM P2_3=1

#define MAX_ANGLE 4400
#define MIN_ANGLE 1500
#define MID_ANGLE 3000

unsigned int dutytime=40000;
unsigned int ton=4400;
bit start_flag;
bit change_flag;

void Timer0_Init(void);
void Timer0_ISR(void);
void Timer1_Init(void);
void Switch(unsigned int counts);
void Timer1_ISR(void);

void main(void)
{
TMOD|=0x11;
Timer1_Init();
Timer0_Init();
start_flag=0;
change_flag=0;


while(1)
  {
  if(start_flag==0)
     {
         start_flag=0;
         SERVO1_PWM;
         Switch(MAX_ANGLE);

         while (change_flag==0);
         {
     change_flag=0;
     SERVO2_PWM;
     Switch(MAX_ANGLE);
         }

     while (change_flag==0);
         {
     change_flag=0;
     SERVO3_PWM;
     Switch(MAX_ANGLE);
         }

     while (change_flag==0);
         {
     change_flag=0;
     SERVO4_PWM;
     Switch(MAX_ANGLE);
         }
         while (change_flag==0);
         {
     change_flag=0;
         }

         }
  }

}
         
void Timer0_Init(void)
{
ET0=1;
TH0=(65536-dutytime)/256;
TL0=(65536-dutytime)%256;
EA=1;
TR0=1;
}

void Timer0_ISR(void) interrupt 1
{
TF0=0;
TH0=(65536-dutytime)/256;
TL0=(65536-dutytime)%256;
start_flag=0;
}

void Timer1_Init(void)
{
TH1=(65536-ton)/256;
TL1=(65536-ton)%256;
ET1=0;
TR1=0;
}

void Switch(unsigned int counts)
{
TH1=(65536-counts)/256;
TL1=(65536-counts)%256;
ET1=1;
TR1=1;
}

void Timer1_ISR(void) interrupt 3
{
TR1=0;
P2=0x00;
change_flag=1;
}
4#
 樓主| 發表於 2012-7-30 17:20:43 | 只看該作者
問題一 修正~
1.修改每一個P2_0,P2_1....的ANGLE,Period就會隨著改變
nichal 該用戶已被刪除
5#
發表於 2012-7-31 13:11:32 | 只看該作者
PWM的寬度就是決定SERVO停住的角度
範例是用4個servo的寫法
如果只要一個
那其餘三個砍掉就可以了

有示波器嗎?
用示波器看一下波型就知道囉~~
6#
 樓主| 發表於 2012-7-31 17:46:56 | 只看該作者
回復 5# nichal

抱歉~因為我問題寫錯了...
原問題
------------------------------------------------------------------
1.修改每一個P2_0,P2_1....的ANGLE,Dutycycle 就會隨著改變
------------------------------------------------------------------
不是dutycycle 是 週期 會隨著改變

我只要輸入不同PWM寬度
就是以下三行的值,整個週期就會改變~
#define MAX_ANGLE 4400
#define MIN_ANGLE 1500
#define MID_ANGLE 3000

再麻煩您費心~謝謝~
nichal 該用戶已被刪除
7#
發表於 2012-7-31 17:53:31 | 只看該作者
while(1)
  {
  if(start_flag==0)
     {
         start_flag=1;
..................................

再試試看吧
8#
 樓主| 發表於 2012-8-1 08:59:29 | 只看該作者
回復 7# nichal

哇~可以了耶~
我看了一天....
你只花了 10分鐘....
唉...我真笨~

感恩喔~
nichal 該用戶已被刪除
9#
發表於 2012-8-1 09:23:54 | 只看該作者
程式是我寫的
所以知道寫那些參數的用意
沒有什麼啦~~~

要把程式看懂變成自己的工具唷!!
祝你順利~~~
10#
 樓主| 發表於 2012-8-27 14:02:38 | 只看該作者
回復 9# nichal
不好意思~請教一下~
我之前是用 AT89S51 配上 MG995的馬達 ,都很正常~
但是因為 AT89S51 timer 只有2個沒辦法產生包率,
後來就換成 AT89C51ED2,然後接上馬達之後,轉到指定角度....
馬達就會發出"吱吱...喳喳.. 吱...喳..."然後很像便秘一樣的小抖動(非常小)
我有量過波形,都很正常也沒抖動...
又要煩煩您了~感謝~
nichal 該用戶已被刪除
11#
發表於 2012-8-28 09:09:26 | 只看該作者
如果波形都一樣
那你要思考是不是驅動電流不足或是準位不足
送給馬達的訊號是否要外加提供或緩衝器
再試試看囉~~

不然就是馬達的齒箱已經有點磨耗
拆開來檢查一下是不是要潤滑或是更換
12#
 樓主| 發表於 2012-8-28 12:09:02 | 只看該作者
回復 11# nichal
謝謝~
波形一樣
電流,準位確認過
馬達之前有卡死...被我拆過,有個齒輪缺一腳 <==但在AT89S51 正常,所以我認為應該不是這個問題

最後外加緩衝器...是什麼意思呢?可否指點指點...謝謝你~
xu3u4rmp4 該用戶已被刪除
13#
發表於 2012-8-28 22:06:49 | 只看該作者
緩衝器 74LS07 試試看
nichal 該用戶已被刪除
14#
發表於 2012-8-29 12:03:23 | 只看該作者
回復 12# martinlee0312


    你所確認的電流是"信號電流"還是"馬達出力電流"?
加緩衝器就是要讓信號電流穩定且不飄移用的
因為你更換的是IC
所以要確認的是有更換的部分跟原來有什麼不一樣
如果只確認馬達電流是不對的唷~~~
15#
 樓主| 發表於 2012-9-12 11:37:25 | 只看該作者
回復 14# nichal
謝謝~
問題解決了~換一顆 馬達 就好了~
原來那一顆被我搞到齒輪掉光光~哈....
也不知道是什麼問題了~
16#
 樓主| 發表於 2012-9-12 15:51:07 | 只看該作者
回復 14# nichal
另外在請教一個問題...
網路有人提到,用分時系統去產生PWM訊號...
我用8051 C 也可以寫分時系統嗎?

謝謝~
nichal 該用戶已被刪除
17#
發表於 2012-9-12 17:49:43 | 只看該作者
我的程式寫法就是一個簡單的分時系統
每個servo分配不同的時間
時間到了就換下一個servo
所以一共只用了兩個Timer

如果是掃瞄的寫法
會受到中斷或判斷式的影響
使得脈衝的寬度不穩定
參考看看囉~~~
nichal 該用戶已被刪除
18#
發表於 2012-9-12 17:59:44 | 只看該作者
齒輪牙齒掉光光
很可能是正反轉間隔太短又太頻繁
或是負載過大造成的
放慢一下你的角度切換速度吧
19#
 樓主| 發表於 2012-9-14 15:12:36 | 只看該作者
回復 18# nichal
謝謝你的建議~
又有問題要請教了....
這個程式我現在還不是非常清楚他的動作方式,我在您的工作站留言裏,你有提到這個原理有很多地方都有清楚說明,
不知道是否方便給我幾個連結呢?
另外最近我把PWM的訊號加到15個...結果波形會抖動
我想可能是因為超過了週期的20ms了...
不知道是否還有其他方式能產生多個PWM呢?

謝謝你~
nichal 該用戶已被刪除
20#
發表於 2012-9-14 21:42:46 | 只看該作者
本帖最後由 nichal 於 2012-9-14 21:49 編輯

http://www.robofun.net/forum/viewthread.php?tid=438
這是論壇上很久以前的文章
你看一下裡面的線路圖
有提到一個74HC595
用這個搭配一個Timer
就可以擴充為8個servo channel
兩個Timer就可以造出16個servo channel
裡面有很多相關連結都是很有用的文章建議每篇都瀏覽一下

花點時間在自組機器人版塊裡瀏覽一下舊文章
應該還可以找到更多的相關資料
話說我的文章已經是四年前寫的
中間累積的文章很多
可能要花點時間多挖寶.....

另外
論壇最下面有一個論壇統計
點進去找一下較多人討論的主題
應該也會有相關的資料
再來就要請你多多動手啦!!
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2024-4-28 18:24 , Processed in 0.192953 second(s), 8 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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