找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10606|回复: 16
收起左侧

51单片机舵机控制原理+程序(单个和多个的舵机控制都有)

  [复制链接]
ID:639290 发表于 2020-4-13 09:27 | 显示全部楼层 |阅读模式
因我体会过学习舵机过程中寻找资料的苦恼,现将我学习过的资料和大家分享。希望大家能快乐的学习舵机

单片机源程序如下:
  1. /*****************************************************************************
  2. ** 文件                        : main.c
  3. ** 作者                        : Zheng23
  4. ** 日期                        :                        
  5. ** 功能                        :
  6. /*****************************************************************************/
  7. //#include <STC15.h>
  8. //#include"STC89C5xRC.H"


  9. //一定要用12M的晶振
  10. //一定要用12M的晶振
  11. //一定要用12M的晶振
  12. //一定要用12M的晶振
  13. //一定要用12M的晶振
  14. //一定要用12M的晶振

  15. #include "reg51.h"

  16. #define uint8        unsigned char    //无符号字符型
  17. #define uint16        unsigned short int
  18. #define uint32        unsigned long

  19. sbit SERVO0=P0^0;                        //控制舵机的PWM输出口

  20. uint16 Servo0PwmDuty=1500;        //PWM脉冲宽度   1.5ms脉冲宽度

  21. /***********************************************************
  22. * 名    称: DelayMs(uint16 ms)
  23. * 功    能: 延时ms毫秒
  24. * 入口参数: ms        毫秒
  25. * 出口参数: 无
  26. * 说    明:                                          
  27. /**********************************************************/
  28. void DelayMs(uint16 ms)
  29. {
  30.         uint16 i,j;
  31.         for(i=0;i<85;i++)                //89单片机用85,12系列单片机用800
  32.                 for(j=0;j<ms;j++);
  33. }
  34. /***********************************************************
  35. * 名    称:InitTimer0()
  36. * 功    能:时钟0初始化
  37. * 入口参数:无
  38. * 出口参数:无
  39. * 说    明:12M晶振,12分频,所以计数器每递增一个数就是1微秒,完全满足舵机控制的精度要求
  40.                         因为定时器是TH0,TL0都要全部计数到0xFF后在计1个数就会产生中断,所以要想产生
  41.                         x毫秒的中断,那么TH0,TL0就应该赋值(0xFFFF-x)        从这个值开始计数产生定时中断                                         
  42. /**********************************************************/
  43. void InitTimer0(void)
  44. {
  45.         TMOD &= 0xF0;                //设置定时器模式
  46.         TMOD |= 0x01;                //设置定时器模式
  47.         TL0 = 0x00;                        //设置定时初值
  48.         TH0 = 0x00;                        //设置定时初值
  49.         TF0 = 0;                        //清除TF0标志
  50.         TR0 = 1;                        //定时器0开始计时
  51.         ET0 = 1;                        //开定时器0中断
  52. }
  53. /***********************************************************
  54. * 名    称:Timer0Value(uint16 pwm)  
  55. * 功    能:给定时器0计数器赋值产生定时中断
  56. * 入口参数:pwm                控制舵机的PWM脉冲宽度值(范围:500~2500)
  57. * 出口参数:无
  58. * 说    明:12M晶振,12分频,所以计数器每递增一个数就是1微秒,完全满足舵机控制的精度要求
  59.                         因为定时器是TH0,TL0都要全部计数到0xFF后在计1个数就会产生中断,所以要想产生
  60.                         pwm毫秒的中断,那么TH0,TL0就应该赋值(0xFFFF-pwm)        从这个值开始计数产生定时中断                                          
  61. /**********************************************************/
  62. void Timer0Value(uint16 pwm)
  63. {
  64.         uint16 value;
  65.         value=0xffff-pwm;       
  66.         TR0 = 0;
  67.         TL0=value;                        //16位数据给8位数据赋值默认将16位数据的低八位直接赋给八位数据
  68.     TH0=value>>8;                //将16位数据右移8位,也就是将高8位移到低八位,再赋值给8位数据       
  69.         TR0 = 1;
  70. }
  71. /***********************************************************
  72. * 名    称: main()
  73. * 功    能: 入口函数
  74. * 入口参数: 无
  75. * 出口参数: 无
  76. * 说    明:                                          
  77. /**********************************************************/
  78. void main(void)
  79. {

  80.         InitTimer0();        //定时器0初始化
  81.         EA = 1;                        //开总中断
  82.         while(1)                //大循环
  83.         {       
  84.                 Servo0PwmDuty = 500;                //脉冲宽度在500微秒,对应-90°
  85.                 DelayMs(1000);                //延时1秒
  86.                 Servo0PwmDuty = 1000;        //脉冲宽度在1000微秒,对应-45°
  87.                 DelayMs(1000);
  88.                 Servo0PwmDuty = 1500;
  89.                 DelayMs(1000);
  90.                 Servo0PwmDuty = 2000;
  91.                 DelayMs(1000);
  92.                 Servo0PwmDuty = 2500;
  93.                 DelayMs(1000);
  94.                 Servo0PwmDuty = 2000;
  95.                 DelayMs(1000);
  96.                 Servo0PwmDuty = 1500;
  97.                 DelayMs(1000);
  98.                 Servo0PwmDuty = 1000;
  99.                 DelayMs(1000);
  100.         }
  101. }

  102. /***********************************************************
  103. * 名    称: Timer0_isr() interrupt 1 using 1
  104. * 功    能: 时钟0中断处理
  105. * 入口参数: 无
  106. * 出口参数: 无
  107. * 说    明:                                          
  108. /**********************************************************/
  109. void Timer0_isr(void) interrupt 1 using 1
  110. {
  111.         static uint16 i = 1;        //静态变量:每次调用函数时保持上一次所赋的值,
  112.                                                         //跟全局变量类似,不同是它只能用于此函数内部
  113.         switch(i)
  114.         {
  115.                 case 1:
  116.                         SERVO0 = 1;        //PWM控制脚高电平
  117.                         //给定时器0赋值,计数Pwm0Duty个脉冲后产生中断,下次中断会进入下一个case语句
  118.                         Timer0Value(Servo0PwmDuty);       
  119.                         break;
  120.                 case 2:
  121.                         SERVO0 = 0;        //PWM控制脚低电平
  122.                         //高脉冲结束后剩下的时间(20000-Pwm0Duty)全是低电平了,Pwm0Duty + (20000-Pwm0Duty) = 20000个脉冲正好为一个周期20毫秒
  123.                         Timer0Value(20000-Servo0PwmDuty);
  124.                         i = 0;       
  125.                         break;         
  126.         }
  127.         i++;
  128. }
