10、江科大stm32视频学习笔记——PWM驱动led呼吸灯、驱动舵机、驱动直流机

这篇具有很好参考价值的文章主要介绍了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、参数计算

3、代码

(1) PWM.c修改的地方

(2)PWM.c完整代码

(3)Servo.c

(4)main.c

三、PWM驱动直流电机

1、原理图

2、代码

(1)PWM.c中改的地方

(2)Motor.c

(3)main.c

四、基础知识


一、PWM驱动LED呼吸灯(灯接在PA0)

1、PWM波和GPIO的对应关系参考引脚定义表

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

(1)TIM2的引脚复用在了PA0引脚上,故要是要TIM2的OC1也就是CH1通道,输出PWM,那它只能在PA0的引脚上输出,而不能任意选择引脚输出

(2)同样,若选择 TIM2的是CH2通道,那只能在PA1端口输出,以此类推

(3)但还是有一次重映射的机会,可以在其他引脚上输出 

2、计数器的计算

PWM的频率=计数器的更新频率

若要产生一个频率为1kHz,占空比为50%,分辨率为1%的PWM波形

带入公式:72M/(PSC+1)/(ARR+1)=1000

                  CCR/(ARR+1) = 50%

                  1/(ARR+1)=1%

则计算出:ARR+1=100,CCR=50,PSC+1=720 

则等以1kHZ的频率闪烁,但是我们看不出来

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;        //ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;        //PSC
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;

3、TIM输出PWM波使用步骤

第一步:RCC开启时钟,打开TIM外设和GPIO外设的时钟

第二步:配置时基单元,包括时基单元和时基单元前的时钟源选择

第三步:配置输出比较单元,里面包括CCR的值、输出比较模式、极性选择、输出使能(结构体配置)

第四步:配置GPIO口,初始化为复用推挽输出的配置

第五步:运行控制,启动计数器,就能输出PWM波

4、代码

(1)输出化比较单元

	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的值0-ffff
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);//用结构体初始化	

(2) 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;
	//对于普通的开漏推挽输出,引脚的控制权是来自于输出数据寄存器,
	//若想要定时器控制引脚,需要使用复用开漏/推挽输出的模式
	//此时,输出数据寄存器将被断开,输出控制权将转移到片上外设
	//本实验中片上外设引脚连接的就是TIM2的CH1通道,所以只有把GPIO设置程复用推挽输出
	//引脚的控制权才能交给片上外设,PWM波形才能通过引脚输出
	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_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);
	
	//初始化输出比较单元
	//PA0口对应1通道
	TIM_OCInitTypeDef TIM_OCInitStructure;
	//不想把所有成员都列出来赋一个初始值,就用TIM_OCStructInit初始化值,防止出现奇怪的错误
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1和PWM模式2
	//输出比较极性:
	//TIM_OCPolarity_High高级性,就是极性不翻转,REF波形直接输出,或者说有效电平是高电平
	//TIM_OCPolarity_Low低极性,就是REF波形电平取反,有效电平为低电平
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;		//设置CCR的值0-ffff
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);//用结构体初始化	
	
	TIM_Cmd(TIM2, ENABLE);//启动定时器
}

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

(3)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);
		}
	}
}

5、重映射更换成PA15亮灯

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

 想要把PA0改成PA15,就可以选重映射方式1或者完全重映射

在"GPIO_InitTypeDef GPIO_InitStructure;"前面添加

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);              (1)

GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);                    (2)
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE)           (3)

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

PA15是调试端口,所以要解除调试端口 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE)

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

改变引脚:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

改为

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;

此时PA0的灯不亮,而PA15的灯亮了

二、PWM驱动舵机(舵机接在PA1、按键在PB1) 

1、电路图

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

2、参数计算

  • 舵机要求的频率:20ms,故为50Hz
  • 占空比:舵机要求高电平时间是0.5ms~2.5ms
  • 计算出来的PSC和ARR不固定
  • 测试PSC+1=72,ARR+1=20k时比较方便,此时,CCR=500,则0.5ms,CCR=2500,则2.5ms
  • CCR=500,0度,CRR=2500,180度

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

3、代码

(1) PWM.c修改的地方

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;		//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC

void PWM_SetCompare2(uint16_t Compare)//从通道1改为使用通道2
{
	TIM_SetCompare2(TIM2, Compare);
}

(2)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)//使用通道2
{
	TIM_SetCompare2(TIM2, Compare);
}

(3)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);
}

(4)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);
	}
}

三、PWM驱动直流电机

1、原理图

gpio pwm,stm32单片机,stm32,单片机,嵌入式硬件

  •  红色的是TB6612电机驱动模块
  • 连接电机的两根线不分正反,对调知识反过来转动,AIN1和AIN2是方向控制,任意连接两个GPIO就行(此处接PA4、PA5),PWMA是速度控制,需要接PWM的输出脚(PA2,PA2对应的是TIM2的通道3,到时候初始化通道三即可)

2、代码

(1)PWM.c中改的地方

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//(0改为2)
TIM_OC3Init(TIM2, &TIM_OCInitStructure);//(1改为3)


TIM_TimeBaseInitStructure.TIM_Period = 1000 - 1;		//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC
//改频率,将1kHZ改为20kHz
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;		//PSC

