博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[AVR]使用AVR单片机驱动舵机
阅读量:6503 次
发布时间:2019-06-24

本文共 2268 字,大约阅读时间需要 7 分钟。

最近参加了三系举办的小车比赛(好像叫什么"驭远杯")。领导要求我驱动3-4个舵机。研究了几日,总算折腾出一个方案..、


1.舵机驱动的基本原理

  (可以参考)

  "控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。"

简单的来讲,就是输出一个周期为20Ms,不同的占空比对应舵机转过不同的角度。

难点主要在于

  • 舵机控制信号需要保持,这样就比用脉冲控制步进电机要复杂一些。
  • 你需要保持多路PWM,并且要随时调节占空比来获得要求的角度

2.实现思路

网上有用工作在相频修正PWM模式下的T1来产生信号,这样虽然十分精确,然而并不太好实现多路控制.(至少我是没想出来,如果有高手知道怎么做,还望多多指教)

我决定采用以下方法:

  • 将 20ms 等分成240份,这样一份是20000/240 us //分成240份的原因是这样可以算出整数值得TCNT1
  • 将T1配置为溢出中断模式,每20000/240 us溢出一次
  • 中断服务程序更新TCNT1的值,维护一组变量,产生信号。

这样做的优点是方便了多路控制。虽然我只控制了四路舵机,稍加修改就可以控制更多..

然而中断服务程序中维护变量时,产生的微小误差会累加,这样不可避免的会产生较大误差。直接采用计算值肯定不行,最后需要修正。

3.代码

代码还是相当的不成熟...愿各位高手多多指教.

通过传入一个指针给Servo_AngelPWM实现四个舵机的角度控制

#include 
#include
#ifndef SERVO_CONTROL_H#define SERVO_CONTROL_H#define Servo1 PB7#define Servo1_1 PORTB|=_BV(Servo1)#define Servo1_0 PORTB&=~_BV(Servo1)#define Servo2 PB6#define Servo2_1 PORTB|=_BV(Servo2)#define Servo2_0 PORTB&=~_BV(Servo2)#define Servo3 PB5#define Servo3_1 PORTB|=_BV(Servo2)#define Servo3_0 PORTB&=~_BV(Servo2)#define Servo4 PB4#define Servo4_1 PORTB|=_BV(Servo2)#define Servo4_0 PORTB&=~_BV(Servo2)#define to_us(x) (((x/180.0)*2.0+0.5)*1000)uint32_t Servo_Flag[4];uint32_t Servo_Cflag=0;void Servo_AngelPWM(char *angel){ for(int i=0;i<4;i++) Servo_Flag[i]=to_us(angel[i])*3/250; TIMSK|=_BV(TOIE1);//开启TC1中断 }ISR(TIMER1_OVF_vect){ TIMSK&=~_BV(TOIE1);//关闭TC1中断 //1 TCNT1=64525;//65535-(1000+10)这个10加的有讲究 //3 Servo_Cflag++; //4 if(Servo_Cflag>=239) //5 { Servo1_1; Servo2_1; Servo3_1; Servo4_1; Servo_Cflag=0; } else if(Servo_Flag[0]==Servo_Cflag)Servo1_0; //6 else if(Servo_Flag[1]==Servo_Cflag)Servo2_0; //7 else if(Servo_Flag[2]==Servo_Cflag)Servo3_0; //8 else if(Servo_Flag[3]==Servo_Cflag)Servo4_0; //9 TIMSK|=_BV(TOIE1);//开启TC1中断 //10}#endif

4.后记

给TCNT1赋计算值,也就是65535-1000=64525时,产生的信号大约是47HZ。如我所料,准确性比较差。

然后尝试根据分析语句来修正TCNT1的初值,可以从我的注释看出...修正完后大约是48hz,还是不太准。

最后直接上示波器微调了...当TCNT1为64569(修正值34)时,如上图,产生了比较准确的驱动信号(45度和90度)。

(所以说学会汇编还是很重要的...有时间一定要研究研究)

 

转载于:https://www.cnblogs.com/cn-lhc/p/5997855.html

你可能感兴趣的文章
中断小笔记
查看>>
C#委托、事件、消息(入门级)
查看>>
python设置windows桌面壁纸
查看>>
Visual Studio 11 Beta新特性(一):安装VS11
查看>>
通信常用概念
查看>>
PreferenceFragment 使用 小结
查看>>
FreeBinary 格式说明
查看>>
oracle相关链接
查看>>
有关奇葩的mex编程时的matlab出现栈内存错误的问题
查看>>
使用Spring Cloud和Docker构建微服务
查看>>
常用链接
查看>>
NB-IoT的成功商用不是一蹴而就
查看>>
九州云实战人员为您揭秘成功部署OpenStack几大要点
查看>>
1.电子商务支付方式有哪些 2.比较不同支付方式的优势劣势
查看>>
医疗卫生系统被爆漏洞,7亿公民信息泄露……
查看>>
神秘函件引发的4G+与全网通的较量
查看>>
CloudCC:智能CRM究竟能否成为下一个行业风口?
查看>>
高德开放平台推出LBS游戏行业解决方案提供专业地图平台能力支持
查看>>
追求绿色数据中心
查看>>
Web开发初学指南
查看>>