jake2006的个人空间 https://blog.eetop.cn/43359 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

FPGA开发

已有 706 次阅读| 2006-8-16 17:21

天气: 晴朗
心情: 高兴
FPGAs are suitable to control R/C Servos ("remote control servo motors"). (转)

What are they?

An R/C servo consists of a motor and set of gears enclosed into a small box.
A single axis comes out of the servo. You control precisely the angle of rotation of the axis using PWM pulses.

Here's a picture of one servo (old and bitten up, but illustrates our purpose).


Useful informational links include:

Where are they used?

  • In remote controlled models (cars, airplanes...).
  • In robotics.

Servo connection

Servos have 3 wires:
  • Red: power supply (+5V).
  • Black: ground.
  • White: rotation control (PWM).

PWM pulses

The control pulse length needs to be anywhere from 1ms to 2ms.
A pulse of 1.5ms rotates the axis in the middle of its rotation range.

A new pulse needs to be sent regularly (every 10 to 20ms), even if the angular position doesn't need to be changed, or the servo will stop trying to hold it.

PWM pulses from an FPGA

Let's control a servo with an 8 bits resolutions (256 steps, from 0 to 255). That means that we need to generate a pulse from 1ms (0) to 2ms (255), with a resolution of 1ms/256=3.9µs.
Dividing the clock
Using a 25MHz clock (40ns period), the first step is to divide the clock to generate a "tick" of period as close as possible to 3.9µs.

parameter ClkDiv = 98;    // 25000000/1000/256 = 97.56

reg [6:0] ClkCount;
reg ClkTick;
always @(posedge clk) ClkTick <= (ClkCount==ClkDiv-2);
always @(posedge clk) if(ClkTick) ClkCount <= 0; else ClkCount <= ClkCount + 1;

Using the "ClkTick", we instantiate a 12-bits counter that increments at every tick.

reg [11:0] PulseCount;
always @(posedge clk) if(ClkTick) PulseCount <= PulseCount + 1;

Each tick lasts 3.9µs, so 256 ticks lasts 1ms, and the 12 bits counter "PulseCount" rolls-over every 16ms. Just what we need to generate a new pulse regularly.
Generating the PWM pulse
We start each pulse when "PulseCount" equals 0.
We end each pulse when "PulseCount" is somewhere between 256 and 511. That generates the pulse between 1ms and 2ms.

Assuming that "RCServo_position" is the 8 bits position value (from 0 to 255), we concatenate a "0001" in front of it to create a 12 bits value ranging from 256 ot 511. Finally, we compare these 12 bits to "PulseCount" to generate the pulse.

reg RCServo_pulse;
always @(posedge clk) RCServo_pulse = (PulseCount < {4'b0001, RCServo_position});

That's all folks! The complete code can be found here.
As you can see, it takes very little hardware to control an R/C servo, so an FPGA could control multiple of them simultaneously.

Your turn to experiment!

点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 0

    评论
  • 访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-26 12:55 , Processed in 0.039435 second(s), 17 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部