不久前作了个机械手。。用了四一个舵机。。
下面贴出一个舵机 的控制程序 。。多路。只需要在 中断程序中加代码就行
//头文件
#include <ioM16v.h>
#include <macros.h>
/*------宏定义------*/
#define uchar unsigned char
#define uint unsigned int
uint pwm1,pwm2,pwm3,pwm4,base;
//端口初始化
void port_init(void)
{
PORTA = 0xF0;
DDRA = 0xF0;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
//定时器T2初始化
void timer2_init(void)
{
TCCR2 = 0x00;//停止定时器
ASSR = 0x00;//异步时钟模式
TCNT2 = 0xE2;//初始值
OCR2 = 0xE1;//匹配值
TIMSK |= 0x40;//中断允许
TCCR2 = 0x02;//启动定时器
}
//T2溢出中断服务程序
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
TCNT2 = 0xE2;
base++;
if((base*20)<pwm1)
PORTA|=BIT(4);
else PORTA&=~BIT(4);
if(base==1000)
{
base=0;
PORTA|=BIT(4);
}
}
void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
port_init();
timer2_init();
SEI();//开全局中断
}
//主函数
void main(void)
{
init_devices();
pwm1=1500;
while(1)
{
NOP();
}
}
在论坛上看见了有用这单片机作舵机控制的,下载下来,一看,头就晕了,(可能是小弟的水平太次了吧),所以,自己新潮来血,也作了这么一个舵机控制的,用的是PWM,自我感觉,代码简单,修改方便,可移植性也比较高。
大概说明一下原理,我也是听我同事说得,舵机的脉宽值是500us到2500us,所以在产生脉宽的时候,周期至少要在400Hz以下。
如果产生PWM时,你的分频数为1时(不分频),那么产生的方波是4000Hz的,你要2500us的方波肯定是没戏了,至于500us的,我也忘了自己试没试,
分频数为8时,那么产生的方波是500Hz的,你要2500us的方波肯定也是没戏了,
所以,我用了64分频的方式,因此,TCCR1B=0x03;
用示波器看的,当OCR1AL=0x20时,脉宽为500us,当OCR1AL=0xa0时脉宽2500us。这个值也是大概比较准确的,OCR1AL的值差那么一点点也不怎么看的出来,所以,我就用了这么两个整数值。
单片机用的是M16,8M内部晶振,没有用到外部资源,使用的是PD5的第二功能,脉宽调制, 所以,也没有什么原理图可以画了。
下面与大家一起分享:
#include <iom16v.h>
#include <macros.h>
void delay_MS(unsigned int i)
{unsigned int j;
for (;i!=0;i--)
{
for (j=500;j!=0;j--)
;
}
}
void main()
{
unsigned int i=0x20;
DDRD|=BIT(PD5); //设置输出,OC1A
TCCR1A=0x83; //10位快速PWM,且OC1A输出反向
TCCR1B=0x03; //设置10位快速PWM,且64分频
while(1)
{
while(160-i) //脉宽从500uS往上加 注释(1)
{
OCR1AH=0;
OCR1AL=i;
delay_MS(50);
i++;
}
while(i-32) //脉宽从2500uS往下减 注释(2)
{
OCR1AH=0;
OCR1AL=i;
delay_MS(50);
i--;
}
}
}
/*************************************************************
注释(1):160的由来,此设置要产生2500ms的脉宽,OCR1AL=0xa0,OCR1AH=0x00;
a0换算成10进制,得160
(2):32的由来,此设置要产生500ms的脉宽,OCR1AL=0xa20,OCR1AH=0x00;
20换算成10进制,得32
OCR1AL=0x20; 脉宽500
OCR1AH=0x00;
OCR1AL=0xa0;
OCR1AH=0x00; 脉宽2500
用示波器测量出的结果。
还有阿,延时程序可能不准阿,这个延时程序我也不知道什么时候从哪里抄下来的,呵呵。(见谅哈)
***************************************************************/
目前就这么多啦,其他的正在改良中,呵呵,欢迎各位前来赐教,不胜感激。
评论0