本文章转自B站江科大自化协
1。pwm驱动LED呼吸灯
新建PWM.C PWM.H
PWM.C
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
//第一步RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//初始化PA0引角
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_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; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCIStructure;
TIM_OCStructInit(&TIM_OCIStructure);//给结构体附初始值
TIM_OCIStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCIStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCIStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCIStructure.TIM_Pulse=0; //CCR
TIM_OC1Init(TIM2,&TIM_OCIStructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare);
}
PWM.H
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
uint8_t i;
int main(void)
{
OLED_Init();
PWM_Init();
while (1)
{
for(i = 0; i<=100; i++)
{
PWM_SetCompare1(i);
Delay_ms(10);
}
for(i = 0; i<=100; i++)
{
PWM_SetCompare1(100 - i);
Delay_ms(10);
}
}
}
编译下载
PS:引脚重映射 --TIM2_CH1可以从PA0 挪到PA15引脚上
具体操作 用到AFIO
pwm.c
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
//第一步RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//初始化PA0引角
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//开启AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//引脚重映射配置 PA0换到PA15
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG调试端口的复用
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//第二步选择时基单元的时钟源
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; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCIStructure;
TIM_OCStructInit(&TIM_OCIStructure);//给结构体附初始值
TIM_OCIStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCIStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCIStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCIStructure.TIM_Pulse=0; //CCR
TIM_OC1Init(TIM2,&TIM_OCIStructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare);
}
编译下载看效果
2.PWM驱动舵机
接线图
目录结构
pwm.c
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
//第一步RCC开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//初始化PA0引角
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_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; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCIStructure;
TIM_OCStructInit(&TIM_OCIStructure);//给结构体附初始值
TIM_OCIStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCIStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCIStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCIStructure.TIM_Pulse=0; //CCR
TIM_OC2Init(TIM2,&TIM_OCIStructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
void PWM_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(TIM2,Compare);
}
pwm.h
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);
#endif
Servo.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
//舵机初始化
void Servo_Init(void)
{
PWM_Init();
}
//0 500
//180 2500
//舵机设置角度
void Servo_SetAngle(float Angle)
{
PWM_SetCompare2(Angle / 180 *2000+500);
}
servo.h
#ifndef __SERVO_H
#define __SERVO_H
void Servo_Init(void);
void Servo_SetAngle(float Angle);
#endif
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);
}
}
效果图
3.PWM驱动直流电机
接线图
目录结构
Motor.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
void Motor_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIOA时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
//初始化GPIOA 电机方向控制脚初始化
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);
}
}
Motor.h
#ifndef __MOTOR_H
#define __MOTOR_H
void Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);
#endif
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();
Key_Init();
Motor_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);
}
}
测试
完美