89S52控制RC Servo |
答題得分者是:㊣
|
david_ls
一般會員 ![]() ![]() 發表:5 回覆:13 積分:3 註冊:2005-01-31 發送簡訊給我 |
請教前輩有關控制 遙控模型 伺服器的問題
我查了一些資料 RC Servo 使用的是PWM Duty Cycle介於 1ms ~ 2ms, 週期50~60Hz http://chipware.myvnc.com/phpbb/viewforum.php?f=20 我使用的是Keil C, 單晶片AT89S52 程式Download到單晶片上執行, 結果伺服器完全不動作! 想請板上大大幫我看看哪裡有問題了! Ps. 8051直接輸出接Servo的Signal端, 不知道是否會有問題? 感激不盡 Source code: //--- 2009.06.25 Writed by Te-Jung Lo #include #define PWMDUTY 1000 // 2us * 500 = 1ms, 2us * 750 = 1.5ms, 2us * 1000 = 2ms #define PWMWIDTH 11250 //[24T => 12MHz/24 = 0.5MHz] 2us x 11250 = 22.5ms sbit LED = P0^0; sbit PWM = P0^1; void timer0 () interrupt 1 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { TL0 = (65536 - PWMDUTY) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH0 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // Timer count from (65536 - PWMDUTY) to 65536, total times: PWMDUTY TL1 = (65536 - (PWMWIDTH)) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH1 = ((65536 - (PWMWIDTH)) & 0xFF00) >> 8; // Timer count from (65536 - PWMWIDTH) to 65536, total times: PWMWIDTH LED = 1; PWM = 1; TR1 = 1; // Timer_1 start to count } void timer1 () interrupt 3 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { LED = 0; PWM = 0; TR0 = 1; // Timer_0 start to count } void main() { IE = 0x8A; // Timer_0 enable TMOD= 0x11; // Timer_0 interrupt enable // initialize timer TL0 = (65536 - PWMDUTY) & 0x00FF; // & 0x00FF: mask Lower bit TH0 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // & 0xFF00) >> 8: mask Higher bit and then shift 8 bits for reserving High bits PWM = 0; // initial PWM = 0 TR0 = 1; // Timer_0 start to count while(1); } 編輯記錄
david_ls 重新編輯於 2009-06-25 13:51:12, 註解 無‧
|
david_ls
一般會員 ![]() ![]() 發表:5 回覆:13 積分:3 註冊:2005-01-31 發送簡訊給我 |
感謝老天, 因為在寫電子鐘程式時發現我的時脈計算是錯誤的@@, 修改後 已經可以work了^_^
Timer的正確T數是 12T 輸入脈波是12MHz, 所以 12MHz/12 = 1MHz(Timer累加一次所耗時間是1us) 另外PWM pulse的部份也寫反了, 波形變成標準波形的反相, 自己把 Timer_0與Timer_1的暫存器互相對調, 還有, 我在8051 PWM的輸出P2.0外加一顆pnp電晶體來推動Servo的訊號線, 不過後來發現是多餘的, 但最後有找到問題自己已經很滿足了^^ 紅色註記部份是錯誤的地方 Source code: //--- 2009.06.25 Writed by Te-Jung Lo #include #define PWMDUTY 1000 // 2us * 500 = 1ms, 2us * 750 = 1.5ms, 2us * 1000 = 2ms #define PWMWIDTH 11250 //[24T => 12MHz/24 = 0.5MHz] 2us x 11250 = 22.5ms sbit LED = P0^0; sbit PWM = P0^1; void timer0 () interrupt 1 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { TL0 = (65536 - PWMDUTY) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH0 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // Timer count from (65536 - PWMDUTY) to 65536, total times: PWMDUTY TL1 = (65536 - (PWMWIDTH)) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH1 = ((65536 - (PWMWIDTH)) & 0xFF00) >> 8; // Timer count from (65536 - PWMWIDTH) to 65536, total times: PWMWIDTH LED = 1; PWM = 1; TR1 = 1; // Timer_1 start to count } void timer1 () interrupt 3 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { LED = 0; PWM = 0; TR0 = 1; // Timer_0 start to count } void main() { IE = 0x8A; // Timer_0 enable TMOD= 0x11; // Timer_0 interrupt enable // initialize timer TL0 = (65536 - PWMDUTY) & 0x00FF; // & 0x00FF: mask Lower bit TH0 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // & 0xFF00) >> 8: mask Higher bit and then shift 8 bits for reserving High bits PWM = 0; // initial PWM = 0 TR0 = 1; // Timer_0 start to count while(1); } ------------------------------------------------------------------------------------------------------------------------ 修改後的完整Keil C程式 //--- 2009.06.25 Writed by Te-Jung Lo #include #define PWMWIDTH 22500 // [12T => 12MHz/12 = 1MHz] 1us x 22500 = 22.5ms int PWMDUTY; // 1us * 1000 = 1ms, 1us * 1500 = 1.5ms, 1us * 2000 = 2ms sbit SW = P0^0; sbit PWM = P2^0; void timer0 () interrupt 1 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { TL1 = (65536 - PWMDUTY) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH1 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // Timer count from (65536 - PWMDUTY) to 65536, total times: PWMDUTY TL0 = (65536 - (PWMWIDTH)) & 0x00FF; // if Timer count to 0x1111_1111, there will held a interrupt TH0 = ((65536 - (PWMWIDTH)) & 0xFF00) >> 8; // Timer count from (65536 - PWMWIDTH) to 65536, total times: PWMWIDTH PWM = 1; TR1 = 1; // Timer_1 start to count } void timer1 () interrupt 3 // interrupt 1 for Timer_0, interrupt 3 for Timer_1 { PWM = 0; TR0 = 1; // Timer_0 start to count } void main() { IE = 0x8A; // Timer_0 enable TMOD= 0x11; // Timer_0 interrupt enable // initialize timer TL0 = (65536 - PWMDUTY) & 0x00FF; // & 0x00FF: mask Lower bit TH0 = ((65536 - PWMDUTY) & 0xFF00) >> 8; // & 0xFF00) >> 8: mask Higher bit and then shift 8 bits for reserving High bits PWM = 0; // initial PWM = 0 TR0 = 1; // Timer_0 start to count while(1){ if(SW == 1) PWMDUTY = 1000; // PWM_Duty = 1us * 1000 = 1ms else PWMDUTY = 2000; // PWM_Duty = 1us * 2000 = 2ms } }
編輯記錄
david_ls 重新編輯於 2009-06-25 20:43:13, 註解 無‧
|
㊣
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:261 回覆:2302 積分:1667 註冊:2005-01-04 發送簡訊給我 |
|
hch5327
一般會員 ![]() ![]() 發表:0 回覆:4 積分:0 註冊:2009-08-20 發送簡訊給我 |
|
david_ls
一般會員 ![]() ![]() 發表:5 回覆:13 積分:3 註冊:2005-01-31 發送簡訊給我 |
您可以先檢查看看Code的PWM輸出是否為固定的Duty Cycle, 也就是說只輸出一種角度的PWM訊號(Code不妨可以PO出來讓大家參考, 以利檢查是否Code有誤)
針對一樓的8051 C Code: 電路部份我先用文字描述給你, 若還是無法成功我再畫給你看(我是懶惰蟲^^), 8051我是採用 12MHz 的震盪頻率, PWM輸出腳位為P0.1, 和Servo的Signal線相接, Servo的電源當然也要一起接上, 然而我的Code中有將P0.0拉出, 連接一顆LED燈, 這是我自己測試訊PWM號有無輸出觀測用的(個人覺得加上LED成功率會比較高@@) 針對二樓修改後的8051 C Code: 硬體如同宣告部份 sbit SW = P0^0; sbit PWM = P2^0; P0.0拉出一條導線, P2^0為PWM訊號輸出, 當P0.0 接觸 5V時, PWM輸出的派波寬度為1ms, 反之若接地, 則輸出2ms 大致上是如此! 若還有問題, 很歡迎您跟我共同討論研究! Rgds, David
編輯記錄
david_ls 重新編輯於 2009-08-22 11:20:13, 註解 無‧
|
hch5327
一般會員 ![]() ![]() 發表:0 回覆:4 積分:0 註冊:2009-08-20 發送簡訊給我 |
|
hch5327
一般會員 ![]() ![]() 發表:0 回覆:4 積分:0 註冊:2009-08-20 發送簡訊給我 |
又試了幾天,不管PWMWIDTH、PWMDUTY給什麼值,都一樣一直轉,我用555來做就可經由可變電阻來控制轉向及角度,但用89S52就是一直轉,不知跟RC SERVO 廠牌有無關係,他好像也還分數位及類比的。
請問你是用哪一種RC SERVO ? 我是用http://goods.ruten.com.tw/item/show?11090710848460 這個的。謝謝! |
hch5327
一般會員 ![]() ![]() 發表:0 回覆:4 積分:0 註冊:2009-08-20 發送簡訊給我 |
|
david_ls
一般會員 ![]() ![]() 發表:5 回覆:13 積分:3 註冊:2005-01-31 發送簡訊給我 |
===================引 用 hch5327 文 章===================
我把PWMWIDTH 及 PWMDUTY 顛倒,竟然可運作,跟你1樓的一樣,現在剩下精確度的問題了,不過這樣跟你2樓的更正又互相牴觸,實在搞不懂,然道真的跟廠牌型號有關? 謝謝! 您好! 我用的Servo跟你買的很可能是同一顆(外型顏色包裝價格跟規格), 對於提到 "顛倒" 就可以正常的情形, 我的看法是程式部份可能有地方沒改到, 導致會有反過來的情形, 我印象中在寫Servo PWM的Timer部分也遇到類似的問題!! 提供您參考! Rgds, David |
ererer40
初階會員 ![]() ![]() 發表:37 回覆:91 積分:45 註冊:2008-05-02 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |