|
发表于 2009-11-8 20:29:04
|
显示全部楼层
重新改写一下例程,以利于大家阅读,错误之处请大家指出。没经过lz允许,不知道可不可以??
大概说明一下原理,我也是听我同事说得,舵机的脉宽值是500us到2500us(400hz),所以在产生脉宽的时候
,周期至少要在400Hz以下。
本例用的是atmega16L,8M内部晶振,定时器1的10位相位修正PWM,OC1A引脚输出控制舵机。
如果产生PWM时,你的分频数为1时(不分频),那么产生的方波是4000Hz(由8000000/2^10/2得出)的,你要
2500us的方波肯定是没戏了,至于500us的,我也忘了自己试没试,分频数为8时,那么产生的方波是500Hz
(8000000/2^10/2/8得出)的,你要2500us的方波肯定也是没戏了,所以,我用了64分频的方式,因此,
TCCR1B=0x03;
用示波器看的,当OCR1AL=0x20时,脉宽为500us(计算:32*1/(8000000/64)),当OCR1AL=0xa0时脉宽
2500us。这个值也是大概比较准确的,OCR1AL的值差那么一点点也不怎么看的出来,所以,我就用了这么两个整
数值。
下面与大家一起分享:
#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的由来,此设置要产生2500us的脉宽,OCR1AL=0xa0,OCR1AH=0x00;
a0换算成10进制,得160
(2):32的由来,此设置要产生500us的脉宽,OCR1AL=0xa20,OCR1AH=0x00;
20换算成10进制,得32
OCR1AL=0x20; 脉宽500
OCR1AH=0x00;
OCR1AL=0xa0;
OCR1AH=0x00; 脉宽2500
用示波器测量出的结果。
还有阿,延时程序可能不准阿,这个延时程序我也不知道什么时候从哪里抄下来的,呵呵。(见谅哈)
***************************************************************/
目前就这么多啦,其他的正在改良中,呵呵,欢迎各位前来赐教,不胜感激 |
|