佳礼资讯网

 找回密码
 注册

ADVERTISEMENT

查看: 4812|回复: 32

servo programing

[复制链接]
发表于 4-5-2008 01:14 PM | 显示全部楼层 |阅读模式
版主好,小弟又有一些问题关于servo的program。
我找到了一个简单的program但是不明白为何如此写法。。。
希望版可以帮帮忙,谢谢!

Counter         EQU     0Ch             ;Servo delay counter register

Position        EQU     0Dh             ;Servo Position register



Servo1          EQU     RB.0            ;Servo I/O port pin



Main            .

                .

Servo           MOVLW   248             ;Load Counter with # of cycles for

                MOVWF   Counter         ;1 ms Servo Delay

                BSF     Servo1          ;Activate the Servo1 output

                CALL    Delay           ;Wait for 1ms to pass

                MOVF    Position,0      ;Load W with servo position

                                        ;00 & FF=extremes, 128=centre

                MOVWF   Counter         ;and store in Counter for next delay

                CALL    Delay           ;Keep servo active for position delay

                BCF     Servo1          ;Deactivate the Servo1 output

                .

                .                       ;Do other processing here, but

                                        ;remember to update each servo

                                        ;approximately once every 20 ms



Delay           ;Servo time delay

                NOP                     ad the loop with one cycle

                DECFSZ  Counter         ;Counter=Counter-1

                GOTO    Delay           ;If Counter is not 0, repeat

                RETURN                  ;If 0, return
回复

使用道具 举报


ADVERTISEMENT

发表于 4-5-2008 05:37 PM | 显示全部楼层
我不懂要怎样解释。不过大概大概。

servo motor用pwm来控制position.
0-9ms-2.1ms有些是1.0ms-2.0ms.

http://mcu-programming.blogspot.com/2006/09/servo-motor-control.html

这个program一开始delay 1 ms (counter).
过后再delay 0-1ms(position).看你要servo 去那里。
过后等到20ms.在从新execute 过。

这个program是用instructrion execution time 来generate pulse.可以很准, 不过不flexible. crystal frequency改, mcu不一样都可能用不到了。
回复

使用道具 举报

 楼主| 发表于 4-5-2008 07:52 PM | 显示全部楼层
如果我用bsf, call delay 1.5ms, 然后bcf可以吗?
回复

使用道具 举报

发表于 5-5-2008 12:58 AM | 显示全部楼层
原帖由 dns 于 4-5-2008 07:52 PM 发表
如果我用bsf, call delay 1.5ms, 然后bcf可以吗?

也是可以。不过在你给的program. 255最多可以去到delay 1ms而已。
回复

使用道具 举报

 楼主| 发表于 5-5-2008 01:34 AM | 显示全部楼层
我想要控制servo可以向左向右甚至可以停着,
应该要怎么写呢?我用的是asm
谢谢版主!
回复

使用道具 举报

发表于 5-5-2008 08:58 AM | 显示全部楼层
原帖由 dns 于 5-5-2008 01:34 AM 发表
我想要控制servo可以向左向右甚至可以停着,
应该要怎么写呢?我用的是asm
谢谢版主!

请问你用什么MCU?
你要控制一粒Servo motor 而已?
如是一个, 用内建的HW PWM是最简单的做法。
回复

使用道具 举报

Follow Us
 楼主| 发表于 5-5-2008 10:25 PM | 显示全部楼层
我用的是16F877A, 打算用来控制6~9个SERVO.
回复

使用道具 举报

发表于 6-5-2008 12:44 AM | 显示全部楼层
原帖由 dns 于 5-5-2008 10:25 PM 发表
我用的是16F877A, 打算用来控制6~9个SERVO.


6-9 个servo的话,你这个program不能用。
浪费时间。不precise.用timer generate吧。不过microcontroller的limitation,resolution可能去不到很高。
你的resolution要多高?
回复

使用道具 举报


ADVERTISEMENT

 楼主| 发表于 6-5-2008 11:18 AM | 显示全部楼层
不好意思小弟只是个初学者,很多东西都不懂。
什么是resolution?
我的servo不用很precise,可以转动就行了。
回复

使用道具 举报

发表于 6-5-2008 02:18 PM | 显示全部楼层
resolution ahh...
16F877A 好像是 10个 bit 的啊。。
回复

使用道具 举报

发表于 6-5-2008 03:15 PM | 显示全部楼层
原帖由 dns 于 6-5-2008 11:18 AM 发表
不好意思小弟只是个初学者,很多东西都不懂。
什么是resolution?
我的servo不用很precise,可以转动就行了。

6~9个SERVO, 一开始就应该说明。

还是先问清楚先。。。请问, 你的servo motor
1. 长什么样子?请放照片。
2. 做什么用途?
3. 为什么要6~9个?

先理解了才给解答吧。。。
回复

使用道具 举报

 楼主| 发表于 7-5-2008 01:39 PM | 显示全部楼层

我要用SERVO来做ROBOT ARM.这是我要用的SERVO。
ROBOTARM 要有一共要有3个手指。
一个手指要有2~3个SERVO来做关节。
回复

使用道具 举报

发表于 7-5-2008 04:44 PM | 显示全部楼层
原帖由 dns 于 7-5-2008 01:39 PM 发表
我要用SERVO来做ROBOT ARM.这是我要用的SERVO。
ROBOTARM 要有一共要有3个手指。
一个手指要有2~3个SERVO来做关节。

你可以做Software PWM, 6-9 个 low Freq 的Soft PWM, 不会有问题。
回复

使用道具 举报

 楼主| 发表于 8-5-2008 11:12 PM | 显示全部楼层
原来如此,酱software应该要如何写呢?
我的robot arm要接去一个手套,
当我们将手指弯曲时,robot arm也要跟着做。
这一点有点困扰,因为我不懂program的flowing应该怎么写,
希望版主们可以帮帮忙,谢谢!!
回复

使用道具 举报

发表于 9-5-2008 10:11 AM | 显示全部楼层
原帖由 dns 于 8-5-2008 11:12 PM 发表
原来如此,酱software应该要如何写呢?
我的robot arm要接去一个手套,
当我们将手指弯曲时,robot arm也要跟着做。
这一点有点困扰,因为我不懂program的flowing应该怎么写,
希望版主们可以帮帮忙,谢谢!!

下面我用CCS C 写了简单的8ch Soft PWM,  resolution 是8bit, duty cycle (0-255)
频率可以通过preload 来改变, 输出是PortD。

  PWMx_duty = (0-255),  改变PWM 的Duty Cycle。

其他的你自己写了。。。不明白再问。
  1. ////////////////////////////
  2. // Software PWM (8Ch)
  3. // PWM Output at port D0~D7
  4. // By pic@cArI
  5. // Date: 9 May 2008
  6. ////////////////////////////

  7. #include <16F877A.h>
  8. #fuses HS,NOPROTECT,NOWDT,PUT
  9. #use delay(clock=20000000)

  10. #use Fast_io(D)
  11. #byte port_d=0x08


  12. //PWM Freq can be change here
  13. #define preload 65180


  14. #bit oPWM1 = port_d.0
  15. #bit oPWM2 = port_d.1
  16. #bit oPWM3 = port_d.2
  17. #bit oPWM4 = port_d.3
  18. #bit oPWM5 = port_d.4
  19. #bit oPWM6 = port_d.5
  20. #bit oPWM7 = port_d.6
  21. #bit oPWM8 = port_d.7


  22. ///////////////////////
  23. int PWM1_duty;
  24. int PWM2_duty;
  25. int PWM3_duty;
  26. int PWM4_duty;
  27. int PWM5_duty;
  28. int PWM6_duty;
  29. int PWM7_duty;
  30. int PWM8_duty;

  31. int intCnt;

  32. ////////////////////////////////////////////////
  33. //approx 20ms per cycle, preload=61650
  34. //////////////////////////////////////////////
  35. #INT_TIMER1
  36. void timer_irq()
  37. {
  38.     set_timer1(preload);
  39.    if (intCnt < 255)
  40.     {
  41.       if (intCnt == PWM1_duty)
  42.        {
  43.          oPWM1=0;
  44.        }   
  45.       if (intCnt == PWM2_duty)
  46.        {
  47.          oPWM2=0;
  48.        }   
  49.       if (intCnt == PWM3_duty)
  50.        {
  51.          oPWM3=0;
  52.        }   
  53.       if (intCnt == PWM4_duty)
  54.        {
  55.          oPWM4=0;
  56.        }   
  57.       if (intCnt == PWM5_duty)
  58.        {
  59.          oPWM5=0;
  60.        }   
  61.       if (intCnt == PWM6_duty)
  62.        {
  63.          oPWM6=0;
  64.        }   
  65.       if (intCnt == PWM7_duty)
  66.        {
  67.          oPWM7=0;
  68.        }   
  69.       if (intCnt == PWM8_duty)
  70.        {
  71.          oPWM8=0;
  72.        }   
  73.     }
  74.    
  75.    else if(intCnt == 255)
  76.     {
  77.       intCnt = 0;
  78.       Port_D=255; // All PWM1 ~8 = High
  79.     }   
  80.     intCnt++;
  81. }



  82. void main()
  83. {

  84.    set_tris_D(0b00000000);
  85.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  86.    enable_interrupts(INT_TIMER1);
  87.    enable_interrupts(GLOBAL);


  88.    // Set your Duty cycle here (0-255)
  89.    PWM1_duty = 128;
  90.    PWM2_duty = 63;
  91.    PWM3_duty = 32;
  92.    PWM4_duty = 16;
  93.    PWM5_duty = 128;
  94.    PWM6_duty = 63;
  95.    PWM7_duty = 32;
  96.    PWM8_duty = 16;

  97.    intCnt = 0;

  98.    While(True)
  99.    {
  100.    
  101.    }
  102. }
复制代码

[ 本帖最后由 pic 于 9-5-2008 10:54 PM 编辑 ]
回复

使用道具 举报

 楼主| 发表于 9-5-2008 12:07 PM | 显示全部楼层
不好意思版主,我不会用c-language,请问有asm吗?
回复

使用道具 举报


ADVERTISEMENT

发表于 9-5-2008 05:21 PM | 显示全部楼层
原帖由 dns 于 9-5-2008 12:07 PM 发表
不好意思版主,我不会用c-language,请问有asm吗?

对不起, 我不用ASM。 (用ASM 我会找不到吃, 我是指我自己, 不包括其他人。)
回复

使用道具 举报

发表于 9-5-2008 11:39 PM | 显示全部楼层
原帖由 dns 于 9-5-2008 12:07 PM 发表
不好意思版主,我不会用c-language,请问有asm吗?


老实说, 我觉得用16f877a generate 9 channel pwm给servo motor很难。用pic斑竹的方式, 20mhz crystal 的pic.
每392 machine cycle就要interrupt一次。
resolution = 8 bits, 255 steps.
不过servo motor的pwm range是0.9ms-2.1ms/20ms. 8 bits的resolution只能给那个servo motor大概(2.1-0.9)/20 *255 = 16个steps.
你首先要confirm每一次interrupt,你的irq 不能太久,一定要在392 machine cycles里面搞定全部irq function.
接下来, 你还有其他的任务。 相信你的mcu不只是拿来做pwm 吧。

终结来讲, 这个program可能不简单写。还用asm来写, 会吐。
我建议用两个mcu.一个专门拿来generate pwm.另一个做processing其他的东西。
可以用usart, i2c来link 这两个mcu.
回复

使用道具 举报

发表于 10-5-2008 07:14 AM | 显示全部楼层
原帖由 fritlizt 于 9-5-2008 11:39 PM 发表
老实说, 我觉得用16f877a generate 9 channel pwm给servo motor很难。用pic斑竹的方式, 20mhz crystal 的pic.
每392 machine cycle就要interrupt一次。 resolution = 8 bits, 255 steps.
不过servo motor的pwm range是0.9ms-2.1ms/20ms. 8 bits的resolution只能给那个servo motor大概(2.1-0.9)/20 *255 = 16个steps.
你首先要confirm每一次interrupt,你的irq 不能太久,一定要在392 machine cycles里面搞定全部irq function.
接下来, 你还有其他的任务。 相信你的mcu不只是拿来做pwm 吧。

首先, 我不曾玩过或做过Servo motor的project, 我上面的源码, 只是示范如何做简单的Soft PWM,
(它并不是我特意设计来给Servo 用, 它是我以前做DMX灯光控制时而做的。)

我的源码里的resolution 是8bit, 其实可以改成4bit (16Step), 5bit (32step), 6bit (64Step), 来争取更多的MCU time。
要用20MHZ的PIC16来做, 不是不可能, 可以做0~2ms 的PWM(Full time), 过后的18ms 释放给其他的Task用
也可以考虑用PIC18F, 40Mhz。


我建议用两个mcu.一个专门拿来generate pwm.另一个做processing其他的东西。
可以用usart, i2c来link 这两个mcu.

我非常赞同用双MCU来实现. (我有一款的DMX灯光控制也是用双MCU)
回复

使用道具 举报

 楼主| 发表于 10-5-2008 02:17 PM | 显示全部楼层
酱如果我把servo的数量减少到6个
program会不会简单一点呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

 

ADVERTISEMENT



ADVERTISEMENT



ADVERTISEMENT

ADVERTISEMENT


版权所有 © 1996-2023 Cari Internet Sdn Bhd (483575-W)|IPSERVERONE 提供云主机|广告刊登|关于我们|私隐权|免控|投诉|联络|脸书|佳礼资讯网

GMT+8, 25-4-2024 05:04 PM , Processed in 0.076984 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表