00. 目录
文章目录
- 00. 目录
- 01. 输出比较相关API
- 1.1 TIM_OC1Init
- 1.2 TIM_OCInitTypeDef结构体
- 1.3 TIM_OCMode
- 1.4 TIM_OutputState
- 1.5 TIM_OutputNState
- 1.6 TIM_OCPolarity
- 1.7 TIM_OCNPolarity
- 1.8 TIM_OCPolarity
- 1.9 TIM_OCNPolarity
- 02. PWM实现呼吸灯接线图
- 03. PWM实现呼吸灯示例
- 04. PWM驱动舵机接线图
- 05. PWM驱动舵机示例
- 06. PWM驱动直流电机接线图
- 07. PWM驱动直流电机示例
- 08. 源码下载
- 09. 附录
01. 输出比较相关API
1.1 TIM_OC1Init
/**
* @brief Initializes the TIMx Channel1 according to the specified
* parameters in the TIM_OCInitStruct.
* @param TIMx: where x can be 1 to 17 except 6 and 7 to select the TIM peripheral.
* @param TIM_OCInitStruct: pointer to a TIM_OCInitTypeDef structure
* that contains the configuration information for the specified TIM peripheral.
* @retval None
*/
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
功能:
根据 TIM_OCInitStruct 中指定的参数初始化外设 TIMx
参数:
TIMx:x 可以是 2,3 或者 4,来选择 TIM 外设
TIM_OCInitStruct:指向结构TIM_OCInitTypeDef 的指针,包含了TIMx时间基数单位的配置信息
返回值:
无
1.2 TIM_OCInitTypeDef结构体
/**
* @brief TIM Output Compare Init structure definition
*/
typedef struct
{
uint16_t TIM_OCMode; /*!< Specifies the TIM mode.
This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */
uint16_t TIM_OutputState; /*!< Specifies the TIM Output Compare state.
This parameter can be a value of @ref TIM_Output_Compare_state */
uint16_t TIM_OutputNState; /*!< Specifies the TIM complementary Output Compare state.
This parameter can be a value of @ref TIM_Output_Compare_N_state
@note This parameter is valid only for TIM1 and TIM8. */
uint16_t TIM_Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register.
This parameter can be a number between 0x0000 and 0xFFFF */
uint16_t TIM_OCPolarity; /*!< Specifies the output polarity.
This parameter can be a value of @ref TIM_Output_Compare_Polarity */
uint16_t TIM_OCNPolarity; /*!< Specifies the complementary output polarity.
This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
@note This parameter is valid only for TIM1 and TIM8. */
uint16_t TIM_OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
uint16_t TIM_OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
@note This parameter is valid only for TIM1 and TIM8. */
} TIM_OCInitTypeDef;
1.3 TIM_OCMode
/** @defgroup TIM_Output_Compare_and_PWM_modes
* @{
*/
#define TIM_OCMode_Timing ((uint16_t)0x0000)
#define TIM_OCMode_Active ((uint16_t)0x0010)
#define TIM_OCMode_Inactive ((uint16_t)0x0020)
#define TIM_OCMode_Toggle ((uint16_t)0x0030)
#define TIM_OCMode_PWM1 ((uint16_t)0x0060)
#define TIM_OCMode_PWM2 ((uint16_t)0x0070)
1.4 TIM_OutputState
/** @defgroup TIM_Output_Compare_state
* @{
*/
#define TIM_OutputState_Disable ((uint16_t)0x0000)
#define TIM_OutputState_Enable ((uint16_t)0x0001)
1.5 TIM_OutputNState
/** @defgroup TIM_Output_Compare_N_state
* @{
*/
#define TIM_OutputNState_Disable ((uint16_t)0x0000)
#define TIM_OutputNState_Enable ((uint16_t)0x0004)
1.6 TIM_OCPolarity
/** @defgroup TIM_Output_Compare_Polarity
* @{
*/
#define TIM_OCPolarity_High ((uint16_t)0x0000)
#define TIM_OCPolarity_Low ((uint16_t)0x0002)
1.7 TIM_OCNPolarity
/** @defgroup TIM_Output_Compare_N_Polarity
* @{
*/
#define TIM_OCNPolarity_High ((uint16_t)0x0000)
#define TIM_OCNPolarity_Low ((uint16_t)0x0008)
1.8 TIM_OCPolarity
/** @defgroup TIM_Output_Compare_Idle_State
* @{
*/
#define TIM_OCIdleState_Set ((uint16_t)0x0100)
#define TIM_OCIdleState_Reset ((uint16_t)0x0000)
1.9 TIM_OCNPolarity
/** @defgroup TIM_Output_Compare_N_Idle_State
* @{
*/
#define TIM_OCNIdleState_Set ((uint16_t)0x0200)
#define TIM_OCNIdleState_Reset ((uint16_t)0x0000)
02. PWM实现呼吸灯接线图
03. PWM实现呼吸灯示例
pwm.h
#ifndef __PWM_H__
#define __PWM_H__
#include "stm32f10x.h"
void pwm_init(void);
void pwm_setCompare(uint16_t compare1);
#endif /*__PWM_H__*/
pwm.c
#include "pwm.h"
//PWM初始化
void pwm_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
//1. 开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO初始化 PA0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//2. 开启定时器2内部时钟
TIM_InternalClockConfig(TIM2);
//3. 初始化定时器
TIM_TimeBaseInitStruct.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStruct.TIM_Prescaler = 720 - 1; //预分频 PSC
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //高级定时器使用
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 20; //CCR
TIM_OC1Init(TIM2, &TIM_OCInitStruct);
//7. 使能定时器
TIM_Cmd(TIM2, ENABLE);
}
void pwm_setCompare(uint16_t compare1)
{
TIM_SetCompare1(TIM2, compare1);
}
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "pwm.h"
void pwm_setCompare(uint16_t compare1);
int16_t num;
uint16_t i;
int main(void)
{
//初始化
OLED_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
pwm_init();
OLED_ShowString(1, 1, "num:");
while (1)
{
for (i = 0; i <= 100; i++)
{
pwm_setCompare(i);
delay_ms(10);
}
for (i = 0; i <= 100; i++)
{
pwm_setCompare(100 - i);
delay_ms(10);
}
}
return 0;
}
04. PWM驱动舵机接线图
05. PWM驱动舵机示例
pwm.h
#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);
#endif
pwm.c
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
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_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_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(TIM2, Compare);
}
Servo.h
#ifndef __SERVO_H
#define __SERVO_H
void Servo_Init(void);
void Servo_SetAngle(float Angle);
#endif
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);
}
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);
}
}
06. PWM驱动直流电机接线图
07. PWM驱动直流电机示例
pwm.h
#ifndef __PWM_H__
#define __PWM_H__
#include "stm32f10x.h"
void pwm_init(void);
void pwm_setCompare(uint16_t compare1);
#endif /*__PWM_H__*/
pwm.c
#include "pwm.h"
//PWM初始化
void pwm_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
//1. 开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO初始化 PA0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//2. 开启定时器2内部时钟
TIM_InternalClockConfig(TIM2);
//3. 初始化定时器
TIM_TimeBaseInitStruct.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStruct.TIM_Prescaler = 36 - 1; //预分频 PSC
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //高级定时器使用
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 0; //CCR
TIM_OC3Init(TIM2, &TIM_OCInitStruct);
//7. 使能定时器
TIM_Cmd(TIM2, ENABLE);
}
void pwm_setCompare(uint16_t compare)
{
TIM_SetCompare3(TIM2, compare);
}
motor.h
#ifndef __MOTOR_H__
#define __MOTOR_H__
#include "stm32f10x.h" // Device header
void motor_init(void);
void motor_setSpeed(int8_t speed);
#endif
motor.c
#include "motor.h"
#include "pwm.h"
void motor_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO初始化 PA0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP ;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
pwm_init();
}
void motor_setSpeed(int8_t speed)
{
if (speed >= 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_4);
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
pwm_setCompare(speed);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
GPIO_SetBits(GPIOA, GPIO_Pin_5);
pwm_setCompare(-speed);
}
}
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "motor.h"
#include "key.h"
uint8_t keyNum;
int8_t speed = 0;
int main(void)
{
//初始化
OLED_Init();
motor_init();
key_init();
OLED_ShowString(1, 1, "speed:");
while (1)
{
keyNum = key_scan();
if (1 == keyNum)
{
speed += 20;
if (speed > 100)
{
speed = -100;
}
}
motor_setSpeed(speed);
OLED_ShowSignedNum(1, 7, speed, 3);
}
}
08. 源码下载
11-PWM驱动呼吸灯.rar
12-PWM驱动舵机.rar
13-PWM驱动直流电机.rar
09. 附录
参考: 【STM32】江科大STM32学习笔记汇总