江科大 STM32入门教程 P16 PWM驱动LED&舵机&直流电机

发布时间:2023年12月20日

1 PWM驱动LED

1.1 接线图

在这里插入图片描述

1.2 PWM通路初始化步骤

在这里插入图片描述

  1. RCC开启时钟(打开TIM外设时钟和RCC外设时钟)
  2. 配置时基单元(时钟源原选择)
  3. 配置输出比较单元(ccr\输出比较模式、极性选择、输出使能)
  4. 配置GPIO(复用)
  5. 运行控制(启动计数器)

1.3 PWM库

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
配置输出比较模块的库函数(oc:ouput compare)
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);//
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
//配置强制输出模式
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
配置CCR寄存器的预装功能(也是影子寄存器,在写入不会立即生效,而是出发事件后才会生效)
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
//配置快速使能的
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
//外部事件时清除REF信号
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
//单独设置输出比较的极性,带N就是高级定时器互补通道的配置
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
//单独修改输出使能参数
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
//单独更改CCR寄存器值的函数

1.4 初始化代码实现

  1. 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_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO复用功能推挽输出
	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //选择要调用的GPIOpin口
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 100-1;//周期的值ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频器的数值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
  //初始化输出比较单元
	TIM_OCInitTypeDef IM_OCInitStruct;
	 TIM_OCStructInit(&IM_OCInitStruct);//给结构体变量成员赋初始值,再修改部分的结构体成员
	IM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1 ;//设计输出比较的模式
	IM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
	IM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	IM_OCInitStruct.TIM_Pulse = 0; //设置CCR捕获比较寄存器的数值
	TIM_OC1Init(TIM2,&IM_OCInitStruct);
	
	TIM_Cmd(TIM2,ENABLE);
	
	
}
void PWM_SetCompare1(uint16_t Compare)//设置CCR的数值由之前的固定值变成动态值 uint16 范围0到2^16;
{
	TIM_SetCompare1(TIM2,Compare);
}

  1. PWM.h程序
#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
#endif

3.main.程序

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "PWM.h"
#include "OLED.h"
#include "Delay.h"
uint8_t i;

int main()
{  
	OLED_Init();
	PWM_Init();
	
	
	
	while(1)
	{
		for(i = 0;i<=100;i++)//IED由0到100,逐渐变亮
		{
			PWM_SetCompare1(i);//设置CCR寄存器的值
			Delay_ms(10);
		}
		for(i = 0;i<=100;i++)//IED由100到0,逐渐变暗
		{
			PWM_SetCompare1(100-i);
			Delay_ms(10);
		}
		}
}

效果:呼吸灯由亮变暗,由暗变亮;
这里输出的用PA1口的通道2

补充:引脚重映射功能

在这里插入图片描述
例子:TIM2_CH1_Enable的功能可以从PA0映射到PA15引脚上,这里需要使用GPIO的AFIO功能,如何使用AFIO功能?

  1. 开启AFIO寄存器挂载在总线上,开启总线时钟;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//AFIO是APB2的设备,

2.打开GPIO.h的库函数进行查找

void GPIO_PinRemapConfigure();//引脚重新配置映射函数

在这里插入图片描述

2 PWM驱动舵机

2.1 接线图

在这里插入图片描述
PWM输出通道接到PA1的引脚上;
在PB1接一个按键用来控制舵机;
在这里插入图片描述

2.2 代码实现

3 直流电机

include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	 GPIO_InitTypeDef GPIO_InitStruct;
	 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO复用功能推挽输出
	 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //选择要调用的GPIOpin口
	 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	 GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 100-1;//周期的值ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1;//预分频器的数值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
  //初始化输出比较单元
	TIM_OCInitTypeDef IM_OCInitStruct;
	 TIM_OCStructInit(&IM_OCInitStruct);//给结构体变量成员赋初始值,再修改部分的结构体成员
	IM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1 ;//设计输出比较的模式
	IM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
	IM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	IM_OCInitStruct.TIM_Pulse = 0; //设置CCR捕获比较寄存器的数值
	TIM_OC3Init(TIM2,&IM_OCInitStruct);
	
	TIM_Cmd(TIM2,ENABLE);
	
	
}
void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM2,Compare);
}

#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);
#endif

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "Motor.h"
#include "OLED.h"
#include "Delay.h"
#include "Key.h"
uint8_t i;
uint8_t KeyNum;
int8_t speed;

int main()
{  
	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);
	}
		
}
	
文章来源:https://blog.csdn.net/CScodemini/article/details/134955914
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。