【STM32】STM32学习笔记-PWM驱动LED呼吸灯 舵机 直流电机(16)

发布时间:2023年12月31日

00. 目录

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 可以是 23 或者 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学习笔记汇总

文章来源:https://blog.csdn.net/u010249597/article/details/135317978
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。