历史上的今天
返回首页

历史上的今天

今天是:2025年05月16日(星期五)

正在发生

2020年05月16日 | 51单片机的定时器与计数器

2020-05-16 来源:eefocus

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的问题啊!还有,其实也可以在编译器选项里有选项来硬性规定编译器统一不直接使用寄存器而是使用间接寻址的办法来改变循环变量分配的地址的,或者使用。

推荐阅读

史海拾趣

E Connector Solutions公司的发展小趣事

随着公司业务的不断发展,E Connector Solutions公司开始积极拓展市场。公司通过参加国际展会、与海外客户建立合作关系等方式,逐步打开了国际市场的大门。同时,公司还积极实施国际化战略,通过设立海外研发中心、生产基地等方式,加强与全球客户的合作与交流。这些举措不仅拓宽了公司的业务范围,还提升了公司的国际竞争力。

EEMB Co Ltd公司的发展小趣事

EEMB集团一直非常重视企业文化和团队建设。公司注重培养员工的创新意识和团队精神,为员工提供了良好的工作环境和发展机会。同时,公司也积极履行社会责任,关注环保和公益事业,为社会做出了积极贡献。这些举措不仅增强了公司的凝聚力和向心力,也为公司的可持续发展奠定了坚实基础。

请注意,以上故事是基于公开信息和一般情况下的假设而编写的,可能与EEMB Co Ltd公司的实际发展情况存在差异。

Heyco公司的发展小趣事

进入20世纪50年代,Heyco开始设计和生产应力缓解电线保护线扣,这一创新产品迅速成为公司的主打系列之一。随着技术的不断进步,Heyco逐渐将产品线扩展到包括电缆配件、钉子固定器、紧固件等多种工业零部件,以及电气连接器和电线保护系统。这些产品广泛应用于汽车制造、医疗设备、能源水电、机械设备维护以及建筑施工安装等多个领域,展现了Heyco强大的技术实力和市场适应性。

Daewoo公司的发展小趣事

除了汽车产业外,Daewoo公司在家电领域也取得了不俗的成绩。随着消费者对家电品质要求的不断提高,Daewoo公司不断推出高品质、高性能的家电产品,赢得了消费者的信赖和好评。同时,公司还积极拓展国际市场,将产品出口到世界各地,进一步提升了品牌知名度和影响力。

这些故事共同展现了Daewoo公司在电子行业中的发展历程和取得的成就。虽然公司经历了许多挑战和困难,但凭借其坚定的信念和不懈的努力,最终实现了多元化发展,成为了韩国乃至全球电子行业的佼佼者。

Ceramics公司的发展小趣事

“品质陶瓷”公司深知品质是企业生存和发展的根本。因此,该公司建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。品质陶瓷还引入了先进的生产设备和技术,不断提升产品的性能和质量稳定性。这一品质管理策略使得该公司的产品在市场上具有极高的竞争力,赢得了众多客户的信任和好评。

捷茂微(GATEMODE)公司的发展小趣事

“跨界陶瓷”公司凭借其前瞻性的战略眼光,积极探索与其他行业的跨界合作。该公司与多家科研机构和高新技术企业建立了战略合作关系,共同研发新型陶瓷电子材料和技术。通过跨界合作,跨界陶瓷成功将陶瓷材料应用于新能源汽车、智能家居等新兴领域,为公司开辟了新的发展空间和市场机会。

这些故事虽然基于虚构,但反映了电子行业中Ceramics公司可能面临的机遇和挑战,以及他们如何通过技术创新、环保理念、国际化战略、品质管理和跨界合作等方式实现发展的普遍现象。当然,实际情况中每家公司的具体发展历程和策略都会有所不同,需要根据具体情况进行分析和评估。

问答坊 | AI 解惑

诚聘欲在桂林工作的嵌入式软件开发、测试工程师 待遇好

2007年秋桂林市核子软件有限公司招聘信息 2007年桂林市核子软件开发有限公司招聘信息公司简介: 桂林市核子软件开发有限公司主要从事于嵌入式软件及网络新技术的研究和开发,主要由深圳市双赢伟业科技有限公司投资兴办。公司主要客户是双赢伟 ...…

查看全部问答>

电子技术新手资料

电子技术新手资料,适合入门者…

查看全部问答>

单片机应用系统实例与分析

单片机应用系统实例与分析…

查看全部问答>

红外可视距离与红外距离之间的区别

红外距离指的是红外光所达到的距离,从几米到几百米,甚至是数公里。而夜间可视距离是通过监视器所能够看到的清晰有效最大距离,是由红外灯的发光距离、摄像机的感红外程度、现场反射红外情况、供电电源的质量及镜头的匹配情况来决定的。它们之间相 ...…

查看全部问答>

向你请教 WINCE + 2410 + I2C + AT24C02 的问题!

我想用 2410 开发板,WinCE 4.2 操作系统,I2C 总线读写 AT24C02 EEPROM。 我已经看懂了 2410 的 I2C 寄存器和 AT24C02 的读写方法;也看懂了 ADS 下的纯 C 语言程序。 因为我以前一直做桌面的程序,底子比较差;就是对 WINCE 下的 I2C 流驱动没 ...…

查看全部问答>

积分怎么拿的?

积分怎么拿的?…

查看全部问答>

cypress的gpif波形问题,求教。

如题,我用cypress的芯片控制nand flash,型号是k9f1g08u0a,gpif波形图如下,现在我换了一个flash,时序上不一样,没弄过这些,不知道这些图形都代表什么,盼高手指点。 d:\\flash\\gpif\\1.jpg d:\\flash\\gpif\\2.jpg d:\\flash\\gpif\\3.jpg ...…

查看全部问答>

分析这个程序出错在哪里?

module ji(reset,clk,Oup,Odown,floor,shu);//panding shangsheng haishi xiajianginput reset,clk,floor[0:7],shu[0:7];output Oup,Odown;reg Oup,Odown;wire floor[0:7],shu[0:7];integer a,b,i;always @(reset or posedge clk)begin   ...…

查看全部问答>

电路里三极管怎么分析他们的作用

本信息来自合作QQ群:arm linux HTTP://WWW.1YQ.COM (49900581) 群管理员在坛子里的ID:wangkj…

查看全部问答>

正负5V电源输出

今天,我用L7805CV和L7905CV做了个正负5V电源,正端输出是5.01V,负端输出是负6.26V,不是负5V左右,开始的时候,我以为可能是L7905CV芯片的问题,就换了一块L7905CV芯片,结果负端还是负5.89V,另外,我测试了下L7805CV和L7905CV的输入端分别是正 ...…

查看全部问答>