51单片机的定时器与计数器

发布者:RadiantGaze最新更新时间:2020-05-16 来源: eefocus关键字:51单片机  定时器  计数器 手机看文章 扫描二维码
随时随地手机看文章

1.0

1.0.1定时器

(1)51单片机的定时器是一个内部外设。

(2)定时器相当于CPU的一个“闹钟”。

(3)定时器是用计数器来实现的。


1.0.2计数器

(1)计数器可以计数外部脉冲的个数.

(2)脉冲:(个人理解)单片机中一个低电平跳变成高电平在回到低电平的这么一个过程就称为一个脉冲。


1.0.3定时器是如何工作的

(1)第一步:先设置好定时器的时钟源(AT89C51单片机的时钟源只有一个不需要设置)

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

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

(4)第四步:设置中断处理程序(定时器总是与中断相互配合使用)

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

(6)第六步:定时器计数到后产生中断,然后执行中断处理程序。


1.1寄存器

1.1.0什么是寄存器

(1)register。

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

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


1.1.1寄存器的工作原理

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

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

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


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

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

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

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

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

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


1.2AT89C51定时器介绍

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

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


1.3定时器的主要寄存器介绍

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) TH0 TL0中写入的值计算:

假如要写入1000.那么1000所对应的16进制为:0x3E8高八位为:0x03 低八位为:0XE8

也可以是TL0 = 1000 %256 TH0 = 1000 / 256;

1000 = 0x3E8 = 高0x3 低0xE8 => TL0 = 0xE8 TH0 = 0x3

要写入8888也一样。

8888 = 0x22B8 = 高0x22 低0xB8 => TL0 = 0xB8 TH0 = 0x22


(6)我们开发板的定时器最多能订多长时间?

内部时钟频率是1MHz,时钟周期是1us。最多能定65535(16位定时器),也就是说最大定时时间为65535*1us=65535us=65.535ms。

如果要定比较长的时间(譬如2s),定时器直接是不能满足的,解决办法是多次定时后加起来构成一个长时间。


1.4加法定时器与减法定时器

加法定时器和减法定时器

(1)定时器的原理就是计数器,加法定时器计数方法是从我们给定的值开始计数,直到溢出(譬如16位定时器最大值为0xffff,也就是65535,计数值到达这个值就溢出了)。减法定时器是从我们给定的值开始减1,减到0就溢出了。

(2)实例来看,譬如16位定时器。我们设置的计数值为1000,则如果是减法定时器那么计数个数就是1000,如果是加法定时器则计数个数就是65535-1000=64535.

(3)51单片机就是典型的加法定时器

(4)现代的单片机或者嵌入式soc,一般常用的都是减法定时器了。虽然加法定时器和减法定时器都能实现功能,但是明显减法定时器更加直观。


#include


//利用定时器实现数码管显示0-F依次显示的同时 LED灯每1s闪烁一次。

//定时器选用定时器0:


/*

接线:

矩阵键盘:P1端口

数码管:  P0端口

*/

#define DIG P0


sbit LED = P3^0;


unsigned char count = 20; //20次,对应1s。

void delay(unsigned char t);


//独立数码管的显示0-F

unsigned char varry[16] = 

{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};


void Timer0_Isr() interrupt 1 using 1 // interrupt 1

{

TL0 = (65535 - 50000) / 256;

TH0 = (65535 - 50000) % 256;

if(count-- == 0)

{

count = 20;

LED = !LED;

}

}

void main(void)

{

unsigned char i = 0;


TMOD = 0x01; //定时器模式寄存器:0x01表示16位定时器,TL0 TH0全用


//51单片机的定时器是加法定时器,要注意初值的计算。

TL0 = (65535 - 50000) / 256;

TH0 = (65535 - 50000) % 256;

TR0 = 1;   //定时器0的运行控制位,该位由软件置位或清0. TR=1表示允许开始记数

ET0 = 1;       //T0中断溢出允许位,也就是打开中断

EA = 1;   //打开中断总开关

count = 20;


while(1)

{  

for(i=0; i<16;i++)

{

DIG = varry[i];

delay(200); //大概延时,能看出变化就好。

}

}

}


void delay(unsigned char t)

