历史上的今天
今天是:2024年12月29日(星期日)
2021年12月29日 | STM32F103高级定时器使用
2021-12-29 来源:eefocus
STM32F103单片机中定时器分为3种,高级定时器、通用定时器、基本定时器。
高级控制定时器(TIM1和TIM8)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器(TIM1和TIM8)和通用定时器(TIMx)是完全独立的,它们不共享任何资源。它们可以同步操作。
TIM1和TIM8定时器的功能包括:
16位向上、向下、向上/下自动装载计数器
16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值
多达4个独立通道:
输入捕获
输出比较
PWM生成(边缘或中间对齐模式)
单脉冲模式输出
死区时间可编程的互补输出
使用外部信号控制定时器和定时器互联的同步电路
允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
如下事件发生时产生中断/DMA:
更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
输入捕获
输出比较
刹车信号输入
支持针对定位的增量(正交)编码器和霍尔传感器电路
触发输入作为外部时钟或者按周期的电流管理
可编程高级控制定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数
器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。计数器、自动装载寄存器和预分频器寄存器可以由软件读写,即使计数器还在运行读写仍然有效。
高级定时器初始化方法如下:
void TIMER1_Init(u16 arr, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_DeInit(TIM1);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //允许更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //TIM1更新中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM1, ENABLE);
}
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
LED0 = !LED0;
}
}
这里使用的是定时器1,在初始化时传递了两个参数,其中arr用来设置定时器的周期,PSC设置时钟的分频系数。默认定时器的时钟频率为72MHz,所以带入这两个参数后,定时器的周期计算公式为:
(arr+1)*(psc+1)/72MHz,设置定时器的计数模式为向上计数。接下来还需设置重复计时器的值。TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x00;这个是高级定时器特有的一个计数器,默认设置为0,表示定时器永远循环计数,不会停止。如果设置为一个确定的数据,那么定时器执行一定次数后,就会停止运行。如果定时器需要开启中断功能的话,还需要设置NVIC寄存器,用来设置定时器的中断优先级。
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
KEY_Init();
TIMER1_Init(9,71); //50Khz 10us Tout=(9+1)*(71+1)/72M=10us
while(1)
{
}
}
在主程序中初始化定时器,这里设置定时器周期值为9,分频值为71,计算出来的定时器周期为10us。在中断函数中让LED灯取反,通过示波器观察就可以看到,LED等每隔10us电平就会变化一次。
史海拾趣
|
想请教一下,2407是不是没有CPU Timer? 2812已经有了通用计数器GP,为什么还需要CPU Timer? 2812的Timer主要是做什么用的呢? 是不是PSC减至0后,TIM才会减1 ? 如果没有用DSP-BIOS,2812的CPU-Timer2是否就能自行使用? 新手接触,问题太 ...… 查看全部问答> |
|
很郁闷的问题,WinCE、Platform Builder达人请进来,多提提建议,谢谢! 本人买了一块FriendlyARM(友善之臂)的板子,用VS2005开发了一个程序要运行在板子上面,系统刷成WinCE 5.0了,程序开发也完成了,正当以为一切可以结束的时候,发现板子重启之后保存在WinCE里面的数据完全消失了,程序可以放在别的 ...… 查看全部问答> |
|
Tornado2.2 for pcPentium问题,快被弄疯了 tornado2.2 for pentium,目标机是集成显卡,3com网卡的p4。 bsp选择p4,#define INCLUDE_EL_3C90X_END,#define INCLUDE_PC_CONSOLE都定义了,但是目标机一启动,v1.6+++++++走完就自动重启。 在网上查了下,好像是说集成显卡的内存可 ...… 查看全部问答> |
|
请教:我原来使用的WinCE5.0可以安装一个程序,但是后来设备更新后,WinCE升级了,我再重新安装时,一直无法安装。 我原来使用的WinCE5.0可以安装一个程序,但是后来设备更新后,WinCE升级了,我再重新安装时,一直无法安装。对此我一直很疑惑,系统主要对bug进行了修复,但是原来安装的程序只是复制到系统的文件夹中。其中有一点,系统盘符的名称变更了,原来是英 ...… 查看全部问答> |
|
比如 PA6--CH1/IN6 PA7 --CH2/IN7 现在我要捕获pwm的占空比 也就是要用到pwm模式 用到了两个输入口i 不过按照st的资料 ch2是内部连接的 那么 我还能PA7做模拟输入 ...… 查看全部问答> |
|
--基于AD56XX的VHDL控制程序--设计者 eeleaderlibrary ieee;use ieee.std_logic_1164.all; use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity Wr_Ad56XX is port ( clk: in std_logic;------20M ...… 查看全部问答> |
|
现在很多设备仪器都在用可充电锂电池组(锂电池组加装有电池保护板),为了防水的原因,电池组的封装固定后,电池组做防水处理一般用胶水固定,问题是:有的设备和仪器使用几个月后出现不能充电了,什么原因?当然电池供 ...… 查看全部问答> |




