stm32——pwm驱动LED灯、舵机、直流电机

这篇具有很好参考价值的文章主要介绍了stm32——pwm驱动LED灯、舵机、直流电机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、知识点补充

1.PWM波输出与GPIO的引脚对应关系图

stm32驱动舵机pwm,stm32,单片机,嵌入式硬件
stm32驱动舵机pwm,stm32,单片机,嵌入式硬件

a. TIM2的引脚复用子啊PA0引脚上,所以TIM2、CH1、PA0三者是捆绑在一起的,即在PA0引脚上通过TIM2通道1CH1输出PWM
b. TIM2、CH1、PA0三者一般是捆绑在一起,但可以通过重映射改变
c. TIM2、CH2、PA1同理

2.重映射简介

stm32驱动舵机pwm,stm32,单片机,嵌入式硬件
改为PA15,选择重映射方式1或完全重映射
在时钟开启后写入

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  //PA15为调试端口,需要解除调试端
若想要让PA15、PB3、PB4这三个引脚当作普通GPIO来使用,则加第一、三句,打开AFIO时钟,让AFIO时钟将JTAG复用解除掉
如果想要重映射定时器或者其他外设的复用引脚,加第一句和第二句,就要先打开AFIO时钟,再用AFIO重映射外设复用的引脚,
若重映射的引脚正好是调试端口,则三句全加上

3.计数器的计算

PWM频率=计数器更新频率
比如要产生一个频率为1KHz,占空比为50%,分辨率为1%的PWM波形
72M/(PSC+1)/ (ARR+1)=1000
CCR/(ARR+1)=0.5
1/(ARR+1)=0.01
计算得:ARR=99,CCR=50, PSC=720-1;

4.基本步骤

stm32驱动舵机pwm,stm32,单片机,嵌入式硬件

第一步:RCC开启时钟,打开TIM外设和GPIO外设的时钟
第二步:配置时基单元,包括时基单元和时基单元前的时钟源选择(不选择则默认内部时钟)
第三步:配置输出比较单元,里面包括CCR的值、输出比较模式、极性选择、输出使能(结构体配置)
第四步:配置GPIO口,初始化为复用推挽输出的配置
第五步:运行控制,启动计数器,就能输出PWM波

5.输出比较模式简介

stm32驱动舵机pwm,stm32,单片机,嵌入式硬件
常用模式为 PWM1模式1

二、实例

1.PWM驱动LED灯

PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)	
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   //第一步,开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;  //第四步,配置GPIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	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_OCInitStructure;   //第三步,配置输出比较单元(CCR)
	TIM_OCStructInit(&TIM_OCInitStructure);  //初始化所以结构体(结构体中有带N的变量,是高级配置输出比较单元才有的,本次实例不需要用到,初始化后让他不影响别的模块)
	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(0-0xff)
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);  
	
	TIM_Cmd(TIM2,ENABLE);//第五步,运行控制启动
	
}


void PWM_SetCompare1(uint16_t Compare) //由main.c设置占空比
{
	TIM_SetCompare1(TIM2,Compare); 
}

PWM.h

#ifndef  __PWM_H__
#define  __PWM_H__

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

#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++)  更改CCR值
		{
			PWM_SetCompare1(i);
			Delay_ms(10);
		}
		for(i=0;i<=100;i++)
		{
			PWM_SetCompare1(100-i);
			Delay_ms(10);
		}	
	}
}

2.PWM驱动舵机

参数计算
stm32驱动舵机pwm,stm32,单片机,嵌入式硬件

舵机要求频率 :50Hz(周期为20ms)
舵机角度控制(占空比):0.5-2.5ms(时长)
(3个变量,2个方程)解不是唯一的
为方便计算
取PSC+1=72,ARR+1=20k
当CCR=500时,高电平时长为0.5ms 

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_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	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)  //变为通道2
{
	TIM_SetCompare2(TIM2,Compare);
}

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();
	Init_KEY();
	
	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驱动直流电机

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_2;		//GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	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 = 36 - 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_OC3Init(TIM2, &TIM_OCInitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
	
}


		void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM2,Compare);
}

Motor.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"
 
void Motor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	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;
	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);
	}
}

main.c文章来源地址https://www.toymoban.com/news/detail-765471.html

#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();
	Motor_Init();
	Init_KEY();
	
	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);
	}
}

