如图这种模拟舵机,在智能小车中是用来带动超声波探头旋转,刚接触的朋友在使用的时候可能觉得有些棘手,故将这几天的使用心得总结如下: 首 先,这个舵机是模拟舵机,而非数字舵机,这两者的区别是这样,数字舵机只要给一个PWM信号即可,这个信号是目的地的位置,舵机会自动旋转到这个位置,而 模拟舵机需要一直给予目的地的PWM信号。由于舵机需要的PWM信号实际就是一个方波,所以模拟舵机就是需要不断的重复发一样的方波,直到舵机旋转到指定 的位置,并且如果需要锁定在这个位置,那么还需继续给予这个方波。
请看下面这个例子: - void main(void)
-
- {
-
- DUOJI=1;
-
- Delay500us();
-
- Delay500us();
-
- DUOJI=0;
-
- Delay500us();
-
- Delay500us();
-
- while(1)
-
- {
-
- DUOJI=1;
-
- Delay500us();
-
- Delay500us();
-
- DUOJI=0;
-
- Delay500us();
-
- Delay500us();
-
- }
-
- }
复制代码 同样的代码一个在while外,一个在while内,如果将while内的代码都注释起来,那么舵机并不会转动,因为并没有一直给予方波,就是这意思。 但 是这样写代码不太好,因为使用的是延迟函数,程序就会停在这里,不会去响应其他的函数,所以一般是使用定时器中断,具体的代码就不在这里写了,附件里有。 需要注意的一点是,进入中断的频率越高,数每+1,舵机转过的角度就越小,也就是精度越好,我使用的是每0.02ms进入一次中断,那么数每+1,舵机大 概转过0.02/2*185=1.85°。
再有就是这个方波与转过角度的关系了,如下图:
重要的部分是0.5-2.5ms上升沿这段,时间越长舵机转过角度越大,0.5ms舵机就转过0°,2.5ms舵机就转到最大角度(大概185°),根据自己需要设定即可。0.5-30ms下降沿这段,并不重要,只要保证大于0.5ms即可。
最后请看这段代码:
- void timer0(void) interrupt 1
-
- {
-
- // TR0=0; //如果加上TR0,那么定时时间会受到影响,被延长
-
- TH0=255-TIME_CLOCK/TIME_PER_SEC/12/256;
-
- TL0=255-TIME_CLOCK/TIME_PER_SEC/12%256;
-
-
-
- uiPwmCountDuoJ++;
-
- if(uiPwmCountDuoJ>200)
-
- {
-
- uiPwmCountDuoJ=0;
-
- }
-
- PwmServomoto();
-
- // TR0=1;
-
- }
复制代码
这个中断函数里需要注意的是两行注释掉的TR0语句,如果不注释这 两条语句,那么每次进入中断会先关闭中断计数,等出中断了再继续计数,这样就相当于延长了每次中断的时间,那么舵机转过的角度就会受到影响,如果后续再在 中断中增加别的代码,那么舵机就得每次都进行调整,很麻烦,所以如果中断中的代码并不长,不建议加上TR0这两条语句。
基本就是这些了,有什么问题就留言,看到会第一时间回复。
如图这种模拟舵机,在智能小车中是用来带动超声波探头旋转,刚接触的朋友在使用的时候可能觉得有些棘手,故将这几天的使用心得总结如下: 首先,这个舵机是模拟舵机,而非数字舵机,这两者的区别是这样,数字舵机只要给一个PWM信号即可,这个信号是目的地的位置,舵机会自动旋转到这个位置,而模拟舵机需要一直给予目的地的PWM信号。由于舵机需要的PWM信号实际就是一个方波,所以模拟舵机就是需要不断的重复发一样的方波,直到舵机旋转到指定的位置,并且如果需要锁定在这个位置,那么还需继续给予这个方波。
请看下面这个例子: - void main(void)
- {
- DUOJI=1;
- Delay500us();
- Delay500us();
- DUOJI=0;
- Delay500us();
- Delay500us();
- while(1)
- {
- DUOJI=1;
- Delay500us();
- Delay500us();
- DUOJI=0;
- Delay500us();
- Delay500us();
- }
- }
复制代码
同样的代码一个在while外,一个在while内,如果将while内的代码都注释起来,那么舵机并不会转动,因为并没有一直给予方波,就是这意思。 但是这样写代码不太好,因为使用的是延迟函数,程序就会停在这里,不会去响应其他的函数,所以一般是使用定时器中断,具体的代码就不在这里写了,附件里有。需要注意的一点是,进入中断的频率越高,数每+1,舵机转过的角度就越小,也就是精度越好,我使用的是每0.02ms进入一次中断,那么数每+1,舵机大概转过0.02/2*185=1.85°。 再有就是这个方波与转过角度的关系了,如下图: 重要的部分是0.5-2.5ms上升沿这段,时间越长舵机转过角度越大,0.5ms舵机就转过0°,2.5ms舵机就转到最大角度(大概185°),根据自己需要设定即可。0.5-30ms下降沿这段,并不重要,只要保证大于0.5ms即可。 最后请看这段代码: - void timer0(void) interrupt 1
复制代码
这个中断函数里需要注意的是两行注释掉的TR0语句,如果不注释这两条语句,那么每次进入中断会先关闭中断计数,等出中断了再继续计数,这样就相当于延长了每次中断的时间,那么舵机转过的角度就会受到影响,如果后续再在中断中增加别的代码,那么舵机就得每次都进行调整,很麻烦,所以如果中断中的代码并不长,不建议加上TR0这两条语句。 最后附上完整的51单片机控制舵机源码: |