赞
踩
最近在学习郭天祥老师的单片机教程,遇到很多问题,期间看了很多博客,终于对单片机的定时器有些了解,在此像CSDN优秀的博主表示感谢,由于这是我第一次写博客(研究内容很浅)为了以后复习方便以及希望各位优秀的童鞋帮我指正错误哈哈
最后再废话一句,本人学的很菜,不懂得东西太多了,写的也肯定,,,,所以不喜勿喷哟,,,,
言归正传:
定时器/计数器:顾名思义既能定时又能计数。它存在于单片机内部的一个独立硬件部分,依赖晶振产生固定的时间间隔,产生一定的时间间隔后会引起定时器中断,从而产生的时间信息传送给主程序。
51单片机有2个定时器,分别是T0和T1,52单片机比51单片机多了一个T2定时器,但51和52的定时器设置差不多。
首先解释一下常规概念:
周期:周期是物体循环一周的时间
频率:1秒钟内循环的次数
(补充下:单片机是靠脉冲来工作的,一个脉冲产生一个操作)
单片机中包括四个周期:分别是时钟周期、机器周期、指令周期、状态周期
时钟周期:也叫振荡周期,定义为时钟脉冲(晶振频率)的倒数
即产生一个脉冲的时间。例如12M晶振,时钟周期是1/12us
机器周期:单片机访问一次存储器的时间,称为一个机器周期。以51单片机为例,它有固定的机器周期,一个机器周期包含六个状态例如,取指令、存储器读、存储器写等。即机器周期等于6个状态周期,而一个状态周期是2个时钟周期,因此一个机器周期又等于12个时钟周期。单片机的晶振最常用的是12MHZ,11.0592MHZ,当晶振是12MHZ时:时钟周期是1/12us,机器周期是12*(1/12us)=1us,产生一次机器周期的时间是1us,也就是向寄存器每传入1个数,机器周期的时间是1us. 11.0592MHZ的晶振同理。
定时器的应用举例(数码管1、3、5个亮,时间间隔是1s,以12M的晶振为例,本程序只涉及定时器T0,16位)
设计思路:以12Mhz的晶振来说,机器周期是1us,计满TH0、TL0就需要2^16-1个数,再来一个数就“溢出”产生中断,一次溢出也就是65536us,约等于65.5ms,所以定时时间1s超出范围,因此需要进入中断20次,每次中断50ms。
1. 对TMOD赋值,以确定T0和T1的工作方式
本文只涉及T0,所以令T1定时器端口全为0,对于T0定时器:门控位GATE=0,C/T=0(定时器模式) ,M1M0=01(方式一为16位定时计数器)。所以TOMD=0x01
2. 计算初值,并将其写入TH0、TL0和TH1、TL1
假设单片机的晶振的频率是12MHZ,那么一个机器周期的时间就是1us,计满TH0、TL0就需要2的16次方-1个数,再来一个数就“溢出”产生中断,一次溢出也就是65536us,约等于65.5ms,因此如果我们要定时65.5ms的话,就可以这样做,但是定的时间如果不是65.5ms的话,则需要装入定时器中一个初值。假设我们要计数的个数是N个,设装入的初值是X,则X=2^16-N,比如要装50000个数的话,初值X=65536-50000=15536,然后把15536对256取模15536/256=60装入TH0中,15536%256=176装入TL0中。因为实验板上的晶振是11.0592MHZ,可知机器周期=1.09us,比如说我们要定时50ms(50000us)那么计数的个数是N=50000/1.09=45872,再计算初始值X=65536-45872=19664,,再分别计算TH0和TL0中具体装多少就可以了。(本文是以12M晶振为例)
3. 中断发生时,则对IE赋值,开放中断
图为中断允许控制位
开总中断EA=0;
外部中断允许控制位EX0=1,允许外部中断0中断
4. 使TR0和TR1置位,启动定时/计数定时器定时或计数
TR0=1,启动定时/计数器定时或者计数
下面展示一些 内联代码片
。
/* 将定时器0设置为1s,进入中断一共20次,每次进入中断50ms 现象:1/3/5数码管显示从0到F静态*/ #include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit dula=P2^6; sbit wela=P2^7; uchar num,tt; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 }; void main() { num=0; tt=0; TMOD=0x01;//设置定时器0位工作方式1 ,由于TMOD的字节地址是89H,不能被8整除,所以不能位寻址sbt=? TH0=(65536-50000)/256; //计算初值:高8位 TL0=(65536-50000)%256; //计算初值:低8位 EA=1;//开总中断 ET0=1;//开定时器0中断 TR0=1;//启动定时器0 开始定时,计50ms时马上进入中断子程序 wela=1; P0=0xEA; //第1、3、5个数码管全是0;最高位和次高位全是1,低电平有效 1、、3、、5亮 wela=0;//27、28、29三句是打开位选信号 dula=1;//开段选 P0=0x3f;//开始数码管显示0 dula=0;//关段选 while(1) { if(tt==4)//只有进入中断20次,(每进去一次中断时间为50ms)才有可能tt=20 { tt=0; num++;//依次加一 if(num==16) num=0; dula=1; P0=table[num]; dula=0; } } } void exter0() interrupt 1 //当设置的初值加满才进去中断 { TH0=(65536-50000)/256; //计算初值:高8位 TL0=(65536-50000)%256; //计算初值:低8位; tt++; //计数 }
下面是我参考的一些博客,希望对大家有所帮助
http://bbs.elecfans.com/jishu_178566_1_1.html
https://blog.csdn.net/weixin_42119585/article/details/103587848
这是我的第一篇博客,写的不好大家多多指导,大家一起加油
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。