Robofun 機器人論壇

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

16 channel serial servo controller(AT90S4414)

[複製鏈接]
跳轉到指定樓層
1#
發表於 2006-8-9 11:16:42 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
http://www.seattlerobotics.org/encoder/200106/16csscnt.htm
http://www.seattlerobotics.org/encoder/200106/fig3.pdf
[table=128]   [size=-1]
Search WWW  Search seattlerobotics.org


16 channel serial servo controller for robotic applicationsDesign & Development
George Vastianos Electronics Engineer BSc.
Dipl. from Electronics Department,
Faculty of Technological Applications,
Technological Educational Institute of Piraeus, Greece

george.vastianos@ieee.org
Table of contents
0. Abstract
1. Basic theory
1.1 The servo motors
1.2 How to use servo motors to walk!
1.3 The AT90S4414 microcontroller
2. Project's hardware
3. Project's software
4. References
0. Abstract
This article describes a servo motor controller that is able to control up to 16 hobby servo motors and its based on the AT90S4414 microcontroller (a member of Atmel's AVR Family). This servo controller is ideal in cases of building small robotic arms (3 to 5 axes) or small walker mobile robots (quadrapods or hexapods).
The servo controller receives position commands through a serial connection which can be provided by using one I/O pin of another microcontroller, or a PCs serial port! The communication protocol, that is used for this controller, is the same with the protocol of all the famous servo controllers of Scott Edwards Electronics Inc., this makes this new controller 100% compatible with all the programs that have been written for the "SSC" controllers...! However, if you want to write your own software, it is as easy as sending positioning data to the serial port as follows:
Byte1 = Sync (255)
Byte2 = Servo #(0-15)
Byte3 = Position (0-254)
So sending a 255,4,150 would move servo 4 to position 150, sending 255,12,35 would move servo 12 to position 35.
The standards of the serial communication should be the following: 9600 baud, 8 data bits, 1 stop bit and no parity.
1. Basic theory
1.1 Servo motors
Servo motors are geared dc motors with positional control feedback and are used for position control. The shaft of the motor can be positioned or rotated through 180 degrees. They are commonly used in the hobby R/C market for controlling model cars, airplanes, boats, and helicopters.


(Picture 1. A hobby servo motor)
Because of their widespread use in the hobby market, servo motors are available in a number of stock sizes. While larger industrial servos are also available, they are priced out of range for most hobby applications. This article is restricted to the hobby servo motors that are inexpensive and readily available.


(Picture 2. Internal view of a hobby servo motor : the gear box)
There are three leads to a servo. Two are for power, + 4 to 6 volts and ground. The third lead feeds a position control signal to the motor, and the control signal is a variable-width pulse. A neutral, midrange positional pulse is a 1.5-ms (millisecond) pulse, which is sent 50 times (20 ms) a second to the motor.


(Picture 3. Internal view of a hobby servo motor : the motor controller)
This pulse signal will cause the shaft to locate itself at the midway position +/-90 degrees. The shaft rotation on a servo motor is limited to approximately 180 degrees (+/-90 degrees from center position). A 1-ms pulse will rotate the shaft all the way to the left, while a 2-ms pulse will turn the shaft all the way to the right. By varying the pulse width between 1 and 2 ms, the servo motor shaft can be rotated to any degree position within its range.


(Figure 1. The servo motors pulse signal)
1.2 How to use servo motors to walk!
In general, legged locomotion systems are quite complicated. There are however, a few simple variations. An insectlike leg can be constructed using only two model hobby servos, as shown in Figure 2.




[ 本帖最後由 uucww 於 2006-8-9 11:23 編輯 ]
2#
 樓主| 發表於 2006-8-9 11:20:00 | 只看該作者
; *******************************************
; **                                       **
; **  16 Channel Serial Servo Controller   **
; **       For Robotic Applications        **
; **                                       **
; **    Microcontroller's Unit Software    **
; **                                       **
; **       Copyright (c) March 2000        **
; **          by George Vastianos          **
; **                                       **
; *******************************************

; *******************
; * Microcontroller *
; * characteristics *
; *******************

; MCU  = AT90S4414
; Fclk = 3.6864 MHz

.include "4414def.inc"

.cseg
.org        $0000                        ; * Reset handler
        rjmp        start                 
.org        $0009                        ; * UART RX Complete handler
        rjmp        uart_rxc       
.org        $000d                        ; * Main program start
       
;******************************
;* Interrupt Service Routines *
;******************************

.def        sregb        =        r16
.def        stemp        =        r17

uart_rxc:
        in        sregb,        SREG        ; * Store status register
        rjmp        rcvdchar                ; * Start the task
uart_rxcf:
        out        SREG,        sregb        ; * Restore status register
        ldi        stemp,        $90        ; * Enable UART Receiver & RX Complete Interrupt
        out        UCR,        stemp
        reti                        ; * Return to main program

;**************************
;* UART Reception Routine *
;**************************

.def        rxchar        =        r18

rcvdchar:                                ; * Store the received character
        in        rxchar,        udr       
        cpi        rxchar,        $ff        ; * Check if character is sync byte
        brne        rcvdchar1
        ldi        r30,        $60        ; * If character is sync byte then
        ldi        r31,        $00        ; * set Z register in the begin of packet area (in int. SRAM)
        rjmp        uart_rxcf
rcvdchar1:                                ; * If character is not sync byte then
        st        Z+,        rxchar        ; * increase Z and store in int. SRAM the character
        cpi        r30,        $62        ; * Check if packet finished
        brne        rcvdchar2
        ldi        r30,        $60
        rjmp        panalysis                ; * If packet finished go to analyze it
rcvdchar2:
        rjmp        uart_rxcf       

;********************************
;* Data Packet Analysis Routine *
;********************************

.equ        baddr        =        0        ; * Base address = 0 (in case of use up to 16 servos)

panalysis:
        lds        stemp,        $0060        ; * Check if the base address of packet is the same
        andi        stemp,        $F0
        cpi        stemp,        baddr * 10
        brne        panalysis1                ; * If its not the same then ignore the packet
        lds        stemp,        $0060        ; * If its the same then update the servo position data
        andi        stemp,        $0F
        ldi        r28,        $80       
        ldi        r29,        $00       
        add        r28,        stemp
        lds        stemp,        $0061               
        st        Y,        stemp
panalysis1:
        rjmp        uart_rxcf                ; * Analysis finished

;*************************************
;* End Of Interrupt Service Routines *
;*************************************

;****************
;* Main Program *
;****************

start:

;**************
;* Initiation *
;**************

.def        temp        =        r19

init:
        ldi        temp,        $01        ; * Set Stack pointer to $015F of internal SRAM
        out        SPH,        temp               
        ldi        temp,        $5F
        out        SPL,        temp
        ldi        temp,        $17        ; * Set UART on 9600 bps (for 115200 bps use $01)
        out        UBRR,        temp
        ldi        temp,        $90        ; * Enable UART Receiver & RX Complete Interrupt
        out        UCR,        temp
        ldi        temp,        $00
        out        WDTCR,        temp        ; * Watchdog Timer disable
        out         ACSR,        temp        ; * Analog Comparator disable
        sts        $0060,        temp        ; * Init pck byte 01
        sts        $0061,        temp        ; * Init pck byte 02
        ldi        temp,        $fe
        sts        $0080,        temp        ; * Init pos byte 01
        sts        $0081,        temp        ; * Init pos byte 02
        sts        $0082,        temp        ; * Init pos byte 03
        sts        $0083,        temp        ; * Init pos byte 04
        sts        $0084,        temp        ; * Init pos byte 05
        sts        $0085,        temp        ; * Init pos byte 06
        sts        $0086,        temp        ; * Init pos byte 07
        sts        $0087,        temp        ; * Init pos byte 08
        sts        $0088,        temp        ; * Init pos byte 09
        sts        $0089,        temp        ; * Init pos byte 10
        sts        $008A,        temp        ; * Init pos byte 11
        sts        $008B,        temp        ; * Init pos byte 12
        sts        $008C,        temp        ; * Init pos byte 13
        sts        $008D,        temp        ; * Init pos byte 14
        sts        $008E,        temp        ; * Init pos byte 15
        sts        $008F,        temp        ; * Init pos byte 16
        ldi        temp,        $ff        ; * Init all PWM outputs
        out        ddra,        temp
        out        ddrc,        temp
        ldi        temp,        $00        ; * Reset all PWM outputs
        out        porta,        temp
        out        portc,        temp
        sei                        ; * Global interrupt enable

mainloop:

;************************
;* PWM Control Routines *
;************************

.equ        servo0        =        PA0        ; * Set the output pin of Servo01
.equ        servo1        =        PA1        ; * Set the output pin of Servo02
.equ        servo2        =        PA2        ; * Set the output pin of Servo03
.equ        servo3        =        PA3        ; * Set the output pin of Servo04
.equ        servo4        =        PA4        ; * Set the output pin of Servo05
.equ        servo5        =        PA5        ; * Set the output pin of Servo06
.equ        servo6        =        PA6        ; * Set the output pin of Servo07
.equ        servo7        =        PA7        ; * Set the output pin of Servo08
.equ        servo8        =        PC7        ; * Set the output pin of Servo09
.equ        servo9        =        PC6        ; * Set the output pin of Servo10
.equ        servoA        =        PC5        ; * Set the output pin of Servo11
.equ        servoB        =        PC4        ; * Set the output pin of Servo12
.equ        servoC        =        PC3        ; * Set the output pin of Servo13
.equ        servoD        =        PC2        ; * Set the output pin of Servo14
.equ        servoE        =        PC1        ; * Set the output pin of Servo15
.equ        servoF        =        PC0        ; * Set the output pin of Servo16

.def        tsoutA        =        r20        ; * Temp servoA output pin register
.def        tsoutB        =        r21        ; * Temp servoB output pin register
.def        tsposA        =        r22        ; * Temp servoA position   register
.def        tsposB        =        r23        ; * Temp servoB position   register

pwmmark:       
        ldi        tsoutA,        exp2(servo0) ; * Control Servo0 & Servo1
        ldi        tsoutB,        exp2(servo1)
        lds        tsposA,        $0080
        lds        tsposB,        $0081
        rcall        pwmA
        ldi        tsoutA,        exp2(servo2) ; * Control Servo2 & Servo3
        ldi        tsoutB,        exp2(servo3)
        lds        tsposA,        $0082
        lds        tsposB,        $0083
        rcall        pwmA
        ldi        tsoutA,        exp2(servo4) ; * Control Servo4 & Servo5
        ldi        tsoutB,        exp2(servo5)
        lds        tsposA,        $0084
        lds        tsposB,        $0085
        rcall        pwmA
        ldi        tsoutA,        exp2(servo6) ; * Control Servo6 & Servo7
        ldi        tsoutB,        exp2(servo7)
        lds        tsposA,        $0086
        lds        tsposB,        $0087
        rcall        pwmA
        ldi        tsoutA,        exp2(servo8) ; * Control Servo8 & Servo9
        ldi        tsoutB,        exp2(servo9)
        lds        tsposA,        $0088
        lds        tsposB,        $0089
        rcall        pwmB
        ldi        tsoutA,        exp2(servoA) ; * Control ServoA & ServoB
        ldi        tsoutB,        exp2(servoB)
        lds        tsposA,        $008A
        lds        tsposB,        $008B
        rcall        pwmB
        ldi        tsoutA,        exp2(servoC) ; * Control ServoC & ServoD
        ldi        tsoutB,        exp2(servoD)
        lds        tsposA,        $008C
        lds        tsposB,        $008D
        rcall        pwmB
        ldi        tsoutA,        exp2(servoE) ; * Control ServoE & ServoF
        ldi        tsoutB,        exp2(servoF)
        lds        tsposA,        $008E
        lds        tsposB,        $008F
        rcall        pwmB
        rjmp        mainloopend

;********************
;* PWM Mark Routine *
;********************

.def        count        =        r24

; * PWM routine for Servos 01-08 *

pwmA:
        in        temp,        porta        ; * Set output pins of ServoA & Servo B
        or        temp,        tsoutA
        or        temp,        tsoutB
        out        porta,        temp
        rcall        delay                ; * Wait for 900uS
        ldi        count,        $00        ; * Start 1400uS delay
pwmA1:
        cp        count,        tsposA        ; * Reset output pin of ServoA if positionA = count
        brne        pwmA2
        in        temp,        porta
        com        tsoutA       
        and         temp,        tsoutA
        com        tsoutA       
        out        porta,        temp
pwmA2:
        cp        count,        tsposB        ; * Reset output pin of ServoB if positionB = count
        brne        pwmA3
        in        temp,        porta
        com        tsoutB       
        and         temp,        tsoutB
        com        tsoutB       
        out        porta,        temp
pwmA3:
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        inc        count
        cpi        count,        $ff        ; * Check if delay completed
        brne        pwmA1
        ret                        ; * Stop 1400uS delay

; * PWM routine for Servos 09-16 *

pwmB:
        in        temp,        portc        ; * Set output pins of ServoA & Servo B
        or        temp,        tsoutA
        or        temp,        tsoutB
        out        portc,        temp
        rcall        delay                ; * Wait for 900uS
        ldi        count,        $00        ; * Start 1400uS delay
pwmB1:
        cp        count,        tsposA        ; * Reset output pin of ServoA if positionA = count
        brne        pwmB2
        in        temp,        portc
        com        tsoutA       
        and         temp,        tsoutA
        com        tsoutA       
        out        portc,        temp
pwmB2:
        cp        count,        tsposB        ; * Reset output pin of ServoB if positionB = count
        brne        pwmB3
        in        temp,        portc
        com        tsoutB       
        and         temp,        tsoutB
        com        tsoutB       
        out        portc,        temp
pwmB3:
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        inc        count
        cpi        count,        $ff        ; * Check if delay completed
        brne        pwmB1
        ret                        ; * Stop 1400uS delay

;*****************
;* Delay Routine *
;*****************

delay:
        ldi        temp,        $DD        ; * Start of 900 uSec delay
delay1:
        nop
        nop       
        nop
        nop       
        nop
        nop
        nop       
        nop
        nop       
        nop
        nop       
        dec        temp
        cpi        temp,        $00
        brne        delay1       
        ret                        ; * End of 900 uSec delay

;*******************************
;* End Of PWM Control Routines *
;*******************************

mainloopend:
        rjmp        mainloop

;***********************
;* End Of Main Program *
;***********************
z
3#
發表於 2006-12-4 16:37:40 | 只看該作者

something wrong ?

原帖由 uucww 於 2006-8-9 11:16 發表
http://www.seattlerobotics.org/encoder/200106/16csscnt.htm
[img]http://www.seattlerobotics.org/encoder/200106/fig3.pdf[/img]   
Search WWW  Search seattlerobo ...



Hi, Dear dada uucww

Source from  http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=44467&highlight=  by ayu


I'm so happy to find the web and learn so funny to play robot with everybody.

This a asembly code to built a SSC(Serial servo contorller),

I had tried,but just only adjust 0 to 126 ,but 127to 255 can't apply pulses,

Now, hope to solved the  questions,

I tested for the assembly code on an AT90S8515 at 3.6864 MHz. The code was compiled with AVR Studio 4.12 SP3.

Run the Visual Basic program (EXE file) and move the Scroll Bar I get this pulse width:

Beginning,Pulse width = 2285 μs (2.285 ms) ,It's OK.

Press the cnter button(value 127): Pulse width = 1595 μs (1.595 ms),It's OK.  

but move button down to value 128 and down to value 254,the Pulse width = 0.905 ms and no change.  

Press the cnter button(value 127): Pulse width = 1595 μs (1.595 ms),
Move button up to value 126 and up to value 0, It worked fine . Thanks.

Best regards

[ 本帖最後由 z 於 2007-4-27 21:59 編輯 ]
4#
發表於 2006-12-4 19:06:00 | 只看該作者
以FPPA 多核心微控器來說:理論來說:

    兩顆核心微控器可以產生 9 Channel PWM 訊號。

    (因為第二顆微控器最大的PWM訊號為2.1 mSec, So, 2.1 x 9 = 18.9 mSec <20 mSec)

    同樣以FPP6 為同步信號,三顆核心微控器 可以產生 18 Channel !
   
    依此類推,四顆核心微控器 可以產生 27  Channel ,只要FPPA 的I/O pin 夠多就可以了!!

    然後還可以利用剩下的核心微控器當UART 或SPI/ I2C 等等....

    您覺得這樣子的想法簡不簡單?!

    http://chamberplus.myweb.hinet.net/fppa_sa4.htm
   

  

[ 本帖最後由 chamber 於 2006-12-4 19:14 編輯 ]
z
5#
發表於 2006-12-4 20:47:05 | 只看該作者
原帖由 chamber 於 2006-12-4 19:06 發表
以FPPA 多核心微控器來說:理論來說:

    兩顆核心微控器可以產生 9 Channel PWM 訊號。

    (因為第二顆微控器最大的PWM訊號為2.1 mSec, So, 2.1 x 9 = 18.9 mSec <20 mSec)

    同樣以FPP6 為同步信號 ...

Hi, chamber

Thank your suggestion,  and the problem is no sources in Taiwan to learn the  FPPA core,(ayu had the problem,too )sorry.

Because the AVR has many sources in forum by other countries,so we can learn easily.

Taiwan's technology is very smart but the popular  common sense is so absence,and can't popular to learn, that's what we learn
another core.

You're so kind and smart ,and thank your suggestion,hope we can learn the FPPA easily and popular in Taiwna.Thank you.

Best regards,
z.
6#
 樓主| 發表於 2006-12-13 20:47:22 | 只看該作者
恭喜了!!!
7#
發表於 2007-4-28 11:27:46 | 只看該作者

Chuck Baird 的vb程式

今天詢問Mr.Chuck Baird可否公開這個程式,原avr freaks下載點,好像不能下載,下面有下載點,如您有使用的話,麻煩您通知小弟一下,感激了喔。


vb程式下載點  http://www.badongo.com/file/2887054 下載後請把副檔名更換成exe,然後電腦需灌vb軟體才可使用這個程式。

[ 本帖最後由 ayu 於 2007-5-6 10:03 編輯 ]
8#
發表於 2007-4-28 16:40:10 | 只看該作者

AVR Studio 4.13 b528 操作

要用這個程式的話,請先下載atmel公司的分享程式才可編譯原作者的程式,

原網頁atmel公司的分享程式AVR Studio 4.13 b528 不用錢非常好用的編譯程式。

http://www.atmel.com/dyn/products/tools_card.asp?family_id=607&family_name=AVR+8%2DBit+RISC+&tool_id=2725



開啟程式後畫面先選圓圈部分



檔案路徑設定畫面



1、我們用組合語言所以選這項。
2、7項看您要放那個路徑。
4、5項請選起來比較方便,等一下會自動產生專案資料。
3項為專案名稱。
6項為檔名。

接著按finish即產生下面畫面



再來,我們把從下載來的原始程式MCU_SRC裏的16CSSCNT.ASM打開,把裏面的內容複製、貼上上圖的空白部份



因為用的是8515晶片所以要更換成8515,上面那一項可不用更換。


                                                             最後編譯程式:




出現如最下方的圓圈部份即可。




接著到您剛才指定的路徑即可找到燒錄檔8515.hex。



燒錄線製作和燒錄方法,請參閱 rushoun大大的網頁http://myweb.hinet.net/home17/rushoun/AVR/avr_isp.htm
rushoun大大也是我們的網友,他的pic燒錄器,如您有興趣的話,可跟他購買。

接下來把線路兜起來,您就可玩這個16ssc了喔。玩的狀況如何,請告知一下喔,如您發展出更好玩的設計,請不吝分享,謝謝各位大大了。

[ 本帖最後由 ayu 於 2007-4-28 20:30 編輯 ]
9#
發表於 2007-4-28 22:38:53 | 只看該作者
rushoun大大   是否是頗負盛名的白熊前輩?

感謝 ayu 前輩提供這麼棒的開發環境!  讚啦!
10#
發表於 2007-4-28 22:43:13 | 只看該作者
原帖由 pcedison 於 2007-4-28 22:38 發表
rushoun大大   是否是頗負盛名的白熊前輩?

pcedison大大您好喔,沒錯,就是白熊大大喔。
11#
發表於 2007-10-29 18:37:52 | 只看該作者
這程式可以用89C51去用嗎??
可以的話怎麼改?
8515跟4414接腳一樣嗎?
12#
發表於 2007-10-29 21:32:40 | 只看該作者
s610179123大您好,

      這程式可以用89C51去用嗎?? 沒有辦法地   

可以的話怎麼改? 無法吧??編譯器不同,語言也不同。還是有高明的大大可用呢??請示教囉。

8515跟4414接腳一樣嗎?     好像一樣,可上官網查datasheet囉。
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

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

GMT+8, 2024-11-23 23:51 , Processed in 0.163715 second(s), 7 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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