复制代码

所有资料51hei提供下载:
单个舵机控制.zip (68.73 KB, 下载次数: 365)

评分

参与人数 2黑币 +54 收起 理由
gqzjl + 4 感谢楼主分享!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:730552 发表于 2020-5-5 19:07 | 显示全部楼层
如果加8个按键分别控制八个舵机该怎么控制,小白一个,试着写了一天了没成功,哭了
回复

使用道具 举报

ID:730552 发表于 2020-5-5 19:09 | 显示全部楼层
如果加八个按键分别控制八个舵机,程序该怎么写,小白一个,试了一天没成功,哭了
回复

使用道具 举报

ID:639290 发表于 2020-5-6 09:37 | 显示全部楼层
更都赤那 发表于 2020-5-5 19:09
如果加八个按键分别控制八个舵机,程序该怎么写,小白一个,试了一天没成功,哭了

按键输入pwm输出呀  如果检测到按键变化PWM随之响应
回复

使用道具 举报

ID:730552 发表于 2020-5-6 11:39 | 显示全部楼层
你消失的踪迹 发表于 2020-5-6 09:37
按键输入pwm输出呀  如果检测到按键变化PWM随之响应

楼主可以分享一个按键控制多路舵机的程序案例吗万分感谢,我只能做到按键控制单个舵机,但我现在做的按键分别控制6路舵机一直出错
回复

使用道具 举报

ID:639290 发表于 2020-5-6 13:27 | 显示全部楼层
更都赤那 发表于 2020-5-6 11:39
楼主可以分享一个按键控制多路舵机的程序案例吗万分感谢,我只能做到按键控制单个舵机,但我现在做 ...

抱歉按键控制舵机这块我也没有做过
回复

使用道具 举报

ID:495574 发表于 2020-8-6 16:20 来自手机 | 显示全部楼层
有一度一度的那种么
回复

使用道具 举报

ID:168971 发表于 2020-8-9 12:31 | 显示全部楼层
感谢楼主共享资料
回复

使用道具 举报

ID:815493 发表于 2020-9-23 10:00 来自手机 | 显示全部楼层
有没有用定时器的
回复

使用道具 举报

ID:833307 发表于 2020-11-3 05:02 | 显示全部楼层
我也没做成功,郁闷
回复

使用道具 举报

ID:700054 发表于 2021-5-8 17:10 | 显示全部楼层
好聪明的写法,博主厉害
回复

使用道具 举报

ID:204870 发表于 2021-5-8 18:23 | 显示全部楼层

我也没做成功,郁闷
回复

使用道具 举报

ID:918467 发表于 2021-5-15 14:52 | 显示全部楼层
请问博主有仿真图吗
回复

使用道具 举报

ID:969161 发表于 2021-11-10 14:36 | 显示全部楼层
这个不错,正要做舵机控制。
回复

使用道具 举报

ID:399179 发表于 2021-12-8 19:01 来自手机 | 显示全部楼层
正在学习舵机,感谢楼主分享!
回复

使用道具 举报

ID:1051684 发表于 2023-8-2 21:48 | 显示全部楼层
如此小的文件何必分成三个包,你也麻烦大家也麻烦
回复

使用道具 举报

ID:1109327 发表于 2024-1-21 21:01 | 显示全部楼层
这个不错,正要做舵机控制,请问博主有仿真图吗
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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