void PWM_SetCompare3(uint16_t Compare)//(1改为3)
{
	TIM_SetCompare3(TIM2, Compare);
}

(2)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);
	}
}

(3)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();
	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);
	}
}

四、基础知识

void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)

仅高级定时器使用,在使用高级定时器输出PWM时,需要调用这个函数,使能主输出,否则PWM将不能正常输出文章来源地址https://www.toymoban.com/news/detail-627285.html

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

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

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

相关文章

  • stm32HAL库学习笔记----pwm驱动舵机

    目录 一、目标 二、准备 三、原理 四、cubemx 五、程序 实现stm32驱动舵机旋转0°,45°,90°,135°,180°等角度。 stm32f103(c8t6),舵机(SG90 9g),杜邦线 接线:舵机红线-----------5V(mcu)            舵机棕线-----------GND(mcu)            舵机黄线-----------PA1(视情况而定

    2023年04月26日
    浏览(38)
  • 5、江科大stm32视频学习笔记——OLED显示屏

    目录 1、OLED简介  2、OLED硬件电路 3、OLED驱动函函数简介和应用 4、用keil进行调试 4引脚OLED SCL和SDA是I2C通信引脚,需要接在I2C通信的引脚上 实验中用的模块是GPIO口模拟的I2C通信,故SCL和SDA两个端口可以接在任意的GPIO口上 7引脚OLED 右边5个引脚是SPI通信协议的引脚 如果是GPI

    2024年02月14日
    浏览(43)
  • stm32——pwm驱动LED灯、舵机、直流电机

    改为PA15,选择重映射方式1或完全重映射 在时钟开启后写入 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; 常用模式为 PWM1模式1 PWM.c PWM.h main.c 参数计算 PWM.c Servo.

    2024年02月04日
    浏览(43)
  • 【STM32+HAL+Proteus】系列学习教程---PWM(呼吸灯)

    1、利用定时器输出PWM实现呼吸灯 2、学会STM32CubeMX软件输出PWM的配置 3、具体目标:利用定时器3的通道2(部分重映射到PB5管脚)输出1KHz的矩形波,实现呼吸灯。 1、什么是PWM?         PWM (Pulse width modulation)脉冲宽度调制。PWM是通过编程控制输出方波的频率和占空比(高

    2024年04月23日
    浏览(54)
  • STM32CubeIDE学习笔记——使用HAL库PWM输出驱动舵机

    目录 PWM驱动简介 工程配置 代码编写 这里我采用的是STM32F103C8T6最小系统板,SG-90舵机实现功能。 舵机驱动角度和PWM占空比有关系,具体对应为50--0度  150--90度  250--180度,通过STM32的定时器功能输出PWM波来控制舵机进行转动。  时钟选择外部高速时钟 系统映射配置 时钟树设

    2024年02月13日
    浏览(43)
  • 江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟

    目录 一、TIM(Timer)定时器简介  1.1 定时器类型 摘要 1.1.1 基本定时器 1.1.2 通用定时器 1.1.3 高级定时器  1.2 定时中断基本结构 1.2.1 结构框图 1.2.2 时序图 二、定时器定时中断定时器外部时钟 2.1 内部时钟闹钟代码 2.1.1 Timer.c 2.1.2 Buzzer.c加入间隔发声函数 2.1.3 main.c 2.1.4 实验视频

    2024年01月23日
    浏览(64)
  • 18、江科大stm32视频学习笔记——USART串口发送&串口发送和接收

    目录 一、USART串口发送  1、电路图 2、printf函数的移植方法 3、serial.c 4、main.c 5、解决直接写汉字,编译器报错 二 、USART串口发送和接收 1、查询实现 2、中断实现  (1)在Serial.c中添加的代码 (2)主函数中调用 (3)思路 (4)完整的Serial.c代码 (5)mian.c  要交叉连接,所

    2023年04月08日
    浏览(64)
  • STM32F103RCT6开发板M3单片机教程07-TIMER1CH1输出 PWM做LED呼吸灯

    本教程使用是( 光明谷SUN_STM32mini开发板 )   免费开发板   在谷动谷力社区注册用户,打卡,发帖求助都可以获取积分,当然最主要是发原创应用文档奖励更多积分. (可用积分换取,真的不用钱,开发板免费玩):STM32F103RCT6开发板M3单片机核芯小系统板学习板 ... 已经购买用

    2024年02月22日
    浏览(68)
  • 26、江科大stm32视频学习笔记——W25Q64简介

    一、W25Q64简介 1、W25Q64的内存空间结构:  一页256字节,4K(4096 字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048 个扇区。   2、W25Q64每页大小由256字节组成,每页的256字节用一次页编程指令即可完成。 3、擦除指令分别支持: 16页(1个扇区)、128页、256页、全片

    2024年01月22日
    浏览(53)
  • 11、江科大stm32视频学习笔记——输入捕获模式测频率、PWMI模式测频率占空比

    目录 一、知识点 1、IC(Input Capture)输入捕获 2、通用定时器结构 (1)输出比较的执行逻辑 (2)四个输入捕获和输出比较通道 (3)输入捕获的执行流程和输出比较的区别 (4)输入捕获的作用 (5)输入捕获通道 (6)PWMI模式:同时测量频率和占空比 (7)主从触发模式:

    2024年02月13日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包