到了这里,关于stm32——pwm驱动LED灯、舵机、直流电机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【51单片机】直流电机驱动(PWM)(江科大)

    · 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转 · 直流电机主要由永磁体(定子)、线圈(转子)和换向器组成 · 除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等 电机的驱动无法

    2024年02月20日
    浏览(50)
  • 【51单片机】直流电机的驱动和PWM调速

    51单片机驱动直流电机与 PWM 调速是通过使用 51 单片机来控制直流电机的转速和方向。51 单片机通过控制电机的电流来实现驱动,并通过生成 PWM 信号来调节电机的转速。使用 PWM 调速可以使得直流电机的转速精确可控,并且减少了电机的功率损耗。在 51 单片机的控制系统中,

    2023年04月09日
    浏览(42)
  • 10、江科大stm32视频学习笔记——PWM驱动led呼吸灯、驱动舵机、驱动直流机

    目录 一、PWM驱动LED呼吸灯(灯接在PA0) 1、PWM波和GPIO的对应关系参考引脚定义表 2、计数器的计算 3、TIM输出PWM波使用步骤​编辑 4、代码 (1)输出化比较单元 (2) PWM.c (3)main.c 5、重映射更换成PA15亮灯 二、PWM驱动舵机(舵机接在PA1、按键在PB1)  1、电路图 2、参数计算

    2024年02月14日
    浏览(41)
  • STM32PWM控制直流电机

    PWM介绍 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用 微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽 度的控制 PWM的原理: 假定定时器工作在向上计数 PWM 模式,且当 CNT=CCRx 时输出 1。那么就可以

    2024年02月08日
    浏览(49)
  • STM32第八课:PWM控制直流电机

            TB6612FNG是一款新型驱动器件,能独立双向控制2个直流电机,它具有很高的集成度,同时能提供足够的输出能力,运行性能和能耗方面也具有优势因此在集成化、小型化的电机控制系统中,它可以作为理想的电机驱动器件。                           

    2024年03月24日
    浏览(52)
  • K_A08_009 基于 STM32等单片机驱动TB6612模块按键控制直流电机正反转加减速启停

    目录 一、资源说明 二、基本参数         1、参数         2、引脚说明 三、驱动说明         TB6612模块驱动说明         对应程序:         ENA ENB输出PWM 四、部分代码说明         接线说明                 1、STC89C52RC+TB6612模块                 2、STM32F

    2024年02月15日
    浏览(38)
  • STM32-微项目03-pwm控制直流电机运行

    一,项目目标 实现利用STM32F103C8T6+TB6612,输出不同占空比输出的PWM波,从而实现电机不同转速的运行、正反转的功能;    二、硬件涉及 1,STM32核心板 2,TB6612直流电机驱动模块 3,直流电机  三、硬件接线涉及 1,先看TB6612直流电机驱动模块: ①驱动模块是具备两路PWM输入

    2024年02月04日
    浏览(49)
  • K_A08_005 基于 STM32等单片机驱动XY-160D模块按键控制直流电机正反转加减速启停

    目录 一、资源说明 二、基本参数 四、部分代码说明         接线说明                 1、STC89C52RC+XY-160D模块                  2、STM32F103C8T6+XY-160D模块 五、基础知识学习与相关资料下载 六、视频效果展示与程序资料获取 七、项目所有材料清单 八、注意事项 九

    2024年02月14日
    浏览(72)
  • 一文搞懂如何使用STM32驱动直流电机(普通PWM输出和L298N、高级定时器输出带死区双通道互补PWM和IR2110S及自举电路、H桥电路和电机正反转)

    笔者从开始接触嵌入式单片机开始,就和驱动电机相伴而走。从最开始的直接买L298N驱动模块直接驱动直流电机,到现在自己设计PCB电路板驱动直流电机,可以说是和电机驱动共同成长了。现在笔者将这一过程的收获记录下来,希望对大家有所帮助。 不用详细了解L298N芯片和

    2024年02月02日
    浏览(50)
  • stm32+TB6612驱动直流电机

            因为单片机的不可以直接的驱动电机,所以需要在他们之间加上一个电机的驱动模块,之前的文章里面用过L298N电机驱动模块,现在再给大家推荐一个新的电机驱动模块,他比L298N好用许多,而且占用体积小,发热也少。TB6612可以一次驱动两个直流电机,输出PWM也

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包