Robofun 機器人論壇
標題:
89S51控制多個伺服馬達 C程式 請教
[打印本頁]
作者:
martinlee0312
時間:
2012-7-27 15:15
標題:
89S51控制多個伺服馬達 C程式 請教
之前在網路上找到的程式如下~
基本上控制一顆沒有問題,想請教我該怎麼修改程式,才能透過不同的按鍵,去控制不同顆伺服馬達轉動..
譬如:
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
時間:
2012-7-27 18:23
參考一下這種切換方式吧
http://www.wretch.cc/blog/chipware/17881146
按鍵的部份如果要簡單一點
只要多宣告幾個變數(如ton1, toff1, ton2, toff2....)
判斷式複製貼上就可以了
祝您順利~~
作者:
martinlee0312
時間:
2012-7-30 17:07
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;
}
作者:
martinlee0312
時間:
2012-7-30 17:20
問題一 修正~
1.修改每一個P2_0,P2_1....的ANGLE,Period就會隨著改變
作者:
nichal
時間:
2012-7-31 13:11
PWM的寬度就是決定SERVO停住的角度
範例是用4個servo的寫法
如果只要一個
那其餘三個砍掉就可以了
有示波器嗎?
用示波器看一下波型就知道囉~~
作者:
martinlee0312
時間:
2012-7-31 17:46
回復
5#
nichal
抱歉~因為我問題寫錯了...
原問題
------------------------------------------------------------------
1.修改每一個P2_0,P2_1....的ANGLE,
Dutycycle
就會隨著改變
------------------------------------------------------------------
不是dutycycle 是
週期
會隨著改變
我只要輸入不同PWM寬度
就是以下三行的值,整個週期就會改變~
#define MAX_ANGLE 4400
#define MIN_ANGLE 1500
#define MID_ANGLE 3000
再麻煩您費心~謝謝~
作者:
nichal
時間:
2012-7-31 17:53
while(1)
{
if(start_flag==0)
{
start_flag=
1
;
..................................
再試試看吧
作者:
martinlee0312
時間:
2012-8-1 08:59
回復
7#
nichal
哇~可以了耶~
我看了一天....
你只花了 10分鐘....
唉...我真笨~
感恩喔~
作者:
nichal
時間:
2012-8-1 09:23
程式是我寫的
所以知道寫那些參數的用意
沒有什麼啦~~~
要把程式看懂變成自己的工具唷!!
祝你順利~~~
作者:
martinlee0312
時間:
2012-8-27 14:02
回復
9#
nichal
不好意思~請教一下~
我之前是用 AT89S51 配上 MG995的馬達 ,都很正常~
但是因為 AT89S51 timer 只有2個沒辦法產生包率,
後來就換成 AT89C51ED2,然後接上馬達之後,轉到指定角度....
馬達就會發出"吱吱...喳喳.. 吱...喳..."然後很像便秘一樣的小抖動(非常小)
我有量過波形,都很正常也沒抖動...
又要煩煩您了~感謝~
作者:
nichal
時間:
2012-8-28 09:09
如果波形都一樣
那你要思考是不是驅動電流不足或是準位不足
送給馬達的訊號是否要外加提供或緩衝器
再試試看囉~~
不然就是馬達的齒箱已經有點磨耗
拆開來檢查一下是不是要潤滑或是更換
作者:
martinlee0312
時間:
2012-8-28 12:09
回復
11#
nichal
謝謝~
波形一樣
電流,準位確認過
馬達之前有卡死...被我拆過,有個齒輪缺一腳 <==但在AT89S51 正常,所以我認為應該不是這個問題
最後外加緩衝器...是什麼意思呢?可否指點指點...謝謝你~
作者:
xu3u4rmp4
時間:
2012-8-28 22:06
緩衝器 74LS07 試試看
作者:
nichal
時間:
2012-8-29 12:03
回復
12#
martinlee0312
你所確認的電流是"信號電流"還是"馬達出力電流"?
加緩衝器就是要讓信號電流穩定且不飄移用的
因為你更換的是IC
所以要確認的是有更換的部分跟原來有什麼不一樣
如果只確認馬達電流是不對的唷~~~
作者:
martinlee0312
時間:
2012-9-12 11:37
回復
14#
nichal
謝謝~
問題解決了~換一顆 馬達 就好了~
原來那一顆被我搞到齒輪掉光光~哈....
也不知道是什麼問題了~
作者:
martinlee0312
時間:
2012-9-12 15:51
回復
14#
nichal
另外在請教一個問題...
網路有人提到,用分時系統去產生PWM訊號...
我用8051 C 也可以寫分時系統嗎?
謝謝~
作者:
nichal
時間:
2012-9-12 17:49
我的程式寫法就是一個簡單的分時系統
每個servo分配不同的時間
時間到了就換下一個servo
所以一共只用了兩個Timer
如果是掃瞄的寫法
會受到中斷或判斷式的影響
使得脈衝的寬度不穩定
參考看看囉~~~
作者:
nichal
時間:
2012-9-12 17:59
齒輪牙齒掉光光
很可能是正反轉間隔太短又太頻繁
或是負載過大造成的
放慢一下你的角度切換速度吧
作者:
martinlee0312
時間:
2012-9-14 15:12
回復
18#
nichal
謝謝你的建議~
又有問題要請教了....
這個程式我現在還不是非常清楚他的動作方式,我在您的工作站留言裏,你有提到這個原理有很多地方都有清楚說明,
不知道是否方便給我幾個連結呢?
另外最近我把PWM的訊號加到15個...結果波形會抖動
我想可能是因為超過了週期的20ms了...
不知道是否還有其他方式能產生多個PWM呢?
謝謝你~
作者:
nichal
時間:
2012-9-14 21:42
本帖最後由 nichal 於 2012-9-14 21:49 編輯
http://www.robofun.net/forum/viewthread.php?tid=438
這是論壇上很久以前的文章
你看一下裡面的線路圖
有提到一個74HC595
用這個搭配一個Timer
就可以擴充為8個servo channel
兩個Timer就可以造出16個servo channel
裡面有很多相關連結都是很有用的文章建議每篇都瀏覽一下
花點時間在自組機器人版塊裡瀏覽一下舊文章
應該還可以找到更多的相關資料
話說我的文章已經是四年前寫的
中間累積的文章很多
可能要花點時間多挖寶.....
另外
論壇最下面有一個論壇統計
點進去找一下較多人討論的主題
應該也會有相關的資料
再來就要請你多多動手啦!!
作者:
HelloEdward
時間:
2013-12-21 12:01
請問您有幾顆伺服馬達要控制?
我這裡有做即時多工系統(software)
時間解析可至244us/4096hz如果您在台中
倒是可以來控制看看
另時間中斷程式首先要將結果輸出
判斷的工作要安排在後面
作者:
pizg
時間:
2014-7-16 00:08
這是論壇上很久以前的文章
你看一下裡面的線路圖
有提到一個74HC595
用這個搭配一個Timer
就可以擴充 ...
nichal 發表於 2012-9-14 21:42
請問 有沒有您說的這個電路圖?
歡迎光臨 Robofun 機器人論壇 (https://robofun.net/forum/)
Powered by Discuz! X3.2