PWM驱动呼吸灯
源码:
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启时钟
TIM_InternalClockConfig(TIM2);//选择时基单元的时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//配置采样频率(滤波器),消除抖动;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInitStructure.TIM_Period=100-1;//ARR自动重装器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;//预分频器的值 72MHz/7200/10000=1
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//重复计数器的值(高级计数器才需要,目前不需要用给0即可)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//时基单元配置完毕 更新事件和更新中断是同时发生的,
TIM_OCInitTypeDef TIM_OCInitStructure;//配置输出比较单元
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较的模式
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置输出比较的极性
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//设置输出使能
TIM_OCInitStructure.TIM_Pulse=0;//设置CCR
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_Cmd(TIM2,ENABLE);//开启定时器;
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare);
}
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置输出比较的极性
输出比较的极性问题:
high是代表0,即电平信号不反转,low代表电平信号翻转。
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择复用推挽输出
选择复用推挽输出的原因:
对于普通的开漏推挽输出,引脚的控制权来自于输出寄存器的,如果想让定时器来控制引脚,那就需要使用复用开漏/推挽输出,在这里输出寄存器将被断开,输出控制将转移给片上外设。
引脚重映射:
引脚定义表里可以看到,TIM2的CH1可以从PA0挪到PA15上,进行引脚重映射需要用到AFIO,开启AFIO时钟。
引脚定义表中为加粗的就是默认有接口复用的,如果该Pin口想做GPIO口使用,先用GPIO_PinRemapConfig函数给取消复用,然后才能继续使用。
参数详解:
GPIO_Remap_SWJ_NoJTRST: SWJ是SWD和JTAG两种调试方式,NOJTRST意思是接触JTRST引脚的复用,根据引脚定义表,JTRST引脚也就是PB4,如果使用这个参数,PB4就变成正常的GPIO口了,上图其他四个还是调试端口,不能当作GPIO来使用。
GPIO_Remap_SWJ_JTAGDisable:解除JTAG调试端口的复用,PA15,PB3,PB4三个端口变为GPIO,上面的PA13和PA14仍尾SWD的调试端口。
GPIO_Remap_SWJ_Disable:五个引脚全部变为普通的GPIO,没有调试功能。
调试端口使用要小心!解除调试接口后,STLINK就下载不进去程序了。
PWM驱动舵机
源码:
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启时钟
TIM_InternalClockConfig(TIM2);//选择时基单元的时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//配置采样频率(滤波器),消除抖动;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInitStructure.TIM_Period=20000-1;//ARR自动重装器的值
TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//预分频器的值 72MHz/7200/10000=1
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//重复计数器的值(高级计数器才需要,目前不需要用给0即可)
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//时基单元配置完毕 更新事件和更新中断是同时发生的,
TIM_OCInitTypeDef TIM_OCInitStructure;//配置输出比较单元
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较的模式
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置输出比较的极性
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//设置输出使能
TIM_OCInitStructure.TIM_Pulse=0;//设置CCR500-2500=0.5-2.5ms
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
TIM_Cmd(TIM2,ENABLE);//开启定时器;
}
void PWM_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(TIM2,Compare);
}
#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);
}
PWM驱动直流电机
源码
#include "stm32f10x.h" // Device header
#include "PWM.h"
void Motor_Init(void)
{
PWM_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void Motor_SetSpeed(int8_t speed)
{
if (speed>=0){
GPIO_SetBits(GPIOA,GPIO_Pin_5);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
PWM_SetCompare3(speed);
}
else{
GPIO_SetBits(GPIOA,GPIO_Pin_4);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
PWM_SetCompare3(-speed);
}
}