江协科技STM32学习- P16 实验-TIM输出比较(PWD驱动LED呼吸灯,舵机,直流电机)

     🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External clock 时钟源 External clock 
外部时钟源 ETR:External clock mode 1外部时钟源 Extern Input pin 时钟模式1
外部时钟源 ETR:External clock mode 2外部时钟源 Extern Trigger 时钟模式2
外部时钟源 ITRx:Internal trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:external input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。


定时器共四个部分,分为八个小节笔记。本小节为第一部分第一节。

🌳在第一部分,是定时器的基本定时的功能:定时中断功能、内外时钟源选择

🌳在第二部分,是定时器的输出比较功能,最常见的用途是产生PWM波形,用于驱动电机等设备

🌳在第三部分,是定时器的输入捕获功能和主从触发模式,来实现测量方波频率

🌳在第四部分,是定时器的编码器接口,能够更加方便读取正交编码器的输出波形,编码电机测速


1. 🚢TIM定时器输出比较功能实现PWM

TIM定时器输出比较功能实现PWM,在 PWM_Init() 函数中按照下面的步骤初始化使用到的 TIM定时器外设和GPIO外设。

  • 🌾1.RCC开启时钟,把要用的TIM外设和GPIO外设的时钟打
  • 🌾2.配置时基单元,包括时钟源选择,预分频器,自动重装载器,时基单元就配置好了
  • 🌾3.配置输出比较单元,包括CCR的值,输出比较模式,极性选择,输出使能这些参数
  • 🌾4.初始化GPIO,把PWM的OC输出GPIO引脚配置为复用输出模式
  • 🌾5.运行控制,启动计数器

STM32 Tim定时器库函数 stm32f10x_tim.h 中和定时器比较输出(OC:Outpurt Comapre)功能相关的一些库函数。

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);
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
TIM定时器输出比较函数4个输出通道OC1, OC2, OC3, OC4的初始化函数
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);输出比较函数初始化结构体赋一个默认初始值
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);
输出比较,强制输出模式配置,通道OC1,OC2,OC3,OC4
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);
清除比较输出通道OC1,OC2,OC3,OC4的 Reference输出
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);
比较输出通道 OC1,OC2,OC3的互补极性输出,高级定时器的前三个通道各自有2个互补输出通道,所以是 OC1, OC1N,OC2,OC2N,OC3,OC3N
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_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);输出比较控制器的工作模式,输出比较控制器有8中工作模式
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);
输出比较寄存器值设置

TIM_OCMode 输出比较模式中的选择

TIM_OCMode_Timing//冻结模式
TIM_OCMode_Active//相等时置有效电平
TIM_OCMode_Inactive//相等时置无效电平
TIM_OCMode_Toggle//相等时电平翻转
TIM_OCMode_PWM1//PWM模式1,主要用
TIM_OCMode_PWM2//PWM模式2
TIM_ForcedAction_Active//强制输出模式,初始化时不使用
TIM_ForcedAction_InActive

2. 🚢实验1,TIM定时器输出比较-PWM驱动LED呼吸灯

实验1,TIM定时器输出比较-PWM驱动LED呼吸灯,STM32开发板面包板器件接线图如下所示

源码

PWM.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"void PWM_Init(void)
{//1. RCC开启时钟,把要用的TIM外设和GPIO外设的时钟打开//2.配置时基单元,包括时钟源选择,预分频器,自动重装载器,时基单元就配置好了//3.配置输出比较单元,包括CCR的值,输出比较模式,极性选择,输出使能这些参数//4.初始化GPIO,把PWM的OC输出GPIO引脚配置为复用输出模式//5.运行控制,启动计数器//Setp 1.//RCC APB1的外设时钟控制,因为TIM2在STM32的APB1外设总线上RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//GPIO初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;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);//AFIO
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
//	
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//	//Setp 2.//选择时基单元的时钟,使用内部RCC时钟 CLK_INT (Clock_Internal)TIM_InternalClockConfig(TIM2);//Setp 3.//配置时基单元TIM_TimeBaseInitTypeDef TimeBaseInitStruct;TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;		//时钟信号滤波使用,滤波的采样频率,采样点数TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;	//计数器向上计数TimeBaseInitStruct.TIM_Period = 100 - 1;					//ARR, Auto-Reload Register 自动重装载寄存器的值,记得需要减一TimeBaseInitStruct.TIM_Prescaler = 720 - 1;					//PSC, 预分频器的值,记得需要减一TimeBaseInitStruct.TIM_RepetitionCounter = 0;				//重复计数器的值	TIM_TimeBaseInit(TIM2, &TimeBaseInitStruct);//输出表通道1TIM_OCInitTypeDef TIM_OCInitStruct;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 = 10;		//CCRTIM_OC1Init(TIM2, &TIM_OCInitStruct);//输出PWM目标,PWM频率1KHz,PWM占空比 50%,PWM分辨率 1%//PWM频率=72MHz/(PSC+1)(ARR+1) =>PSC 720//PWM占空比=CCR/(ARR+1) ==>CRR 50//PWM分辨率=1/(ARR+1)  ==>ARR 100////Setp 6.//定时器启动TIM_Cmd(TIM2, ENABLE);}void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare);
}

PWM.h

#ifndef __PWM_H__
#define __PWM_H__void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);#endif 

main.c

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "PWM.h"
#include "Delay.h"uint8_t KeyNum = 0;int main(int argc, char *argv[])
{	int i = 0;OLED_Init();OLED_ShowString(1, 1, "PWM Timer OC");PWM_Init();while(1){for(i=0; i<=100; i++){PWM_SetCompare1(i);Delay_ms(12);}for(i=0; i<=100; i++){PWM_SetCompare1(100-i);Delay_ms(12);}}return 1;
}

2.1实验现象

使用STM32 TIM2通用定时器输出比较通道1,输出PWM 频率为 1KHz,PWM占空比为50%,PWM分辨率为 1%,的实验结果如下。

使用淘宝购买的19块钱的24MHz逻辑分析仪看一下STM32定时器比较输出功能输出的 PWM 波形,如下分别是 PWM 10%占空比,50%占空比,90%占空比。

2.2 STM32 外设功能重映射到其它引脚

STM32引脚功能定义表里在“默认复用功能”里可以看到 PA2 引脚默认复用为 "UART2_TX/ADC12_IN2/TIM2_CH3" 功能,如果想同时使用 PA2引脚的 "UART2_TX" UART 串口功能和定时器TIM2_CH3通道功能,就会发生冲突,此时,可以看下STM32引脚功能定义表的“重定义功能”,看是否可以将 "TIM2_CH3"功能重映射(Remaping)到其它引脚上,也就是AFIO(Alternative Function I/O)

类似的,如下代码将 PA0 引脚上的 TIM2_CH1 功能,查看STM32引脚功能定义表,可以重映射到PA15引脚,引脚功能重映射需要使用到AFIO(Alternative Function I/O)。重映射映射(功能服用)PA0 TIM2_CH1功能的代码片段如下。

	//GPIO初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);//AFIORCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  • 🌾RCC启用AFIO外设时钟,因为STM32外设功能重映射需要使用到AFIO外设,所以要启用AFIO外设时钟。
  • GPIO_PinRemapConfig() 重映射 PA0 的 TIM2_CH1 功能
  •  GPIO_PinRemapConfig()重映射关闭PA15原来的 JTAG功能复用。
  • 修改GPIO PA15的工作模式为 GPIO 复用推挽输出。

3.🚢实验2,PWM驱动舵机

驱动舵机的关键就是输出一个下面一样的PWM波形,只要波形能够按照如下规定,准确的输出,那驱动舵机就非常简单了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147037.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

如何访问字符串中某个字符

在Java中&#xff0c;你可以使用字符串的charAt(int index)方法来查看字符串中第index个位置的字符。index是从0开始的&#xff0c;也就是说&#xff0c;字符串的第一个字符的索引是0&#xff0c;第二个字符的索引是1&#xff0c;以此类推。如果索引超出了字符串的长度&#xf…

IO多路转接:select、poll、epoll

目录 非阻塞读取 fcntl函数 I/O多路转接之select select函数 fd_set结构 select的模拟实现 select的优缺点 I/O多路转接之poll poll函数 struct pollfd结构体 poll函数的使用示例 poll的模拟实现 poll的优缺点 I/O多路转接之epoll epoll的三个系统调用 epoll的…

当你在Linux系统中使用MySQL命令行工具查询数据库时,如果中文显示为问号(?)或其他乱码,简单解决办法。(2)

文章目录 1、问题出现2、解决办法 1、问题出现 2、解决办法 mysql -u [username] -p --default-character-setutf8 [database_name]rootab66508d9441:/# mysql -uroot -p123456 --default-character-setutf8 tingshu_album mysql: [Warning] Using a password on the command …

Redis 字符串类型的典型应用场景

目录 1. 缓存功能 2. 计数功能 3. 共享会话&#xff08;Session&#xff09; 4. 手机验证码 前言 这里将详细介绍 Redis 字符串类型在实际开发中的几个典型应用场景&#xff0c;并提供相应的伪代码示例。 1. 缓存功能 场景描述 在许多Web应用中&#xff0c;数据通常需要…

使用AVL树实现Map

一、数组在裂变扩容时可能会出现环、在数组元素转为链表之后选择尾插法插入节点、数组到链表到AVL到RBT的转换 1、数组在裂变扩容时链表中的节点计算出来的位置可能也会发生变化&#xff0c;在多线程情况下调整节点位置可能会出现环。 2、数组中的数组元素转为链表后插入新节点…

在大模型训练中,为什么GPU 通常比 CPU 更重要

在大模型训练中&#xff0c;GPU 通常比 CPU 更重要&#xff0c;原因主要有以下几点&#xff1a; 一、并行计算能力 GPU 拥有强大的并行计算能力。在大模型训练中&#xff0c;需要处理海量的数据和复杂的计算任务。例如&#xff0c;深度学习模型中的矩阵运算、卷积运算等&…

13. 了解人工智能可能存在的偏见

这篇文章没有太多技术和代码细节&#xff0c;更多的是作为一份有趣的报告。 这里没有任何模型会被训练。 这篇文章也为生成式人工智能导论课程中 HW8: Safety Issues of Generative AI 提供中文引导。 代码文件下载 文章目录 为什么人工智能存在偏见&#xff1f;动手试试加载模…

算法_BFS解决多源最短路问题---持续更新

文章目录 前言引入矩阵题目要求题目解析代码如下 飞地的数量题目要求题目解析代码如下 地图中的最高点题目要求题目解析代码如下 地图分析题目要求题目解析代码如下 前言 本文将会向你介绍有关宽度优先搜索&#xff08;BFS&#xff09;解决多源最短路问题的相关题型&#xff1…

故障诊断│GWO-DBN灰狼算法优化深度置信网络故障诊断

1.引言 随着人工智能技术的快速发展&#xff0c;深度学习已经成为解决复杂问题的热门方法之一。深度置信网络&#xff08;DBN&#xff09;作为深度学习中应用比较广泛的一种算法&#xff0c;被广泛应用于分类和回归预测等问题中。然而&#xff0c;DBN的训练过程通常需要大量的…

机器人速度雅可比矩阵(机器人动力学)

博途PLC矩阵求逆 矩阵求逆 博图SCL_博图矩阵运算-CSDN博客文章浏览阅读839次。本文介绍如何用C语言实现矩阵求逆的过程,详细解析了相关代码,适合线性代数和编程爱好者学习。https://rxxw-control.blog.csdn.net/article/details/122367883 1、二自由度平面关节机器人速度雅…

项目第十二弹:功能联调

项目第十二弹&#xff1a;功能联调 一、发布订阅功能测试1.生产者2.消费者3.演示4.持久化信息查看1.消息2.SQLite3数据库 二、持久化恢复测试1.代码2.gc3.演示 三、虚拟机和信道隔离测试1.责任划分2.如何测试3.生产者4.消费者5.演示 一、发布订阅功能测试 我们直接上TOPIC交换…

MySQL中的逻辑条件

逻辑条件组合两个比较条件的结果来产生一个基于这些条件的单个的结果&#xff0c;或者逆转一个单个条件的结果。当所有条件的结果为真时&#xff0c;返回行。 SQL的三个逻辑运算符是&#xff1a; AND、OR、NOT 可以在WHERE子句中用AND和OR运算符使用多个条件。 示例一&#…

惊爆!高通要收购英特尔,巨头也会被时代抛弃!

今天看到的外媒消息&#xff0c;高通要收购英特尔&#xff0c;看到消息的时候&#xff0c;其实&#xff0c;还是挺吃惊的。 高通是移动芯片的王者&#xff0c;英特尔是 PC 芯片的王者。当然了&#xff0c;英特尔这个可能需要再加上两个字&#xff1a;曾经的 PC 芯片王者。 其实…

植物大战僵尸【源代码分享+核心思路讲解】

植物大战僵尸已经正式完结&#xff0c;今天和大家分享一下&#xff0c;话不多说&#xff0c;直接上链接&#xff01;&#xff01;&#xff01;&#xff08;如果大家在运行这个游戏遇到了问题或者bug&#xff0c;那么请私我谢谢&#xff09; 大家写的时候可以参考一下我的代码思…

在VMware16中安装Windows 10:完整教程

在VMware中安装Windows 10&#xff1a;完整教程 1.安装环境准备2.创建虚拟机 1.安装环境准备 1.虚拟机: VMware-workstation-full-16.2.2-19200509 2.系统镜像:win10 2.创建虚拟机 1.自定义 2.下一步 3.稍后安装系统 3.默认下一步 4.虚拟机取名和选择存放路径(按需更改…

利士策分享,江西新余悲剧背后的深思:安全与责任的重构

利士策分享&#xff0c;江西新余悲剧背后的深思&#xff1a;安全与责任的重构 在这个信息瞬息万变的时代&#xff0c;每一次突发事件都能迅速触动社会的神经&#xff0c; 而江西新余近期发生的悲剧&#xff0c;更是让我们在悲痛之余&#xff0c;不得不深刻反思安全管理与社会…

AVL树与红黑树

目录 AVL树 AVL树节点的定义 AVL树的插入 AVL树的旋转 右单旋 左单旋 左右双旋 右左双旋 AVL树的验证 AVL树的性能 红黑树 红黑树的性质 红黑树节点的定义 红黑树结构 红黑树的插入操作 按照二叉搜索的树规则插入新节点 检测新节点插入后&#xff0c;红黑树的性…

升级你的HarmonyOS体验:一窥功能引导与拖拽交换的独家技巧

文章目录 前言项目目录结构开发流程主要步骤讲解关键配置Index.ets 页面讲解高光组件相关HeaderApp 总结 前言 在当今的移动应用开发领域&#xff0c;为了提供更加友好和直观的用户体验&#xff0c;开发者们通常会集成多种交互功能来增强应用的互动性和易用性。在这些功能中&a…

【机器学习】12-决策树1——概念、特征选择

机器学习10-决策树1 学习样本的特征&#xff0c;将样本划分到不同的类别&#xff08;分类问题&#xff09;或预测连续的数值&#xff08;回归问题&#xff09;。 选择特征&#xff0c;划分数据集&#xff0c;划分完成形成模型&#xff08;树结构&#xff09;&#xff0c;一个…

JavaSE——多线程基础

概述 现代操作系统&#xff08;Windows&#xff0c;macOS&#xff0c;Linux&#xff09;都可以执行多任务。多任务就是同时允许多个任务。例如&#xff1a;播放音乐的同时&#xff0c;浏览器可以进行文件下载&#xff0c;同时可以进行QQ消息的收发。 CPU执行代码都是一条一条顺…