定时器和计数器

本文详细介绍了51单片机中的定时器概念及其工作原理,包括定时器的基本功能、计数器的作用及定时器如何通过设置不同的寄存器进行初始化与控制。此外,还提供了使用定时器实现LED闪烁的具体编程实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 定时器介绍

1.1 什么是定时器

(1)SoC的一种内部外设。

(2)定时器就是CPU的“闹钟”。

1.2 什么是计数器

(1)定时器就是用计数的原始实现的。

(2)计数器可以计算外部脉冲个数。

1.3 定时器如何工作

(1)第1步:先设置好定时器的时钟源(如果需要的话)。

(2)第2步:初始化时钟相关寄存器。

(3)第3步:设置定时时间(计数个数)。

(4)第4步:设置中断处理程序。

(5)第5步:打开定时器。

(6)运行时:定时器计数到后产生中断,然后执行中断isr。

2 软件控制硬件的关键-寄存器

2.1 什么是寄存器

(1)register。

(2)寄存器,寄存,内容可变,一般按位定义。

(3)寄存器使用地址访问,编程上像内存一样。

2.2 寄存器的工作原理

(1)寄存器和硬件之间有双向影响。

(2)软件可以读写寄存器。

(3)总结:寄存器是软件能够控制硬件的关键。

2.3 单片机学习的关键就是各种寄存器

(1)单片机的学习主要包括2个:CPU和各种内部外设。

(2)各种内部外设的编程接口就是寄存器。

(3)熟悉一款单片机其实就是熟悉他的寄存器。

(4)寄存器会随着单片机的复杂化而变复杂。

(5)学会用C语言操作寄存器的技巧。

3 51单片机的定时器简介

这里写图片描述

关于脉冲宽度的计算:

譬如外部12MHz晶振,单片机工作在12T模式下,则内部时钟频率是1MHz,则时钟脉冲宽度为1us(1/1MHz = 1us)。如果单片机工作在6T模式下,则内部时钟频率是2MHz,则时钟脉冲宽度为0.5us(1/2MHz = 0.5us)。

4 定时器的主要寄存器介绍(定时器0和1)

这里写图片描述

4.1 TCON

这里写图片描述

(1)8个位,但是有4个名字:TF、TR、IE、IT,每个名字的符号都有2个,后面分别带0和1,对应T0和T1。

(2)TF: timer flag,定时器(溢出)标志位,是只读(软件只是通过读取TF1来知道硬件的状态,而不用去写这一位来设置硬件的状态)的。timer定时时间到了后会做2件事情:第一个是把TF标志改为1,第二个是产生中断让CPU去中断处理;TF是硬件清零的(由1变0是自动的,不需要软件来干预。)有一些CPU的设计是需要软件去清零的,这时候用户的程序就一定要记得给标志位清零,不然就不能重复进入中断或者反复不停的重复进入中断。

(3)TR就是timer run,就是定时器的启动计数的开关。当我们把整个定时器初始化好了之后,我们给TR位写1就可以开启计数了。TR位和GATE位有一定关联性。

(4)GATE是TMOD寄存器中的,也有2个分别对应T0和T1。GATE位中文名叫门控位,工作方式是:当GATE=0时(相当于门是打开的,此时GATE位是可以忽略的),此时定时器开关就只受TR位影响。具体就是TR=1开启计数,TR=0结束计数。当timer处于定时器工作模式时GATE就要等于0;GATE一般是在timer处于计数器模式时用的。当timer用来计数时,很关键的就是什么条件下计数,什么条件下不计数。当GATE=0时计数条件只有TR1一个(TR1=1就计数,TR1=0就不计数),当GATE=1时是否计数不仅取决于TR1还取决于INT1引脚(P3.3),实际规则是:当TR1=1并且INT1引脚也为高电平时才会计数。

(5)IE也是个标志位,作用就是用来展示硬件的状态改变的。譬如IE1对应外部中断1(INT1),平时不发生INT1时IE1=0,当INT1发生中断时,硬件自动IE1=1,当CPU处理了INT1时硬件会自动给IE1=0(硬件自动清零)。

(6)IT是用来设置外部中断的中断触发方式的。所谓中断的触发方式,就是指硬件在某种条件下才会被判定为要产生中断,所以其实就是中断产生的条件。中断触发方式一般就是:边沿触发和电平触发2种。边沿触发又分为:上升沿触发、下降沿触发、双边沿触发;电平触发方式分为:高电平触发、低电平触发2种。

4.2 TMOD

这里写图片描述

(1)C/T位,设置T0/T1工作在定时器模式还是计数器模式。1表示计数器,0表示定时器。

(2)M1 + M0,2个位一起来表示T0/T1处于哪种工作模式下,一般有4种:13位、16位、8位自动重载、双8位。

5 定时器编程实践

5.1 实验目的

(1)使用定时器来完成LED闪烁。

(2)原来实现闪烁时中间的延迟是用delay函数实现的,在delay的过程中CPU要一直耗在这里不能去做别的事情。这是之前的缺点。

(3)本节用定时器来定一个时间(譬如0.3s),在这个定时器定时时间内CPU还可以去做主任务,定时时间到产生中断,在中断处理程序isr中让LED闪烁即可。

5.2 如何编程

(1)定时(timer初始化)。

(2)主程序该干嘛干嘛。

(3)中断处理程序。

我们开发板的定时器最多能订多长时间?
内部时钟频率是1MHz,时钟周期是1us。最多能定65535(16位定时器),也就是说最大定时时间为65535*1us=65535us=65.535ms。
如果要定比较长的时间(譬如2s),定时器直接是不能满足的,解决办法是多次定时后加起来构成一个长时间。

