博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32学习笔记(五)——通用定时器计数延时
阅读量:7260 次
发布时间:2019-06-29

本文共 2539 字,大约阅读时间需要 8 分钟。

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=Period;                            //自动重装值,0-65535    TIM_Init。TIM_Prescaler=  Prescaler;//    TIM_Init。TIM_Prescaler=    8400;                    //分频系数-0。1ms//    TIM_Init。TIM_Prescaler=    42000;                    //分频系数-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=0;        //设置抢占优先级    NC_Init。NVIC_IRQChannelSubPriority=0;                //设置响应优先级    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(168);    LED_Init();                        //LED初始化熄灭    Timer3_Config(2000,42000);        //0.5ms*2000 = 1s    while(1)    {        LED0=!LED0;        delay_ms(1000);                }}

 

这里使用延时函数来延时1s控制LED0闪烁,实际运行效果可以看出两个LED的闪烁在一定的时间内是同步的,但是时间一长还是有点误差。

总结

当学完这一节定时器的时候,我就有一个想法了,那就是写一个LCD电子时钟的程序,通过定时器来达到准确延时的目的,当然还要学习一下LCD1602的驱动方法,哈哈,想想就很有成就感。

参考资料:

 

STM32F4xx中文参考手册

 

以上是我学习过程的一些个人理解,有不对或不准确的地方,欢迎各位大神指正。

 

2017年4月21日21:33:44

 

转载地址:http://eqkdm.baihongyu.com/

你可能感兴趣的文章
第二周进度报告
查看>>
Hadoop集群(一) Zookeeper搭建
查看>>
JDBC事务,银行转账,货物进出库等等。
查看>>
oc-Foundation框架-NSString-常用方法
查看>>
算法:管窥算法-查找旋转数组(即进行了左移或右移的数组)的最小值
查看>>
linux 查看进程和端口
查看>>
服务器端汉字乱码
查看>>
学习笔记之Data analysis
查看>>
Linux系统中“动态库”和“静态库”那点事儿【转】
查看>>
Linux磁盘空间不足
查看>>
Java项目怎么使用Swagger生成API文档?
查看>>
LeetCode OJ:Bulls and Cows (公牛与母牛)
查看>>
吴宁川-阿里云创造者写了《在线》,这是一本怎样的书?
查看>>
CRB and Candies LCM 性质
查看>>
zgg与占卜师
查看>>
WorkStream构想
查看>>
C#正则表达式验证
查看>>
二维数组函数参数传递 –转
查看>>
c# 自定义解析JSON字符串数据
查看>>
spring自定义标签
查看>>