STM32定时器学习---基本定时器
STM32F1系列的产品,除了互联网产品外,工作8个,3种定时器,其中一种就是基本定时器。那么STM32单片机的基本定时器如何操作以及编程呢?
下面我们就来详细的了解一下
STM32F1系列的产品,除了互联型产品外,工位8个定时器
TIM6、TIM7:基本定时器
TIM2/3/4/5:通用定时器
TIM1、TIM8:高级定时器
三种定时器的区别:
基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。简单的说两个定时器是从0计数到N(由自动装载计数器来确定N的具体值),然后复位回0 重新计数。每次复位到0 的时候可以产生对应的中断信号,或者产生DMA 请求,还可以触发DAC 同步电路。不过这次笔记不讨论触发DAC 的问题,等写到DAC 的使用时在讲解如何用这两定时器驱动DAC。
基本定时器TIM6和TIM7挂载在APB1总线上,在使用之前需要先使能对应的时钟信号。对应的语句如下:
[cpp] view plaincopy
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
APB1 总线上的时钟信号在进入定时器之后第一件事情是被预分频器TIMx_PSC分频。程序中随时都可以更改TIMx_PSC的值,但是TIMx_PSC是有缓冲的,只有发生了更新事件时新的预分频值才会生效。
另外有一点必须要特别注意:如果我们想对 CK_PSC 时钟信号N 分频的话,TIMx_PSC 中应该写入 M - 1,而不是 M。
对应的语句如下:
[cpp] view plaincopy
TIMx->PSC = M - 1;
如果我们希望立刻更新预分频器也是有办法的,那就是软件触发一次更新事件。TIM6和TIM7有个事件产生寄存器(TIMx_EGR) 就是起这个作用的。TIMx_EGR 只有最低位有用,称之为 UG 位,向这一位写入 1 则产生更新事件,定时器的计数器被归零。
对应的语句如下:
[cpp] view plaincopy
TIMx->EGR = 0x0001;
自动重装载寄存器TIMx_ARR决定了CNT 计数器最高记到多少就会归零。自动重装载寄存器也是带缓存的。如果TIMx_CR1寄存器中的自动重装载预加载使能位(ARPE)为0,则写入自动重装载寄存器的值立即起作用。如果ARPE = 1,则要等到发生了更新事件后才会起作用。举例来说,当前自动重装载寄存器的值为20000,CNT 计数器的值为1000,ARPE = 1,这时我们向自动重装载寄存器写个 5000,CNT 计数器记到 5000 时并不会归零,它还要继续直到记到20000然后归零,在归零的同时产生计数器溢出事件,计数器溢出事件可以产生更新事件,之后自动重装载寄存器的值才真的变为5000了。
这里出现了两个事件:计数器溢出事件和更新事件。这两个实际是不同的。每次当计数器溢出时都会产生计数器溢出事件,但是不一定产生更新事件。
TIM6和TIM7控制寄存器1(TIMx_CR1) 有一位UDIS:禁止更新 (Update disable)位。
如果这位被设置为1,则计数器溢出事件不会产生更新事件。不产生更新事件则预分频器的系数不能被更新,自动重装载寄存器的值也可能不能更新(ARPE = 1)。
只是产生更新事件是没有用的,我们最终需要的是产生中断或DMA请求。这里先说中断的产生。
TIM6和TIM7 DMA/中断使能寄存器(TIMx_DIER) 有一位为UIE。只有这一位为1时才能产生更新中断。
对应的语句如下:
[cpp] view plaincopy
TIMx->DIER |= 0x0001;
TIM6和TIM7状态寄存器(TIMx_SR) 中也只有一位是有用的,位于这个寄存器的最低位,称之为UIF位。这一位为1 标志着产生了更新中断。什么时候这一位才能为1呢?简单的说就是产生更新事件这一位会被置位为1,不过也有特殊情况,我们知道有两种情况会产生更新事件:计数器溢出事件和 UG=1。如果TIMx_CR1的URS位被设为了1,则UG=1 产生的更新事件不会将UIF位置位1。
一般来说我们都不希望UG=1时产生中断,所以多数时间我们会设置URS位为1。
对应的语句如下:
[cpp] view plaincopy
TIMx->CR1 |= 0x0004;
下面是一个例子程序,使用TIM6,产生一个5Hz的定时中断。时钟频率为72MHz。
[cpp] view plaincopy
void TIM6_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
TIM6->PSC = 7200 - 1; // 分频之后的时钟频率为10KHz
TIM6->ARR = 2000 - 1; // 5Hz 定时频率
TIM6->CR1 = 0x0004 + 0x0001; // URS = 1 CEN = 1
TIM6->DIER = 0x0001; // 使能更新中断
}
void TIM6_IRQHandler(void)
{
LED_Flash(GPIO_LED2);
TIM6->SR=0x0000;//清标志位
}
还可以完全用STM32F10x Standard Peripherals Firmware Library 来写这个程序。下面用TIM7 实现类似的功能。
[cpp] view plaincopy
void TIM7_Init(void)
{
TIM_TimeBaseInitTypeDef TIM7_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); //RCC_APB1Periph_TIM7
TIM_TimeBaseStructInit(&TIM7_TimeBaseStructure);
TIM7_TimeBaseStructure.TIM_Prescaler = 36000 - 1; // 分频之后的时钟频率为2KHz
TIM7_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM7_TimeBaseStructure.TIM_Period = 400 - 1; // 5Hz 定时频率
TIM7_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM7, &TIM7_TimeBaseStructure);
TIM_UpdateRequestConfig(TIM7, TIM_UpdateSource_Regular);
TIM_Cmd(TIM7, ENABLE);
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
}
void TIM7_IRQHandler(void)
{
if(TIM_GetITStatus(TIM7, TIM_IT_Update)== SET)
{
LED_Flash(GPIO_LED3);
TIM_ClearITPendingBit(TIM7 , TIM_FLAG_Update);
}
}
程序写完了,这里说几点注意事项。
(1)在对TIMx 进行设置之前一定要打开APB1总线上对应的时钟,否则所有的设置都不起作用。
(2)一定要设置NVIC,因为默认情况下这些外设的中断都是被禁用的。
stm32相关的学习资料
(stm32 USART串口应用)
http://www.makeru.com.cn/live/1392_1164.html?s=45051
(定时器)
http://www.makeru.com.cn/live/1392_1199.html?s=45051
STM32定时器深藏不露的绝技
http://www.makeru.com.cn/live/3523_1495.html?s=45051
stm32 如何用DMA搬运数据
http://www.makeru.com.cn/live/detail/1484.html?s=45051
(STM32中断系统)
http://www.makeru.com.cn/live/1392_1124.html?s=45051
(时钟系统)
http://www.makeru.com.cn/live/1392_1082.html?s=45051
STM32中断系统
http://www.makeru.com.cn/live/3523_1745.html?s=45051
STM32可以这样玩
http://www.makeru.com.cn/live/4034_1460.html?s=45051
STM32定时器学习---基本定时器的更多相关文章
- stm32定时器学习二——PWM设置
/* STM32 嵌入式学习入门(5)——PWM的实现 上一篇博文介绍了定时器和PWM的基本的原理,本篇博文从代码层面来介绍PWM的具体实现.同样,还是以博主所用的开发板——正点原子开发板STM32F ...
- STM32学习及应用笔记一:SysTick定时器学习及应用
这几年一直使用STM32的MCU,对ARM内核的SysTick计时器也经常使用,但几乎没有仔细了解过.最近正好要在移植一个新的操作系统时接触到了这块,据比较深入的了解了一下. 1.SysTick究竟是 ...
- STM32学习笔记——定时器中断(向原子哥学习)
定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...
- JavaScript学习05 定时器
JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout(“<表达式>”,毫秒) ...
- boost asio 学习(六) 定时器
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=7 6 定时器 ...
- stm32之Cortex系统定时器(SysTick)
转载自:http://www.21ic.com/app/mcu/201811/781135.htm SysTick时钟,俗称“嘀嗒定时器”,它能按设定的时间产生一次中断.控制工程代码中随处可见形如 ...
- python从写定时器学习Thread
目录 python从写定时器学习Thread Timer 对象 粗陋的循环定时器 更 pythonic 循环定时器 FAQ python从写定时器学习Thread python 如何写一个定时器,循环 ...
- STM32F103单片机学习—— 通用定时器
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/fengshuiyue/article/details/79150724 本篇重点记录的是STM32F ...
- Nordic52840SDK学习之定时器
Nordic 52840 SDK学习之定时器 今天开始学习52840SDK,特在此处记录学习内容,防止以后忘记,或许可以给以后的初学者提供一些帮助.如有错误,请发邮件至843036544@qq.com ...
随机推荐
- Redis-数据类型-应用场景
目录 一些小问题 String Hash List Set ZSet BitMaps Hyperloglog Geo Streams 应用场景小结 一些小问题 Redis一共有几种数据类型?(注意是数 ...
- 远程线程注入DLL突破session 0 隔离
远程线程注入DLL突破session 0 隔离 0x00 前言 补充上篇的远程线程注入,突破系统SESSION 0 隔离,向系统服务进程中注入DLL. 0x01 介绍 通过CreateRemoteTh ...
- spark集群的构建,python环境
个人笔记,问题较多 符号说明 [] 表示其中内容可以没有 su [root] 获取root权限 vi /etc/sudoers 1.点击I或Insert获得插入权限 2.在root ALL=(ALL) ...
- sql语句异常向数据库插入数据报错
在php编程向数据库插入数据时报如下错误: [Err] 1064 - You have an error in your SQL syntax; check the manual that corre ...
- Shell系列(37)- while和until循环
while循环 只要条件判断式成立则进行循环,并执行循环程序:一旦循环条件不成立,则终止循环 格式 while [ 条件判断式 ] do 程序 done 例子 需求:计算工具,1+2+--100的和 ...
- 『GoLang』错误处理
Go 没有像 Java 和 .NET 那样的 try/catch 异常机制:不能执行抛异常操作.但是有一套 defer-panic-and-recover 机制. Go 的设计者觉得 try/catc ...
- 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 百篇博客分析OpenHarmony源码 | v67.01
百篇博客系列篇.本篇为: v67.xx 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说一 ...
- Docker安装Jenkins 从GitLab上拉取代码打包SpringBoot项目并部署到服务器
1. 安装Jenkins 采用 Docker 方式安装 jenkins 首先,宿主机上需要安装java和maven,这里我的安装目录如下: 由于是docker安装,jenkins将来是在容器里面运行 ...
- 一凡老师亲录视频,Python从零基础到高级进阶带你飞
如需Q群交流 群:893694563 不定时更新2-3节视频 零基础学生请点击 Python基础入门视频 如果你刚初入测试行业 如果你刚转入到测试行业 如果你想学习Python,学习自动化,搭建自动化 ...
- 【Azure Developer】Azure Automation 自动化账号生成的时候怎么生成连接 与证书 (Connection & Certificate)
Azure Automation :The Azure Automation service provides a highly reliable and scalable workflow exec ...