计算TL0和TH0:
(1)确定自己定时时间,定为50ms
(2)确定内部时钟周期,因为12T模式,外部晶振12MHz,所以为:1us
(3)定时个数就是:50ms/1us = 50000
(4)TL0 = (65536 - 50000) % 256, TH0 = (65536 - 50000) / 256

51单片机的计数器是减计数器,所以应该拿65536减去计数的次数,才能得到TH和TL的值。

#include <reg51.h>

unsigned char count;            // 10次,对应500ms
sbit LED = P0^1;                // LED对应的GPIO定义

#define CNT     20

void timer0_isr(void) interrupt 1 using 1
{
    TL0 = 50000 % 256;  
    TH0 = 50000 / 256;          // 手工重载计数值

    if (count-- == 0)
    {
        // 说明已经中断了10次了,500ms到了,干活了
        LED = !LED;             // LED取反
        count = CNT;
    }
}


void main(void)
{
    TMOD = 0x01;        // T0设置工作在定时器模式下,16位定时器
    TL0 = (65536l - 50000) % 256;   
    TH0 = (65536l - 50000) / 256;
    TR0 = 1;            // 开启计数器,开始计数了
    ET0 = 1;            // 开启T0中断
    EA = 1;             // 开启中断总开关

    count = CNT;            // 10次,对应500ms

    while (1);          // 主任务
}
<think>好的,用户想了解STM32中定时器计数器的区别。首先,我需要回顾一下STM32的定时器模块的基本结构。根据引用[1][2],STM32有多种定时器,比如基本定时器、通用定时器、高级定时器等。这些定时器通常具备定时、计数、PWM生成等功能。 接下来,我需要明确定时器计数器在STM32中的功能差异。根据引用[1],定时器主要用于时间相关的功能,比如定时中断、PWM输出,而计数器则是用来对外部脉冲进行计数。这里可能需要进一步查阅资料确认,比如引用[3]提到定时器可以作为外部计数器使用,这说明计数器功能其实是定时器模块的一部分,而不是独立的硬件。 用户可能存在的混淆点在于,定时器计数器是否是同一模块的不同模式。根据引用[4],定时器的工作模式可以通过配置寄存器来切换,比如设置计数器模式为向上或向下计数,或者外部触发模式。因此,定时器计数器的区别更多是功能上的应用场景不同,而非硬件上的独立模块。 需要进一步确认的是,STM32的计数器是否只能通过定时器模块实现,以及定时器计数器模式下的具体配置方法。例如,引用[3]中的GPIO配置为复用功能,用于外部事件计数,这说明当定时器被配置为外部时钟源时,它就作为计数器使用。 总结来说,STM32中的定时器模块既可以作为定时器使用,也可以通过配置作为计数器使用。两者的主要区别在于功能应用:定时器用于内部时钟驱动的定时任务,而计数器用于外部事件的脉冲计数。硬件上它们是同一个模块的不同工作模式,而非独立存在。</think>### STM32定时器计数器的功能及区别 #### 1. **功能定义** - **定时器(Timer)** 以内部时钟源(如系统时钟)为基准,通过预分频器计数器实现时间测量或周期控制,例如: - 定时中断(如1ms触发一次中断)[^1] - PWM信号生成(控制电机或LED亮度) - 定时触发ADC采样 - 时间戳记录 - **计数器(Counter)** 对外部事件(如脉冲信号)进行计数,常用于: - 测量外部信号的频率或脉冲数量(如编码器信号)[^3] - 捕获外部触发信号的边沿(如按键按下次数) - 作为外部时钟源驱动定时器 #### 2. **核心区别** | **特性** | **定时器** | **计数器** | |----------------|-------------------------------|-------------------------------| | **时钟源** | 内部时钟(如APB总线时钟) | 外部信号(如GPIO引脚输入) | | **主要功能** | 时间测量、PWM生成 | 外部事件计数、频率测量 | | **配置寄存器** | TIMx_PSC(预分频)、TIMx_ARR(自动重载值)[^4] | TIMx_SMCR(从模式控制,选择外部触发源) | | **应用场景** | 定时中断、周期任务 | 编码器接口、脉冲累加 | #### 3. **工作模式示例** - **定时器模式** 配置为向上计数模式时,计数器从0累加到TIMx_ARR值后产生溢出事件,计算公式: $$ T_{定时周期} = \frac{(TIMx\_ARR + 1) \times (TIMx\_PSC + 1)}{f_{时钟源}} $$ 例如:系统时钟为84MHz,TIMx_PSC=8399,TIMx_ARR=9999,则周期为: $$ T = \frac{10000 \times 8400}{84 \times 10^6} = 1秒 $$ [^1] - **计数器模式** 配置为外部时钟模式1(TI1FP1或TI2FP2),通过GPIO引脚输入脉冲,每个上升沿触发计数。例如: ```c // 配置TIM2通道1为外部计数模式 TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); TIM_SetCounter(TIM2, 0); // 清零计数器 TIM_Cmd(TIM2, ENABLE); // 启动计数 ``` 此时,TIM2的计数值会随外部脉冲递增[^3]。 #### 4. **高级功能重叠** - **输入捕获**:计数器模式下可捕获脉冲宽度(如测量超声波回波时间)。 - **PWM输入模式**:同时测量信号的频率占空比,依赖计数器对外部信号的分析[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值