完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
最近在学习郭天祥老师的单片机教程,遇到很多问题,期间看了很多博客,终于对单片机的定时器有些了解,在此像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 #define uint unsigned int #define uchar unsigned char ***it dula=P2^6; ***it 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整除,所以不能位寻址***t=? 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++; //计数 } |
|
|
|
|
只有小组成员才能发言,加入小组>>
3052 浏览 0 评论
820浏览 1评论
1065浏览 0评论
844浏览 0评论
1022浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-12 00:53 , Processed in 3.511977 second(s), Total 76, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1811
