如何包装stm32通用定时器的stm32延时函数delay

STM32之通用定时器_百度文库
您的浏览器Javascript被禁用,需开启后体验完整功能,
享专业文档下载特权
&赠共享文档下载特权
&10W篇文档免费专享
&每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
STM32之通用定时器
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢我想每个单片机爱好者及工程开发设计人员都有过点灯的经历。流水灯是个好东西,尤其是在调试资源有限的环境中,有时会帮上大忙。
然在最初入门时,如何让这些小灯们按照我们的想法欢快地跑起来呢,绝大多数小朋友的做法是:在一个while循环里加上延时程序,让小灯在每个状态下停留一段时间,再进入下一个状态,这样小灯们就会在不同的状态中切换,就可以根据我们设计的程序闪烁了。
这样这里就会涉及到一个延时程序的编写的问题,而一般的做法是一个for循环里去减一个很大的数,直到为0,则延时完成,那个数的值则是根据时钟频率和指令运行周期,估算出来的,还记得较久以前看过一篇帖子介绍51单片机精确延时的几种方法,有一种方法是在keil中设定好时钟频率,然后通过软件仿真试来算延时时间,以达到较精确定时。
但这些方法一般都不够方便,延时也不够精确,更高阶一点的方法便是开一个定时器,在定时中断里面计数达到精确延时的目的。
在STM32的应用中,可考虑利用SysTick系统嘀嗒定时器来实现。但在STM32开发手册中对它的介绍却很少,几乎到没有的程度。因为它是Cortex内核的部分,CM3为它专门开出一个异常类型,并且在中断向量表中占有一席之地(异常号15),这样它可以很方便的移植到不同厂商出CM3内核的芯片上,并且对于有实时操作系统的软件,它一般会作为整个系统的时基,这个对操作系统非常重要。有关SysTick的详细介绍可参考《Cortex-M3 权威指南》第133 页第八章及第179页第十三章。
SysTick总共有四个寄存器:
对应于软件中 SysTick-&CTRL;
对应于软件中&SysTick-& LOAD;
对应于软件中&SysTick-& VAL;
对应于软件中 SysTick-& CALIB& (如上图),没有用过,也不常用,暂不作介绍。
这几个寄存器的偏移量如下图所示:
?寄存器结构体的定义在 \CMSIS\CM3\CoreSupport& core_cm3.h中,如下?
/**&@addtogroup&CMSIS_CM3_SysTick&CMSIS&CM3&SysTick
&&memory&mapped&structure&for&SysTick
typedef&struct
&&__IO&uint32_t&CTRL;&&&&&&&&&&&/*!&&Offset:&0x00&&SysTick&Control&and&Status&Register&*/
&&__IO&uint32_t&LOAD;&&&&&&&&&&&/*!&&Offset:&0x04&&SysTick&Reload&Value&Register&&&&&&&*/
&&__IO&uint32_t&VAL;&&&&&&&&&&&&/*!&&Offset:&0x08&&SysTick&Current&Value&Register&&&&&&*/
&&__I&&uint32_t&CALIB;&&&&&&&&&&/*!&&Offset:&0x0C&&SysTick&Calibration&Register&&&&&&&&*/
}&SysTick_T
?SysTick? 是一个24 位的定时器,即一次最多可以计数 224个时钟脉冲,这个脉冲计数值被保存到SysTick-&VAL 当前计数值寄存器中,它只能向下计数,每接收到一个时钟脉冲SysTick-&VAL 的值就向下减 1,直至0,然后由硬件自动把重载寄存器SysTick-&LOAD 中的值到SysTick-&VAL重新计数,并且当SysTick-&VAL值计数到0时,触发异常,调用void SysTick_Handler(void)函数,可以在此中断服务函数中处理定时中断事件了,一般是对设定值进行递减计数操作。只要不把它在SysTick控制及状态寄存器SysTick-&CTRL中的第0位使能位清除,就永不停息。
SysTick 中断优先级问题这里需要强调下。
&它属于系统异常,是内核级中断,并且优先级是可以设置的,具体设置也是在& core_cm3.h中
&*&@brief&&Initialize&and&start&the&SysTick&counter&and&its&interrupt.
&*&@param&&&ticks&&&number&of&ticks&between&two&interrupts
&*&@return&&1&=&failed,&0&=&successful
&*&Initialise&the&system&tick&timer&and&its&interrupt&and&start&the
&*&system&tick&timer&/&counter&in&free&running&mode&to&generate&
&*&periodical&interrupts.
static&__INLINE&uint32_t&SysTick_Config(uint32_t&ticks)
&&&&if&(ticks&&&SysTick_LOAD_RELOAD_Msk)&&return&(1);&&&&&&&&&/*&Reload&value&impossible&*/
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&SysTick-&LOAD&&=&(ticks&&&SysTick_LOAD_RELOAD_Msk)&-&1;&&&/*&set&reload&register&*/
&&&&NVIC_SetPriority&(SysTick_IRQn,&(1&&__NVIC_PRIO_BITS)&-&1);&&
&&&&SysTick-&VAL&&&=&0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&SysTick-&CTRL&&=&SysTick_CTRL_CLKSOURCE_Msk&|&
&&&&&&&&&&&&&&&&&&&SysTick_CTRL_TICKINT_Msk&&&|&
&&&&&&&&&&&&&&&&&&&SysTick_CTRL_ENABLE_M&&&&&&&&&&&&&&&&&&&&
&&&&return&(0);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&/*&Function&successful&*/
其中如下这句就是设置优先级的函数,此函数对内核中断优先级和外部中断优先级设置通吃,比较强大,但需要手动算出来抢占和从优先级,不太方便,当跳进此函数,我们可以算出Systick默认优先是最低的(效果相当于SCB-&SHP[11] = 0xF0;)
NVIC_SetPriority&(SysTick_IRQn,&(1&&__NVIC_PRIO_BITS)&-&1);
此时若其它外部中断优先级设置比它高时,可以剥夺它进而转向外部中断。
可以做如下实验验证:
先设置一事件中断,把优先级设置高一些,
void&Exti_Config(void)
&&&&EXTI_InitTypeDef&EXTI_InitS
&&&&NVIC_InitTypeDef&NVIC_InitS
&&&&EXTI_InitStructure.EXTI_Line&=&EXTI_Line1;
&&&&EXTI_InitStructure.EXTI_Mode&=&EXTI_Mode_E
&&&&EXTI_InitStructure.EXTI_LineCmd&=&ENABLE;
&&&&EXTI_Init(&EXTI_InitStructure);
&&&&NVIC_InitStructure.NVIC_IRQChannel&=&EXTI1_IRQn;
&&&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority&=&1;&&&&
&&&&NVIC_InitStructure.NVIC_IRQChannelSubPriority&=&1;&&&&&&&&&&&&&&&&
&&&&NVIC_InitStructure.NVIC_IRQChannelCmd&=&ENABLE;
&&&&NVIC_Init(&NVIC_InitStructure);
注:中断分组我在实验中,最初初始化设置为如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
设为第二组。
void&SysTick_Handler(void)
&&&&EXTI_GenerateSWInterrupt(EXTI_SWIER_SWIER1);&
&&&&LED_1&=&ON;
&&&&Delay();
系统滴答中断里触发外部中断事件,并点亮LED1 。
外部中断处理函数如下
void&EXTI1_IRQHandler(void)
&&&&if&(EXTI_GetITStatus(EXTI_Line1)&!=&RESET)&
&&&&&&&&EXTI_ClearITPendingBit(EXTI_Line1);&&&&&
&&&&&&&&LED_0&=&ON;
&&&&&&&&Delay();
此延时函数为阻塞延时如下:
void&Delay(void)
&&&&u32&i;
&&&&for(i=0&&;&i&&&0xFFFFF;&i++){}
加入延时是为了看出来哪个灯先亮。
当外部中断优先级比较高时,它可以抢占Systick中断先执行,以上代码实验结果为,LED0先点亮后,再回到LED1再点亮。
当把外部中断设置为与systick相同的优先级时,则systick优先级就会相对较高,例如把上面的优先级改为
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority&=&3;&&&&
NVIC_InitStructure.NVIC_IRQChannelSubPriority&=&3;
则会LED1先亮,执行完SysTick_Handle函数后才轮到EXTI1_IRQHandler执行。
个人认为,若要实现systick精确延时,最好把systick优先级设置高一些,例如
NVIC_SetPriority&(SysTick_IRQn,&0);
即把SCB-&SHP[11] = 0x00;则可达到systick优先级高于任合外部中断的效果,此时延时会比较精准。
另外对于SysTick的时钟源的选择,要注意它的时钟源可选择内部时钟(FCLK,CM3上的自由运行时钟,STM32中对应是AHB),或者是外部时钟(& CM3处理器上的STCLK信号,STM32中对应是AHB/8)
可参考如下图
它是在SysTick-&CTRL第二位CLKSOURCE时钟源选择中设置。
有关systick延时函数的编写可参考野火《零死角玩转stm32-初级篇》。
至此我们可以简单的实现一流水灯程序
&&&&LED_0&=OFF;
&&&&LED_1&=&ON;
&&&&Delay_ms(500);
&&&&LED_0&=OFF;
&&&&LED_1&=&ON;
&&&&Delay_ms(500);
然而这样做真的好吗 ?这里用的是 阻塞延时哦,CPU的效率很大一部分就耗在了空转上了,太浪费资源。
?假设系统时钟频率为72MHZ或者几十上百MHZ时,当完成一个循环只需要几十或十几纳秒级或者更短,而在这个循环之中阻塞延时个几十至几百毫秒的话,就像是在高速公路上突然横出一条坑坑洼洼的泥泞路,那可想整条路都会因此而慢下来,甚至会出现灾难性的后果,个人认为,一般在系统初始化过程中,各芯片的时序对时间有要求,可以用下阻塞延时,只需要系统启动时运行一下,当系统跑起来之后,最好就别再傻呼呼的这么做了。?
这时主要采用的是在定时器里计数,在外部循环中对变量查询,达到某个值时再执行某个动作,达到延时的效果,而在时间未到时,系统还可以不停的跑圈圈,做别的事情去。
?&gticks在定时中断里每毫秒计数一次
&&&&if(500&==&gticks)
&&&&&&&&LED_0&=OFF;
&&&&&&&&LED_1&=&ON;
&&&&if(1000&==&gticks)
&&&&&&&&LED_0&=OFF;
&&&&&&&&LED_1&=&ON;
&&&&&&&&gticks&=&0
&&&&Do_others();&
??以上需要在事件处理过程中对gticks进行处理,增加了代码的耦合度,更容易出错,如果在一个事件处理中对gticks清除了,而下个事件中又需要查询它,这样就可能导致处理时序的错乱,相互干扰。??
能否在事件处理中只提供查询功能,而定时的事情就交给定时自己去做?
下节高手将登场了,为大家介绍个我曾在一项目中学到的,非阻塞延时的精妙设计。
& 著作权归作者所有
人打赏支持
码字总数 14052
下面为大家介绍一个曾见过的在裸机系统中,非阻塞延时的巧妙设计,当时它是被用在一导航影音娱乐系统的MCU驱动软件中,在此我对其作了一定的改动。 此章节涉及到STM32内容不多,以软件为主。...
小汉憨憨 ?
SysTick-------操作系统的心跳 SysTick是系统滴答定时器,可以说是操作系统的的“心跳”,它被绑在NVIC中,用于产生SysTick异常(异常号:15)。一旦产生SysTick异常,就会产生滴答中断,这个...
panrenqiu ? 04/14 ?
SysTick系统嘀嗒定时器并非STM32独有的,它是Cortex内核的部分,CM3为它专门开出一个异常类型,并且在中断向量表中占有一席之地(异常号15)。这样它可以很方便的移植到不同厂商出CM3内核...
OceanStack ?
因为网上关于STM32读取6050的例程并不少但是总会有古怪的问题存在,在尝试读取的过程中在网上逛论坛发现很多问题到最后没结果不了了之,不知那些前辈们是否已经自己查出了问题,我想尽自己微...
qq_ ? 01/31 ?
一、Linux时钟系统 1.时钟硬件 绝大多数的PC都有两个时钟源,RTC(实时时钟)和OS(系统时钟)。RTC也叫做CMOS时钟,它是PC主机板上的一块芯片。OS时钟产生于PC主板上的定时/计数芯片,由操作...
8yi少女的夢 ?
1、stm32中断向量表配置 在STM32使用中由于中断优先级的设置采用的是库函数,因此要请保证所有的优先级设置为可抢占优先级,具体实现方式是在RTOS启动前调用函数:NVICPriorityGroupConfig(N...
crjmail ? 04/20 ?
让自己别忘了大学里学的东西,那么就把它记录下下来,效率会比忘记然后重新再去找资料再重头学高的多 先讲讲定时器的基础定时功能: 1.先做一个形象的比喻: 它们俩基本相同,不同的是,对...
qq ? 04/10 ?
最近一直在忙STM32的学习,在学习中遇到了不少问题,也经过各种尝试解决问题,在这里我通过博文的形式写出来,也希望能够帮到遇见同样问题的人们。对于STM32系列的芯片,有一个好处就是官方给...
jerry2012cn ?
cube基本配置,外设开启编码器,串口2 -------------------------------------------------------------------------------------------------------------------------- 错误:error: #20:......
super828 ? 03/18 ?
这一部分描述异常模型。 每一个异常都存在一个状态: 闲置 这个异常没有活跃,没有暂停 待进行 异常等待被处理器服务。一个外设或软件中断请求可以改变相应中断的状态到即将发生状态。 ·活跃...
qq_ ? 03/28 ?
没有更多内容
加载失败,请刷新页面
Netty源码分析——flush流程 前言 承接上篇写流程,这篇看下flush流程。之前文章中我们已经提到过,writeAndFlush操作实际上是通过pipeline分别进行了write和flush操作。具体我们就不看了,我...
Java小铺 ? 6分钟前 ?
步骤可参阅wiki 1. 安装libfastscommon时,git报错:Peer reports incompatible or unsupported pro 解决方案: # yum update -y nss curl libcurl ...好像也没什么难的(捂脸)...
休辞醉倒 ? 7分钟前 ?
查看SELinux状态: 1、/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态 SELinux status: enabled 2、getenforce ##也可以用这个命令检查 关闭SELinux: 1、临时关闭(...
侠客行之石头 ? 8分钟前 ?
#根据域名改变入口文件location / {set $enter_file "index";if($host = "s.work.test.com"){set $enter_file "sso";}if (!-e $request_filename) {
dubox ? 9分钟前 ?
描述:今天早上使用root用户界面式登录centos7.1那台机器时,第一步通过windows连接认证是通过的,但是在centos7.1那台机器输入密码打开桌面时,一直登录不上,后来想重启一下远程小工具xrd...
爱运动的小乌龟 ? 11分钟前 ?
public static File MultipartFileToFile(MultipartFile multiFile) {
// 获取文件名
String fileName = multiFile.getOriginalFilename();
// 获取文件后缀 ......
AK灬 ? 12分钟前 ?
1:查看函数的信息,就是该命令的工作(man 2 XXX。例如 man 2 stat)。在vi的命令模式下,光标定位在函数上,按住大K键,就是大写K。也可以按住shift+k组合键。 2:查看头文件。例如你知道头...
HelloRookie ? 12分钟前 ?
摘要: FastDFS简介 oFastDFS是一个轻量级的开源分布式文件系统 oFastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡 oFastDFS实现了软件方式的RAID,可以使...
花的鱼 ? 14分钟前 ?
Docker逐渐成为虚拟化技术的佼佼者,Java架构师之路接下来会推出一系列的Docker相关技术文章,Docker技术也是架构师的必备技能。 什么是Docker Docker 是一个开源的应用容器引擎,基于Go语言...
stars永恒 ? 16分钟前 ?
简介 jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁...
谢思华 ? 17分钟前 ?
没有更多内容
加载失败,请刷新页面
文章删除后无法恢复,确定取消删除此文章吗?
亲,自荐的博客将通过私信方式通知管理员,优秀的博客文章审核通过后将在博客推荐列表中显示
确定推荐此文章吗?
确定推荐此博主吗?
聚合全网技术文章,根据你的阅读喜好进行个性推荐
指定官方社区
深圳市奥思网络科技有限公司版权所有查看: 6334|回复: 2
关于用stm32通用定时器TIM3实现精确延时问题
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间0 小时
本人在用STM32的tim3完成精确延时时,使用如下程序
void TIM3_IRQHandler(void)
&if(TIM3-&SR&0X0001)
&&& yanshi--;
&TIM3-&SR&=~(1&&0);&}
void delay_ms(u16 nms)
{& yanshi=&
&&& Timerx_Init(10,7199); //产生1MS的中断
&while(yanshi);&& &&
这样利用中断延时显然是不行的,因为频繁中断用去大量时间,在仿真我使用延时200ms,但是仿真结果是220ms,请教大哥们,我的这个程序应该怎么改才能得到精确的延时呢,谢谢!
主题帖子精华
金钱128625
在线时间1142 小时
回复【楼主位】zhongding818:
---------------------------------
随时修改中断的设置.
比如,你要延时200ms,就分为4次中断,每次中断50ms(假设你设定的定时器匹频率最大能延时50ms),设置累加器t,当t==4的时候,说明200ms延时到了,那就不用你去中断200次了.
如果延时10ms,那么你直接修改定时器的初始化参数,让其10ms后产生一次中断,那直接一次中断就OK了.
不过这种小延时,用查询的方式最好了.虽然耗CPU.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 55, 距离下一级还需 145 积分
在线时间0 小时
谢谢原子哥!!! 受教了!!
Powered byposts - 12,&
comments - 1,&
trackbacks - 0
STM32用定时器精确延时的方法(非SysTick)
用TIM2来做延时,延时基准时间1ms,最大可延时65535ms。系统基础频率是8MHz*4=32MHz。
先配置定时器:
&&& TIM_TimeBaseInitTypeDef timInitS&&& timInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;&& // 定时器基准频率32MHz&&& timInitStruct.TIM_Prescaler = 32000;&&&&&&&&&&&&&&&&&&& // 计数频率为1KHz&&& timInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数&&& timInitStruct.TIM_RepetitionCounter = 0;&&& timInitStruct.TIM_Period = 0; // 这个值实际上就是TIMX-&ARR,延时开始时重新设定即可
&&& TIM_TimeBaseInit(TIM2, &timInitStruct);&&& TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 计数溢出时触发中断&&& TIM_Cmd(TIM2, DISABLE);
把定时器的计数频率定为1KHz,这样每1ms计数一次,可以做1ms为基准的延时。
定义延时函数:
&&&& u8 _delayTimeO&&& void delay1ms(u16 delayTime)&&& {&&&&&&& _delayTimeOut = 0;&&&&&&& TIM2-&ARR = delayT
&&& &&& TIM_Cmd(TIM2, ENABLE);&&&&&&& while(!_delayTimeOut)&&&&&&& {&&&&&&& }&&&&&&& TIM_Cmd(TIM2, DISABLE);&&& }
定义计数溢出时的中断函数:
&&& extern u8 _delayTimeO&&& void TIM2_IRQHandler(void)&&& {&&&&&&& if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)&&&&&&& {&&&&&&&&&&&& _delayTimeOut = 1;&&&&&&&&&&&& TIM_ClearFlag(TIM2, TIM_FLAG_Update);&&&&&&&& }&&& }
原来的一个思路是配置定时器每1ms就中断一次(TIMX-&ARR值固定),在延时前将全局的延时计数器清零(该值在中断中不断累加),然后比较计数器值与欲延时的值,超过了就停止,就像这样:
&&& void delay1ms(u16 delayTime)&&& {&&&&&&& _delayTimer = 0; // 延时计数器
&&&&&&& TIM_Cmd(TIM2, ENABLE);&&&&&&& while(_delayTimer & delayTime)&&&&&&& {}&&&&&&& TIM_Cmd(TIM2, DISABLE);&&& }&&& void TIM2_IRQHandler(void)&&& {&&&&&&& if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)&&&&&&& {&&&&&&&&&&&& _delayTimer++;&&&&&&&&&&&& TIM_ClearFlag(TIM2, TIM_FLAG_Update);&&&&&&&& }&&& }
这种做法也可以达到延时的目的,不过在延时的时候会频繁中断,因此这种做法不可取。
阅读(...) 评论()STM32学习笔记(五)——通用定时器计数延时
时间: 23:04:08
&&&& 阅读:1208
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&STM32定时器概述
STM32F40x系列总共最多有14个定时器,定时器分为三类:基本定时器、通用定时器和高级定时器。它们的都是通过计数来达到定时的目的,和51的定时器差不多,基本原理都是一样的,就是功能多了一些,这些计数器都是自动重新装载初值的,使用起来非常方便,而且计数时钟频率可以通过分频系数来设置。本文章将介绍使用定时器中断来控制LED间隔1s闪烁。
计数的时钟来源主要有四个:
内部时钟CK_INT
外部时钟模式1:外部输入脚TIx
外部时钟模式2:外部触发输入ETR,仅适用于 TIM2、 TIM3、 TIM4
内部触发输入ITRx:使用 A 定时器作为 B 定时器的预分频器(A为B提供时钟)
我们使用定时器内部时钟,即CK_INT作为计数器的时钟源 = 168MHz / 2 = 84MHz
时钟框图如下:
定时器的配置
1.使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
//定时器3时钟使能
2.初始化定时器参数,设置分频系数和计数初值,计数模式设置等。如果要定时1s定时器溢出,那么可以设置分频系数为8400 ,则分频后的时钟频率为 : 84MHz / 8400 = 10KHz &= 0。1ms &,计数初值设置为1s / 0。1 ms = 10000即可。
/*初始化定时器参数,设置自动重装值,分频系数,计数方式*/
TIM_Init。TIM_ClockDivision=
TIM_CKD_DIV1;
//时钟分频因子
TIM_Init。TIM_CounterMode=TIM_CounterMode_Up;
//定时器模式
TIM_Init。TIM_Period=P
//自动重装值,0-65535
TIM_Init。TIM_Prescaler=
TIM_Init。TIM_Prescaler=
//分频系数-0。1ms
TIM_Init。TIM_Prescaler=
//分频系数-0。5ms
TIM_Init。TIM_RepetitionCounter=
TIM_TimeBaseInit(TIM3,&TIM_Init);
TIM_RepetitionCounter是使用高级定时器要进行设置的。我们使用的是定时器3,属于通用定时器,计数模式设置为向上计数,则计数器从0 开始计数,当计数到设置的初值时,然后计数器重新从0开始计数,并将溢出标志位置1,如果设置了溢出中断,则会产生计数器溢出中断。
3.定时器3中断设置,注意优先级的设置,如果程序中开启了多个中断。就要考虑中断优先级的设置,本程序只使用了一个定时器中断,则配置为任何优先级都是可以的。
/*定时器3中断优先级设置*/
NC_Init。NVIC_IRQChannel=TIM3_IRQn;
//中断通道指定定时器3
NC_Init。NVIC_IRQChannelCmd= ENABLE;
NC_Init。NVIC_IRQChannelPreemptionPriority=<span style="color: #;
//设置抢占优先级
NC_Init。NVIC_IRQChannelSubPriority=<span style="color: #;
//设置响应优先级
NVIC_Init(&NC_Init);
4.使能定时器,当执行完这一句后,定时器就开始从 0 开始计数了。我们可以通过使能定时器来暂停计数器,或者使能定时器来启动定时器,在开发时钟时可以使用这个。
相当于51中的TR1 = 1 / TR1 = 0
TIM_Cmd(TIM3,ENABLE);
5.中断服务函数,本程序是让LED1间隔1s闪烁,那么中断服务函数的功能就是让LED1的状态反转。
void TIM3_IRQHandler(void)
if(TIM_GetITStatus(TIM3,TIM_IT_Update))
//如果产生溢出中断
LED1=!LED1;
//那么状态反转
LED0=!LED0;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
//清楚更新中断标志位
这里检测的是定时器溢出中断,即计时1s时间到,则将LED1的状态反转,然后将溢出标志位清零。
int main(void)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(<span style="color: #8);
LED_Init();
//LED初始化熄灭
Timer3_Config(<span style="color: #00,<span style="color: #000);
//<span style="color: #.5ms*2000 = 1s
while(<span style="color: #)
LED0=!LED0;
delay_ms(<span style="color: #00);
这里使用延时函数来延时1s控制LED0闪烁,实际运行效果可以看出两个LED的闪烁在一定的时间内是同步的,但是时间一长还是有点误差。
当学完这一节定时器的时候,我就有一个想法了,那就是写一个LCD电子时钟的程序,通过定时器来达到准确延时的目的,当然还要学习一下LCD1602的驱动方法,哈哈,想想就很有成就感。
参考资料:
STM32F4xx中文参考手册
以上是我学习过程的一些个人理解,有不对或不准确的地方,欢迎各位大神指正。
日21:33:44
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文地址:http://www.cnblogs.com/whik/p/6746177.html
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!

我要回帖

更多关于 stm32通用定时器 的文章

 

随机推荐