{

unsigned char i,j;

for(i=0;i for(j=0; j

}


逻辑取反与按位取反?

在51单片机中实现LED的翻转,得以LED闪烁。

sbit LED = P3^0;

LED = !LED;

LED = ~ LED;竟然都可以达到效果!!!


using 关键字的使用


(1)目前还没有完全搞懂用法:但是我在以上的程序中实验了一下:0-3(4及其以上是不存在的,编译器报错)

using 0 的情况下数码管的显示切换速度变快了,而且快了很多。

using 1 2 3 这三个没有区别。(就是简单的实验现象上没有区别)

去掉using 0 的数码管显示与using 1 2 3 速度一样。(肉眼观察)


以下是网友总结的:原文链接:http://www.51hei.com/mcu/766.html


using关键字的作用就是指定某个函数在执行时切换寄存器组的

51中有四个寄存器组,每个组有R0-R7这8个寄存器,用于CPU的数据处理,一般主函数main()默认使用第0组,因为PSW寄存器的初始值的第3、4位是00嘛,即默认指定了第0组。using 0就是指定在执行函数时切换为使用第0组,不加using关键字的话,一般都默认使用第0组,但这样的话在调用其他函数(包括中断服务函数)的时候,就会加入一些压栈指令以保护原来的R0-R7寄存器的(这样的话,程序执行会效率会低一点,因为会产生很多个指令是用来压栈出栈的),照这样说,只是加了using 0,使用的也是第0组又不是其它的组,程序就不应该有问题了吧,但是就是因为加了using 0,编译了一次,才发现在定时器中断函数t0()的入口中并没有发现把R0-R7的代码压入栈呀,就是说没有保护好R7呀,那当然就是在执行完之后回来R7不能回复原来的值啦,接下来的事情。。。。我就不说啦,这就是问题的根源,去掉using 0就可以了,编译器就自动帮你将R0-R7压栈,手动加了using 0,就是让编译器以为之前用的并不是第0组,而现在执行这个中断函数时就切换到第0组,而省去了将R0-R7这8个寄存器压入栈的指令了,这样虽然看起来是快了,然而对于这个程序来说却是致命的问题!!!因为根本没有保护好R0-R7,而没有保护R7并不是我预期发生的!!!这不是编译器的问题,是自己没有了解好、用好using的问题啊!还有,其实也可以在编译器选项里有选项来硬性规定编译器统一不直接使用寄存器而是使用间接寻址的办法来改变循环变量分配的地址的,或者使用。

关键字:51单片机  定时器  计数器 引用地址:51单片机的定时器与计数器

上一篇:51单片机第二讲(定时器中断)
下一篇:c51中断计数器

推荐阅读最新更新时间:2024-11-13 10:07

STM32CUBEMX配置定时器门控模式
打开keil5的debug,选中view- system viewer- Tim- Tim3,然后开始按F5运行。 当PA6接高电平时,开始计数,cnt开始自增。 当PA6接低电平时,停止计数,cnt停止自增。
[单片机]
STM32CUBEMX配置<font color='red'>定时器</font>门控模式
51单片机综合学习系统之 红外线遥控篇
大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉,学会了12864点阵型液晶显示的基本知识,体会到了综合学习系统的易用性与易学性,这一期我们将一起学习红外线遥控的基本原理与使用方法。 先看一下我们将要使用的51单片机综合学习系统能完成哪些实验与产品开发工作:分别有流水灯,数码管显示,液晶显示,按键开关,蜂鸣器奏乐,继电器控制,IIC总线,SPI总线,PS/2实验,AD模数转换,光耦实验,串口通信,红外线遥控,无线遥控,温度传感,步进电机控制等等。 上图是我们将要使用的51单片机综合学习系统硬件平台,本期实验我们用到了综合系统主机,1602液晶屏、超薄型红外线遥控
[单片机]
<font color='red'>51单片机</font>综合学习系统之 红外线遥控篇
查表指令(2条)举例——mcs51单片机汇编语言
查表 指令 (2条) 这组指令的功能是对存放于程序存储器中的数据表格进行查找传送,使用变址寻址方式: MOVC A,@A+DPTR ;((A))+(DPTR)→(A) 表格地址单元中的内容送到累加器A中 MOVC A,@A+PC ;((PC))+1→(A),((A))+(PC)→(A) 表格地址单元中的内容送到累加器A中 本指令是将ROM的数据送入A中,本指令也被称为查表指令,常用此指令来查一个已做好在ROM中的表格。 说明: 1、此条指令引出了一个特殊的寻址方式,即变址寻址,在上节课时我们已进行过讲解,本指令是要在ROM的一个地址单元中找出数据,显然必须知道这个单元的地址,这个单元的地址是这样确定的:在执行本指令立脚点
[单片机]
80C51单片机实现专用寄存器位寻址的设计方案
80C51单片机有位处理功能,可以对数据位进行操作,因此就有相应的位寻址方式。所谓位寻址,就是对内部RAM或可位寻址的特殊功能寄存器SFR内的某个位,直接加以置位为1或复位为0。 位寻址的范围,也就是哪些部份可以进行位寻址: 1、我们在第十二课学习51单片机的存储器结构时,我们已知道在单片机的内部数据存储器RAM的低128单元中有一个区域叫位寻址区。它的单元地址是20H-2FH。共有16个单元,一个单元是8位,所以位寻址区共有128位。这128位都单独有一个位地址,其位地址的名字就是00H-7FH。 这里就有一个比较麻烦的问题需要大家理解清楚了。我们在前面的学习中00H、01H。。。。7FH等等,所表示的都是一个字节(或者
[单片机]
80C<font color='red'>51单片机</font>实现专用寄存器位寻址的设计方案
STM32F4定时器初始化的含义
最近在弄STM32以太网的时候,看到定时器的中断,发现忘记了一些定时器的内容。 比如STM32F4的初始化定时器,TIM3_Int_Init(5000-1,8400-1);这一句就没有理解了,这个是多久进入一次的定时器中断呢? 赶紧去翻了一下我之前STM32定时器的网页收藏夹。写下这篇文章记录一下。 定时器的参考链接:STM32定时器 先说结论, TIM3_Int_Init(5000-1,8400-1)这一句是0.5s进入一次的中断。正点原子的中断代码,8400是分频系数,5000是预装载值。我们使用的是TIM3.根据时钟树,可以知道TIM3挂载在APB1下,APB1的时钟频率是=42MHZ,但是因为我们分频系数不等于1,所
[单片机]
s3c6410在linux下的WATCHDOG TIMER(看门狗定时器)驱动(2)
在上一篇中看了看门狗在linux中驱动实现的整体架构,作为混杂设备和平台设备存在。现在开始看平台设备对应的probe函数。 static struct platform_driver s3c2410wdt_driver = { .probe = s3c2410wdt_probe, .remove = s3c2410wdt_remove, .shutdown = s3c2410wdt_shutdown, .suspend = s3c2410wdt_suspend, .resume = s3c2410wdt_resume, .driver = { .owner = THIS_MODULE, .name = s3c2410-wdt
[单片机]
s3c6410在linux下的WATCHDOG TIMER(看门狗<font color='red'>定时器</font>)驱动(2)
步进电机控制+普中51单片机+普中官方
1 实验现象 通过ULN2003驱动模块控制28BYJ48步进电机运行方向及速度,当按下KEY1键可调节电机旋转方向;当按下KEY2键,电机加速(5档);当按下KEY3键,电机减速(5档);同时将电机转速档位显示在数码管上。 2 实验原理 (1)步进电机必须加驱动才可以运转,驱动信号必须为脉冲信号,没有脉冲的时候,步进电机禁止,加入适当的脉冲信号,就会以一定的角度(成为步角)转动。转动的速度和脉冲的频率成正比。 (2)步进电机具有瞬间启动和急速停止的优越特性; (3)改变脉冲的顺序,可以方便的改变转动的方向。 3 系统框图 4 硬件设计 见《普中-2&普中-3&普中-4开发板原理图》:独立按键模块、单片机核心
[单片机]
步进电机控制+普中<font color='red'>51单片机</font>+普中官方
AT89S51单片机的低频信号仿真研究
1 设计目标和思路 文中设计目标是完成4种波形信号输出,即正弦波、三角波、方波和锯齿波,并使其在低频范围内具有稳定稳定性好、性能可靠、体积较小、占空比调节方便等技术优势。文中采用键盘控制的办法,来实现并输出方波、锯齿波、三角波和正弦波等信号。另外,对频率和幅值的变换情况,用键盘也能够较好的进行控制和调整。同时,本文还将其产生的信号参数用LCD进行仿真显示和调试。 在设计中,首先在函数中对某个数组附值,利用DAC0832来实现输出波形信号输出转换,再经过功放滤波模块处理,这样的话,就会在示波器上观察到不同函数值的波形信号。但是,因为函数对数组中的数附值之后并不是一次就输出显示出来,这就需要编写AT89S51的控制字,使其开中
[单片机]
AT89S<font color='red'>51单片机</font>的低频信号仿真研究
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved