上一贴介绍了STM32F411 的按键和用户LED 的点亮,这次来讲讲定时器。 STM32F411的定时器功能非常丰富,从参考手册上可以看到在STM32F411xC/E中有11个定时器,其中1个高级控制定时器(TIM1),4个普通定时器(TIM2-TIM5)和3个基本定时器(TIM9-TIM11),以及2个看门狗定时器(IWDG、WWDG)和1个系统嘀嗒定时器(SysTick)。 (二) 高级控制定时器TIM1 STM32F411的TIM1的特性包括: 16位向上、向下、向上/下自动装载计数器 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 同步电路,用于使用外部信号控制定时器以及定时器互联( 某些型号的芯片没有定时器互联功能) 多达4个独立通道可以配置成: ─输入捕获 ─输出比较 ─PWM生成(边缘或中间对齐模式 ─六步PWM输出 ─单脉冲模式输出 ─三个支持带互补输出,并且死区时间可编程的通道 中断输入信号可以将定时器输出信号置于复位状态或者一个已知状态 产生中断的事件包括: ─更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─输入捕获 ─输出比较 ─中断信号输入 高级控制定时器框图: (三) 普通定时器TIM2 to TIM5 •16位(TIM3,TIM4)或32位(TIM2和tim5)上,下,上/下自动加载 计数器。 •16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 多达4个独立的渠道: –输入捕捉 –输出比较 - PWM生成(边缘和中心对齐模式) 一个脉冲模式输出 同步电路控制外部信号和互连的定时器 几个定时器。 •中断和DMA发生以下事件: –更新:计数器溢出,计数器初始化(通过软件或内部/外部触发 –触发事件(计数器启动,停止,初始化或通过内部/外部触发计数) –输入捕捉 –输出比较 支持增量(正交)编码器和霍尔传感器电路的定位目的 通过循环电流管理触发外部时钟或周期的输入 通用定时器程序框图: (四) 基本定时器TIM9 to TIM11 TIM9: •16位自动重载计数器 •16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 多达2个独立的渠道: –输入捕捉 –输出比较 脉宽调制(边缘对齐模式) 一个脉冲模式输出 同步电路控制外部信号和互连的几个定时器一起 以下事件的中断生成: –更新:计数器溢出,计数器初始化(由软件或内部触发) –触发事件(计数器启动,停止,初始化或由内部触发计数) –输入捕捉 –输出比较 TIM10、TIM11 16位自动重载计数器 •16位可编程分频器用来将计数器时钟频率的因素 在65536和1之间(可以改变“飞”) 独立渠道: –输入捕捉 –输出比较 脉宽调制(边缘对齐模式) 一个脉冲模式输出 以下事件的中断生成: 更新:计数器溢出,计数器初始化(由软件) –输入捕捉 –输出比较 (五) 独立的看门狗IWDG 先解释一下看门狗:看门狗设备(独立看门狗和窗口看门狗)可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,触发一个中断或产生系统复位。 独立看门狗的主要特点 •自由运行的倒计时 •时钟从一个独立的RC振荡器(可以工作在待机和停止模式) ••复位(如果看门狗激活)时的倒计时值达到0x000 独立看门狗是通过IWDG_KR写入OXCCCC,启动独立看门狗功能,计数器值开始递减,减到0时,看门狗复位。IWDG_KR写入0XAAAA,计数器值被重新加载,即避免看门狗复位。IWDG_KR写入0X5555,则允许写IWDG_PR 和IWDG_RLR寄存器写操作。写入其它值,IWDG_PR 和IWDG_RLR被保护,数据将无法写入这两个寄存器。IWDG_SR状态寄存器指示预分频值和递减计数器是否正在被更新。IWDG_RLR寄存器范围为0-0xfff. 如果“硬件看门狗”功能是通过设备选项位启用,看门狗是自动启用在电源上,并将产生一个复位,除非该密钥寄存器是由软件之前,计数器达到计数结束。 独立看门狗框图; (六) 窗口看门狗WWDG 窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在 T6 位 (WWDG->CR 的第六位)变成 0 前被刷新,看门狗电路在达到预置的时间周期时,会产生一个 MCU 复位。在递减计数器达到窗口配置寄存器(WWDG->CFR)数值之前,如果 7 位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个 MCU 复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。 主要特点 可编程自由运行计数器 •条件重置 •复位(如果看门狗激活)当向下计数器值变得小于0x40 •早醒中断(EWI):触发(如果启用看门狗激活)时向下计数器等于0x40。 窗口看门狗框图 总结独立看门狗与窗口看门狗的区别: 1)独立看门狗没有中断,窗口看门狗有中断 2)独立看门狗有硬件软件之分,窗口看门狗只能软件控制 3)独立看门狗只有下限,窗口看门狗又下限和上限 4)独立看门狗是12位递减的。窗口看门狗是7位递减的 5)独立看门狗是用的内部的大约40KHZ RC振荡器,窗口看门狗是用的系统时钟APB1ENR (七) 系统滴答定时器SYSTICK 这是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。 作用: 在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS). 因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。这样SYSTICK存在的意义就是提供必要的时钟节拍,为RTOS的任务调度提供一个有节奏的“心跳”。 (八) 利用定时器3产生PWM 编程步骤 1. 配置系统时钟; 2. 配置NVIC; NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//定时器3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;//抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;//子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure);//初始化NVIC 3. 配置GPIO; voidPWM_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);// GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7; // GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; // GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; // GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; // GPIO_Init(GPIOA,&GPIO_InitStructure); } 4. 配置TIMER; ***************** 通用定时器3初始化 arr:自动装载值 psc:时钟预分频数 定时器时间溢出的计算方法:Tout=((arr+1)*(psc+1))/ Ft us Ft定时器的工作频率,单位MHz ***************** */ voidTIM3_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDefTIM_TimeBaseInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM3时钟 TIM_TimeBaseInitStructure.TIM_Period=arr;//自动重装载值 TIM_TimeBaseInitStructure.TIM_Prescaler=psc;//定时器分频 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上技术模式 TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化定时器3 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//允许定时器3更新中断 NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;//定时器3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;//抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;//子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure);//初始化NVIC TIM_Cmd(TIM3,ENABLE);//使能定时器3 } 5. 主函数: intmain(void) { PWM_GPIO_Config(); TIM3_Init(99,99); // 5Khz定时器时间溢出的计算方法:Tout=((arr+1)*(psc+1))/ Ft us while (1) { GPIO_SetBits(GPIOA,GPIO_Pin_5);// LED } } 这里我通过直接控制寄存器的方法来控制IO口输出,设置输出的IO口为PA7. (九) 测试结果: 将代码下载到板子上后搭线连接示波器。如图示,示波器测得频率为5.076KHz。占空比49.75%,与设定的值几乎一致。
接线方式: 示波器显示的值
|