TIM—通用定时器高级定时器
通用/高级定时器的功能
在基本定时器功能的基础上新增功能:
通用定时器有4个独立通道,且每个通道都可以用于下面功能。
(1)输入捕获:测量输入信号的周期和占空比等。
(2)输出比较:产生输出特定的波形(根据自己需要设置)。
(3)输出PWM。
(4)单脉冲模式.
(5)级联。(一个定时器的溢出事件可以使能下一个定时器的计数器开始计数)
(6)可以触发DAC、ADC。
(7)支持编码器和霍尔传感器电路。
高级控制定时器比通用定时器增加了可编程死区互补输出、重复计数器、带刹车 (断路) 功能,这些功能都是针对工业电机控制方面。
框图
时钟源
• 内部时钟源 CK_INT
• 外部时钟模式 1:外部输入引脚 TIx(x=1,2,3,4)
• 外部时钟模式 2:外部触发输入 ETR
• 内部触发输入 (ITRx)
时基单元
见基本定时器章节
输入捕获
输入捕获可以对输入的信号的上升沿、下降沿或者双边沿进行捕获,常用的有测量输入信号的脉
宽,和测量 PWM 输入信号的频率和占空比这两种。
输入捕获的大概的原理就是,当捕获到信号的跳变沿的时候,把计数器 CNT 的值锁存到捕获寄
存器 CCR 中,把前后两次捕获到的 CCR 寄存器中的值相减,就可以算出脉宽或者频率。如果捕
获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。
输出比较(最常用)
输出比较就是通过定时器的外部引脚对外输出控制信号,有冻结、将通道 X(x=1,2,3,4)设置为
匹配时输出有效电平、将通道 X 设置为匹配时输出无效电平、翻转、强制变为无效电平、强制变
为有效电平、 PWM1 和 PWM2 这八种模式,具体使用哪种模式由寄存器 CCMRx 的位OCxM[2:0]配置。其中 PWM 模式是输出比较中的特例,使用的也最多。
输出比较
输出比较模式总共有 8 种,具体的由寄存器 CCMRx 的位 OCxM[2:0] 配置。
以 PWM1 模式来讲解,以计数器 CNT 计数的方向不同还分为边沿对齐模式和中心对齐模式。 PWM 信号主要都是用来控制电机,一般的电机控制用的都是边沿对齐模式, FOC 电机一般用中心对齐模式。日常开发中最常使用的模式为 PWM1 模式的向上计数模式,因此本文着重介绍该
模式,对于其他模式不做介绍。
在 PWM1 模式 1 向上计数模式中(极性不反转的情况下),当 CNT<CCR 时,输出比较通道对应输出有效电平,即高电平1,当 CNT>=CCR 时,输出比较通道输出无效电平,即低电平0。
PWM
PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域
PWM 中有三个重要参数:频率、占空比(高电平时长占整个周期信号时长的比例)、分辨率(占空比可调精度)。
频率 Freq: Freq = CK _ PSC /(PSC +1) /(ARR +1)
PWM 占空比: Duty = CCR /(ARR +1)
PWM 分辨率: Reso =1/(ARR +1)
CK_PSC 为技术单元时钟源频率, PSC 为分频因子, ARR 为目标计数值, CCR 为 CCR寄存值
输入捕获
IC(Input Capture)输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道 可配置为PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
频率测量方法
输入捕获通道
输入捕获基本结构
PWMI基本结构
测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式,该模式是输入捕获的特例,只
能使用通道 1 和通道 2,通道 3 和通道 4 使用不了。与上面那种只使用一个捕获寄存器测量脉宽
和频率的方法相比, PWM 输入模式需要占用两个捕获寄存器
当使用 PWM 输入模式的时候,因为一个输入通道 (TIx) 会占用两个捕获通道 (ICx),所以一个定
时器在使用 PWM 输入的时候最多只能使用两个输入通道 (TIx)。
PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,一路是
TI1FP1,另外一路是 TI1FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还
是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是
周期,另一路就是对应占空比。
输出比较应用(PWM驱动直流电机)
初始化PWM,设置 PWM频率为100hz,分辨率为0.1%,占空比由TIM_SetComparex()函数配置(x可为1,2,3,4)
#include "pwm.h"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_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_Prescaler = 720-1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period = 1000-1;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;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; //CCRTIM_OC3Init(TIM2,&TIM_OCInitStructure);TIM_OC4Init(TIM2,&TIM_OCInitStructure);TIM_Cmd(TIM2,ENABLE);}void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2,Compare);
}void PWM_SetCompare4(uint16_t Compare)
{TIM_SetCompare4(TIM2,Compare);
}void usart_PWM(uint16_t Compare1,uint16_t Compare2)
{TIM_SetCompare3(TIM2,Compare1);TIM_SetCompare4(TIM2,Compare2);
}
定义 pwm.h文件
#ifndef _PWM_H_
#define _PWM_H_
#include "stm32f10x.h"
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);
void PWM_SetCompare4(uint16_t Compare);
void usart_PWM(uint16_t Compare1,uint16_t Compare2);
#endif
初始化串口中断,并重定义printf()和scanf()函数
#include "usart.h"static void NVIC_Configuration(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStruct.NVIC_IRQChannelSubPriority =1 ;NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE ;NVIC_Init(&NVIC_InitStruct);
}void usart_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;/*TX*/GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);/*RX*/GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate = 9600;USART_InitStruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None ;USART_InitStruct.USART_Mode =USART_Mode_Rx | USART_Mode_Tx ;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART_InitStruct);NVIC_Configuration();USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);
}
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口 */USART_SendData(USART1, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); return (ch);
}int fgetc(FILE *f)
{/* 等待串口输入数据 */while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(USART1);
}
在接收中断中设置直流电机占空比 ,并通过上位机发送指令
void USART1_IRQHandler(void)
{uint8_t ch;ch = getchar();printf( "ch=%c\n",ch );switch(ch){case '1': usart_PWM(0,200);break;case '2': usart_PWM(0,500);break;case '3': usart_PWM(0,1000);break;default: usart_PWM(1000,1000);break;}
}
相关文章:

TIM—通用定时器高级定时器
通用/高级定时器的功能 在基本定时器功能的基础上新增功能: 通用定时器有4个独立通道,且每个通道都可以用于下面功能。 (1)输入捕获:测量输入信号的周期和占空比等。 (2)输出比较:产…...

【数据结构与算法(C语言)】循环队列图解
目录 1. 前言1.1 普通循环队列假溢出1.1.1 初始化队列1.1.2 插满队列1.1.3 删除元素后,再插入元素 1.2 循环队列1.2.1 插入元素,队列已满1.2.2 将元素J1、J2出列,循环队列又空出两个空间1.2.3 元素J6可以继续入列 2. 存储结构和函数说明2.1 队…...
私域流量转化不济的原因
你是不是也曾感到私域流量的转化一直不如意?让我来告诉你,这六大问题是为什么,以及如何轻松解决它们,提升你的私域流量转化率! 1. 问题:目标不明确 你是否常常感到茫然,不知道私域流量应该有何目…...

百万上下文RAG,Agent还能这么玩
❝ 在AI技术飞速发展的今天,我们见证了许多令人惊叹的突破。最近,Qwen2模型的开源引起了广泛的关注,它不仅展示了超越闭源模型的能力,还带来了一个全新的框架——Qwen-Agent。 Qwen-Agent的设计思路虽然与LangChain相似࿰…...

【后端开发】服务开发场景之高可用(冗余设计,服务限流,降级熔断,超时重试,性能测试)
【后端开发】服务开发场景之高可用(冗余设计,服务限流,降级熔断,超时重试,性能测试) 文章目录 序:如何设计一个高可用的系统?可用性的判断指标是什么?哪些情况会导致系统…...

在 Selenium 中更改 User-Agent | 步骤与最佳实践
在 Selenium 中更改 User Agent 是许多网页抓取任务中的关键步骤。它有助于将自动化脚本伪装成常规浏览器,从而避免被网站检测到。本指南将带您了解如何在 Selenium 中更改 Google Chrome 的 User Agent,并提供最佳实践以确保您的网页抓取任务顺利进行。…...

2024酒店IPTV云桌面系统建设方案
Hello大家好,我是点量小芹,这一年多的时间一直在分享实时云渲染像素流相关的内容,今天和大家聊聊酒店IPTV云桌面电视系统解决方案,或者有的朋友也会称之为IPTV服务器。熟悉小芹的朋友知道,IPTV软件系统是我们一直在推的…...
java Thrift TThreadPoolServer 多个processor 的实现
当我们使用Thrift 通信的时候,服务端有时候需要注册多个类,去实现通信,这时候我们就不能再使用单一Processor的方式,就要使用多个Processor,那么如何去实现呢? 多个Process 服务端 public static void m…...

失眠焦虑的解脱之道:找回内心的平静
🍃 在这个快节奏的时代,失眠与焦虑似乎成了许多人的隐形敌人。每当夜幕降临,它们便悄悄潜入心底,扰乱我们的思绪,让宁静的夜晚变得无比漫长。然而,生活总有办法让我们找回内心的平静,只需稍作调…...

OLED柔性屏的显示效果如何
OLED柔性屏的显示效果非常出色,具有多方面的优势。以下是关于OLED柔性屏显示效果的详细分析: 色彩表现:OLED柔性屏的每个像素都可以独立发光,因此色彩准确性极高。黑色呈现得非常深邃,而亮部则展现出鲜明而生动的细节。…...
百货商城优选 伊利牛奶推出全国首款减甲烷环保学生奶
近日,伊利集团受邀参加在全国首个“国际首脑峰会零碳场馆”召开的“降碳增产科技助力奶业绿色高质量发展”首款低碳饲料创新大会。会上,伊利宣布将推出全国首款减甲烷环保学生牛奶——伊利QQ星学生纯牛奶,进一步将可持续发展落到实处…...

Fluid 1.0 版发布,打通云原生高效数据使用的“最后一公里”
作者:顾荣 前言 得益于云原生技术在资源成本集约、部署运维便捷、算力弹性灵活方面的优势,越来越多企业和开发者将数据密集型应用,特别是 AI 和大数据领域应用,运行于云原生环境中。然而,云原生计算与存储分离架构虽…...
软件测试--第十一章 设计和维护测试用例
1.单选题 (2分) 下面有关测试设计的叙述,说法不正确的是( )。 A 测试用例的设计是一项技术性强.智力密集型的活动 B 在开展测试用例设计前,必须将测试需求进行详细展开 C 在一般的测试组织内,测试用例的评审可能不是正式的评审会 D 在测试用例设计时,只设计覆盖正常流程和操…...
前端只允许一次函数调用
如果你正在进行前端开发,并且只想允许一次函数调用,你可以使用JavaScript的闭包结构创建一个只能被调用一次的函数。这样的函数有时被称为单次调用函数(“one-time call” functions)或一次性函数(“once” functions&…...

visdom使用时所遇的问题及解决方法
最近在用visdom进行可视化的过程中,虽然可有效的避免主机拒绝访问(该问题的解决方法,请参考深度学习可视化工具visdom使用-CSDN博客)即在终端输入python -m visom.server 1.训练过程中visdom出现ValueError: too many file descr…...
密封类(sealed class)
在 Kotlin 中,密封类(sealed class)是一种受限的类层次结构,允许您定义一个封闭的类层次结构,其中类的所有可能子类都已知并且位于同一文件中。密封类的主要作用是提供类型安全的受限层次结构,使得 when 表…...

私域引流宝PHP源码 以及搭建教程
私域引流宝PHP源码 以及搭建教程...

磁盘管理 以及磁盘的分区 详细版
磁盘管理 track:磁道,就是磁盘上同心圆,从外向里,依次1号、2号磁道sector:扇区,将磁盘分成一个一个扇形区域,每个扇区大小是512字节,从外向里,依次是1号扇区、2号扇区cylinder&…...

加码多肤色影像技术 这是传音找到的“出海利器“?
全球化时代,市场竞争愈演愈烈,产品差异化已然成为了企业脱颖而出的关键。在黄、白肤色长期占据人像摄影主赛道的背景下,传音就凭借独一无二的多肤色影像技术走出非洲,走向了更广阔的新兴市场。 聚焦深肤色人群拍照痛点,…...
C++方法封装成dll及C#调用示例
1,编译生成dll时可能出现错误,解决办法:pch.h文件头部,添加声明 #define _CRT_SECURE_NO_WARNINGS 2, c头文件声明 extern "C" __declspec(dllexport) char* getvalue(const char * param1, const char * param2); 3, c方法实现…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...