PWM驅動舵機?
接線圖如上圖所示。注意,舵機的5V?線不能接到面包板上的正極,面包板上的正極只有3.3V,是STM32提供的,所以要接到STLINK的5V,
我們如何驅動舵機呢?由之前我們介紹原理知道,要輸出如下圖對應的PWM波形才行,只要你的波形能按照這個規定,準確的輸出,就能驅動
在上次PWM驅動呼吸燈的基礎上改一下,我們現在電路圖連接的是PA1口的通道2,這里GPIO的初始化時,改為GPIO_Pin_1,可以從引腳定義表去看看,呼吸燈是使用PA0引腳,所以是定時器2的通道1,但是PA1是用的定時器2的通道2,所以要把TIM_OC1Init改為OC2.
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
如果通道1和通道2都想用的話,就直接初始化兩個通道,比如
TIM_OC2Init(TIM2,&TIM_OCInitStructure);TIM_OC1Init(TIM2,&TIM_OCInitStructure);
這樣就能同時使用兩個通道來輸出PWM了,同理,通道3與通道4也是可以使用的。
那對于同一個定時器的不同通道輸出的PWM,他們的頻率,因為不同通道是共用一個計數器的,所以他們的頻率必須是一樣的。它們的占空比,由各個的CCR決定,所以占空比可以各自設定,
還有它們的相位,由于計數器更新,所有PWM同時跳變,所以它們的相位是同步的。這就是同一個定時器不同通道輸出PWM的特點,如果驅動多個舵機或者直流電機,那使用同一個定時器不同通道的PWM,就完全可以了。?
?最后,把改的CCR全部變為通道2.
?然后根據舵機計算公式設置CCR,PSC,ARR.
?
最后代碼如下:所用的所有模塊如下
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "Key.h"uint8_t KeyNum;
float Angle;int main(void)
{OLED_Init();Servo_Init();Key_Init();OLED_ShowString(1, 1, "Angle:");while (1){KeyNum = Key_GetNum();if (KeyNum == 1){Angle += 30;if (Angle > 180){Angle = 0;}}Servo_SetAngle(Angle);OLED_ShowNum(1, 7, Angle, 3);}
}
?Servo.c
#include "stm32f10x.h" // Device header
#include "PWM.h"void Servo_Init(void)
{PWM_Init();
}void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle / 180 * 2000 + 500);
}
Servo.h
#ifndef __SERVO_H
#define __SERVO_Hvoid Servo_Init(void);
void Servo_SetAngle(float Angle);#endif
?其他的模塊都在前面的博客有,自己可以去找一下,后面我會全部整理在一起。
PWM驅動直流電機
接線圖:
代碼如下:
所有模塊如下:
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"uint8_t KeyNum;
int8_t Speed;int main(void)
{OLED_Init();Motor_Init();Key_Init();OLED_ShowString(1,1,"Speed:");while(1){KeyNum=Key_GetNum();if(KeyNum==1){Speed+=20;if(Speed>100){Speed=-100;}}Motor_SetSpeed(Speed);OLED_ShowSignedNum(1,7,Speed,3);}
}
Mortor.c
#include "stm32f10x.h" // Device header
#include "PWM.h"void Motor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//方向控制腳GPIO_Init(GPIOA, &GPIO_InitStructure);PWM_Init();
}void Motor_SetSpeed(int8_t Speed)
{if(Speed>=0){GPIO_SetBits(GPIOA, GPIO_Pin_4);GPIO_ResetBits(GPIOA, GPIO_Pin_5);PWM_SetCompare3(Speed);}else{GPIO_ResetBits(GPIOA, GPIO_Pin_4);GPIO_SetBits(GPIOA, GPIO_Pin_5);PWM_SetCompare3(-Speed);}
}
Mortor.h
#ifndef __OLED_H
#define __OLED_H
void Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);#endif