TA的每日心情 | 开心 2017-6-17 09:42 |
---|
签到天数: 3 天 连续签到: 1 天 [LV.2]偶尔看看I
|
玩GD32F450那些事之光耦+舵机
一、前言 早些日子分享了GD32F450半自动相机方案,不知啥情况几天了一直都在审核中,工作人员也没有答复,擦擦!搞得心情不爽,不过咱们不管他们了,不要让这不愉快的事情影响到我们学习分享的步伐。这次我首先要分享的是我在舵机驱动中干得那些坑爹的事。 其实干下这些事都是,自己在瞎搞搞,总感觉驱动金属舵机需要提供给个大的驱动电流,最后导致烧了舵机,烧了小红板上的USB模块芯片。
1.1金属舵机 1.2普通塑料舵机
二、干的那些事
1、S8050驱动舵机
S8050各肯定用得特别的多,我也开始就想到了用这个来搞。
图1.3NPN管驱动
如上图所示,设计的时候,我是想保证这个输出电平幅值是0-5V,管子工作在饱和状态,GD32F450的输出电压是0-3.3V,这样化,R2=47K,R1=200R, 当Vin=3.3V 时Ib=0.07mA, Ic=21mA, 此时Vout=0V ,当Vin=0V时,Vout=5V。
2、S8550驱动舵机
对于PNP管来驱动,我们经常用来驱动蜂鸣器,当然不是下面这种搞法,下面这种形式是我前面在做板子的时候,将以封装搞错了,实在没辙将本应该焊接NPN的换成了PNP在1,2脚直接悬空焊接了一个电阻就得到了下图了。
图1.4PNP管驱动
如上图所示,3.3V时输出0V,0V时输出5V
3、开漏输出驱动舵机
当然对于单片机引脚没法输出5V时,我们还有一个常用的就是开漏输出并上拉5V啦。
图1.5上拉5V
4、光耦驱动
搞到光耦,也是当我用上面的开漏输出去驱动两个金属舵机时,舵机动了几下忽然发现一缕青烟,从此这个GL850就退休了。
图1.7 退休的GL850
冒了烟,要我认识到,保护还是很重要的,所以选择了下面的光耦驱动,将电源隔离了,外接6V电源给舵机供电。
图1.7 光耦驱动
小测了输出波形,这波形还是不错的,怎么说我也不担心烧小红板了。
图1.8输入输出波形
个人总结下:使用前面三种方法输出波形1和3还是挺好的,唯独2幅值达到了,但是擦擦有相当大的干扰,干扰原因不详,反正最后舵机烧了,使用方案1时,也是坑,不知当时是电机已经烧了还是怎么,幅值会被拉低。方案3,那就呵呵呵,两个舵机以上GL850冒烟了。有大神精通请指导一二。
三、舵机 1)、常用舵机的额定工作电压为6V,可以使用LM1117等芯片提供6V的电压,如果为了简化硬件上的设计直接使用5V的供电影响也不是很大,但最好和单片机进行分开供电,否则会造成单片机无法正常工作。
2)、一般来说可以将来信号线连接至单片机的任意引脚,对于51单片机需通过定时器模块出PWM才能进行控制。但是如果连接像飞思卡尔之类的芯片,由于飞思卡尔内部带有PWM模块,可以直接输出PWM信号,此时应将来信号连于专用的PWM输出引脚上。
图1.9脉冲与角度对应图
四、代码
我们这是是定时器产生两路PWM来控制舵机。
1、引脚配置- void SG_gpio_config(void)
- {
- rcu_periph_clock_enable(RCU_GPIOA);
-
- /*Configure PA1 PA2 (TIMER1 CH1 CH2) as alternate function*/
- gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
- gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
- gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
- gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
- gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_1);
- gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2);
- }
复制代码 2、定时器配置- void timer_config(void)
- {
- /* -----------------------------------------------------------------------
- TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
- TIMER1CLK = SystemCoreClock / 120 = 1MHz
- TIMER1 channel1 duty cycle = (4000/ 20000)* 100 = 25%
- TIMER1 channel2 duty cycle = (8000/ 20000)* 100 = 50%
- ----------------------------------------------------------------------- */
- timer_oc_parameter_struct timer_ocintpara;
- timer_parameter_struct timer_initpara;
- rcu_periph_clock_enable(RCU_TIMER1);
- rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
- timer_deinit(TIMER1);
- /* TIMER1 configuration */
- timer_initpara.prescaler = 119;
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 19999; //ÉèÖóÉ20ms
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
- timer_initpara.repetitioncounter = 0;
- timer_init(TIMER1,&timer_initpara);
- /* CH1,CH2 configuration in PWM mode1 */
- timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
- timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
- timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);
- timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocintpara);
- /* CH1 configuration in PWM mode1,duty cycle --% */
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,1000);
- timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);
- timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);
- /* CH2 configuration in PWM mode1,duty cycle --% */
- timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,1000);
- timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM0);
- timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);
- /* auto-reload preload enable */
- timer_auto_reload_shadow_enable(TIMER1);
- /* auto-reload preload enable */
- timer_enable(TIMER1);
- }
复制代码 五、实物图
大家会疑惑怎么晒出来的是两塑料舵机,主要是考虑大家可能用塑料舵机比较多。
图1.10 双舵机实物图
|
|