STM32 定时器详细篇(基于HAL库)
l 16位的向上、向下、向上/向下(中心对齐)计数模式,支持自动重装载
l 16位的预分频器
l 每个定时器都有多个独立通道,每个通道可用于
* 输入捕获
* 输出比较
* PWM输出
* 单脉冲模式
l 高级定时器还可以产生互补输出
l 可以产生中断/DMA请求:
* 更新事件:计数器向上/向下溢出,计数器初始化(通过软或者内部/外部触发)
* 触发事件:计数器启动,停止,初始化或者有内部/外部触发计数
* 输入捕获
* 输出比较
一、定时器之计数模式
(一) 计数模式
向上计数
计数器从0向上计数(递增)到自动装载值,然后再次回到0开始计数,并产生一个计数溢出事件
向下计数
计数器从自动装载值向下计数(递减)到0,然后再次回到自动装载值开始计数,并产生一个计数器向下溢出事件
中央对齐模式(向上/向下计数)
计数器从0开始计数到自动装载值-1,并产生一个计数器溢出事件,然后再向下计数到0+1,并产生一个计数溢出事件,然后再向上计数。
(二)定时器的溢出时间计算
time=(ARR+1)*(PSC+1)/Tclk
ARR为自动装载值
PSC:预分频系数
Tclk:定时器的APB时钟,通常等于系统时钟
如:
tclk为72M
psc为7199
arr为4999
time=(4999+1)*(7199+1)/72 000 000 = 0.5s = 500ms
(三)CubeMX设置
这里需要注意的是你所需要使用的定时器是挂载在APB1还是APB2。相应的要调节他们时钟频率
选择
选择内部时钟
基础配置,这里配置的是1秒计数
l Prescaler (PSC- 16 bits value),预分频器(PSC- 16位值)
l Counter Mode,计数器模式:
up 向上
down 向下
Center Aligned mode 中心对齐模式
l Counter Period (AutoReload Register - 16 bits value),重装载值
l auto-reload preload,自动重装载开启
开启更新中断
中断优先级数字越低越高
(四)编程记录
中断开启
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
溢出事件回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM1){ HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//单独输出电平取反 }
}
开启中断
HAL_TIM_Base_Start_IT(&htim1);
二、 定时器之PWM
PWM即脉冲宽度调制,是一种模拟控制方式,通常用于LED的亮度调节。其实就是快速的高低电平变化让人感觉不出来。
(一)了解一下HZ的概念
1HZ表示1秒变化一个周期
在家用交流点中:
50HZ表示电流每秒钟来回变化50次,方向改变100次。
50HZ是50个周期,所以有50个正玄波形
这个图表示的是1HZ变化,1个周期,1个正玄波
50HZ表示每个周期的时间=1S/50=0.02S=20ms
单片机检测交流电可以200ms内没有检测到高电平,则表示无输入。
在计算机cpu等使用1khz=1000hz
在电磁波和机械波等,1Khz=1024hz
在PWM中
hz是频率的单位
1hz 表示PWM的周期是一秒
1Khz表示一秒钟有一千个周期,也就是周期是1ms
1KKhz、1Mhz表示一秒钟有100万个周期,也就是周期是1us
y秒=1/xHZ
1/1000=0.001S=1ms
1/1000000=0.000001S=1us
如果实现周期是100us
100us=0.0001S=1/0.0001= 10,000HZ
(二)PWM配置
ARR为自动装载值
CCRx 为捕获比较寄存器值
预分频系数决定了PWM的时钟速度
ARR的大小决定了PWM的周期
CRRx决定了输出有效信号的时间
有效信号:
高电平
低电平
PWM模式:
模式1,不管是向上还是向下计数,当计数值小于重装载值是输出有效电平。
模式2,不管是向上还是向下计数,当计数值小于重装载值是输出无效电平。
PWM周期计算
Fpwm = 100M / ((arr+1)*(psc+1))(单位:Hz)
Fpwm = 100M / (arr+1)/(psc+1)(单位:Hz)
arr 是计数值
psc 是预分频值
如:
3. 主频=100M
4. arr=100
5. psc=1000
100,000,000/100/1000=1000Hz
(三) CubeMX设置
设置定时器使用内部时钟
设置定时器的PWM通道1开启
STM32F103C8T6对应的PWM通道为PA8
设置基础参数
Prescaler,分配系数为36
Counter Period,重装载值为100
所以:
PWM的频率为:72 000 000/35/100=20 000 HZ(20KHZ),周期为 1/20000= 0.00005秒
PWM脉宽调制的最大值与重装载值一致,其范围为[0,100]
通道可以设置的值:
Mode,PWM的模式,可以选择模式1或模式2
CH Polarity,有效电平,可选高或底
(四)编程
初始化
//开启PWM输出
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
//设置默认的占空比值
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,10);
while循环改变值
HAL_Delay(30);//延时30ms //变量修改
if(i<100) i++;
else i=0; //设置占空比值
__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,i);
三、 定时器之输入捕获
通过检查定时器通道上的边沿信号,在边沿信号跳变(上升沿或者下降沿)的时候,将当前定时器的计数值存储到对应的捕获/比较寄存器里面,完成一次捕获。
通常用于检测高电平持续时间、低电平持续时间、两次下降沿的持续时间、两次上升沿的持续时间
滤波器:
里可以设置以什么频率采集多少次有效电平才说明边沿触发成功,如设置的是上升沿触发,当上升沿发生时,滤波器或以fDTS的频率采集ICF设置的次数,每次检测是否是高电平,这样可以防止误触发所带来的计算干扰。
边沿检测器:
设置捕获的触发边沿,可以设置上升沿或下降沿
通道选择
通过寄存器可以设置其它通道输入的值到该通道上
如通道1和通道2都可以映射到IC1,但通常是通道1是IC1,通道2是IC2,每个独立一对一映射,互不干扰。
分频器:
每2个事件触发一次捕获,如上升沿捕获时,连续获取到两个上升沿后才会触发计数
每4个事件触发一次捕获
每8个事件触发一次捕获
(一) CubeMX设置
开启TIM4的通道1作为输入捕获通道,对应是PB6引脚
Internal Clock表示内部时钟
input capture direct mode 表示输入捕获
根据硬件连接,这里设置为上拉
开启中断
基础配置
时钟:72 000 000 /72 = 1 000 000 HZ= 1MHZ,所以计数一次为1us
最大计数值为65536,约为65ms
prolarity selection 为触发计数边沿,下降沿
(二)编程
测量低电平的持续时间,先下降沿后上升沿,记录计数值,最终输出us单位。
通用函数
//变量存储
typedef struct
{
uint8_t flg; //0为未开始,1已经开始,2为结束
uint16_t num;//计数值
uint16_t num_period;//溢出次数
}COUNT_TEMP; COUNT_TEMP count_temp={0}; //捕获中断发送时的回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
//判断定时器2
if(TIM2 == htim->Instance){
if ( count_temp.flg == 0 )
{
// 清零定时器计数
__HAL_TIM_SET_COUNTER(htim,0);
//设置上升沿触发
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
count_temp .flg = 1; //设置已经开始
count_temp .num_period = 0; //溢出计数清零
count_temp .num = 0; //计数清零
}
else
{
// 获取定时器计数值
count_temp .num = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
//设置下降沿触发
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING);
count_temp .flg = 2;
}
}
} //定时器溢出回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(TIM2 == htim->Instance){
//每次溢出时间为65536us
if(count_temp.flg==1)//还未成功捕获
{
if(count_temp.num_period==0XFFFF)//电平太长了
{
count_temp.flg=2; //标记成功捕获了一次
count_temp .num=0XFFFF;
}else count_temp .num_period ++;
}
}
}
初始化
//开启定时器溢出中断
HAL_TIM_Base_Start_IT(&htim2);
//开启输入捕获中断,设置下降沿触发中断
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //启动输入捕获
while循环
//等待测量完毕
if(count_temp.flg == 2 )
{
//计数计数值,0xFFFF为最大计数
uint32_t ulTime = (uint32_t)count_temp .num_period * 0xFFFF + count_temp .num;
//输出测量的值
printf ( "低电平时间:%d us\n",ulTime);
count_temp .flg = 0;
}
原文地址:https://www.cnblogs.com/dongxiaodong/p/14351398.html
找作者:https://space.bilibili.com/162091292
STM32 定时器详细篇(基于HAL库)的更多相关文章
- STM32 GPIO输入输出(基于HAL库)
一.基础认识 GPIO全名为General Purpose Input Output,即通用输入输出.有时候简称为"IO口".通用,说明它是常见的.输入输出,就是说既能当输入口使用 ...
- Keil MDK STM32系列(七) STM32F4基于HAL的PWM和定时器
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)
说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...
- 【STM32H7教程】第32章 STM32H7的TIM定时器基础知识和HAL库API
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第32章 STM32H7的TIM定时器基础知识和H ...
- Keil MDK STM32系列(八) STM32F4基于HAL的PWM和定时器输出音频
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- STM32串口接收中断——基于HAL库
写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...
- 基于HAL库的STM32的DSP库详解(附FFT应用)
1 . 建立工程,生成代码时选择包含所有库. 2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...
- STM32标准外设库、 HAL库、LL库
工作以来一直使用ST的STM32系列芯片,ST为开发者提供了非常方便的开发库.到目前为止,有标准外设库(STD库).HAL库.LL库 三种.前两者都是常用的库,后面的LL库是ST最近才添加,目前支持的 ...
随机推荐
- 查看权限详情 将部门大类单据整合,将子类单据id去重合并
/** * 查看权限详情 * @param id 部门id * @return */ @GetMapping("getListInfo") public R getDetail(S ...
- Axis2开发webservice详解
Axis2开发webservice详解 标签: javawebserviceAxis2 2015-08-10 10:58 1827人阅读 评论(0) 收藏 举报 分类: JAVA(275) 服务器 ...
- SpringBoot默认首页配置
@Configuration public class DefaultView extends WebMvcConfigurerAdapter { @Override public void addV ...
- 柔性分布式事务关于异步解决方案MQ版
上述思想本质是 二阶段提交变体 1,2是prepare阶段 4是commit阶段 存在问题 MQ提供半消息支持 生产者提供消息回查功能 发送方多次半消息到MQSERVER 消费方会多次消费消息 生产 ...
- 记一次MAVEN依赖事故
笔者昨天遇到的背景是这样的 MAVEN A模块有一个子模块 需要依赖B模块下的一个子模块 我在B项目内通过mvn deploy上传子模块 但之后在A模块引用 怎么引用都不行 提示 org.a ...
- reactor模式前序(二):NIO WEB服务器设计
前文介绍了传统IO的WEB经典服务器 reactor模式前序:传统IO的WEB服务器设计 下面看看JAVA NIO的WEB服务器设计 NIO是基于事件驱动的,对于NIO来说,重要组件是Selector ...
- golang语法笔记
开始微服务,那就先温习下golang语法吧; golang变量类型 1. 整形 Go %b 表示为二进制 %c 该值对应的unicode码值 %d 表示为十进制 %o 表示为八 ...
- vim_command
vi 打开vi空白面板 vi filename 以编辑模式打开文件.如果参数为已有文件,在vi中打开:如果参数为新文件名,在vi退出时提示用户保存编辑内容 vi -R filename 以只读模式打开 ...
- 如何制作sitemaps网站地图
如何制作sitemaps网站地图 1.0 前言 1.1 xml格式 1.2 常见问题 本文资料来源于网站 1.0 前言 Sitemap 可方便网站管理员通知搜索引擎他们网站上有哪些可供抓取的网页.最简 ...
- 【Java基础】Java11 新特性
Java11 新特性 新增字符串处理方法 新增方法: 判断字符串是否为空白 " ".isBlank(); // true 去除首尾空白 " Javastack " ...