1、51 单片机的定时器_计数器的 C51 编程相关知识点:1、单片机的定时器/计数器,实质是按一定时间间隔、自动在系统后台进行计数的。2、当被设定工作在定时器方式时,自动计数的间隔是机器周期(12 个晶振振荡周期) ,即计数频率是晶振振荡频率的 1/12;3、当定时器被启动时,系统自动在后台,从初始值开始进行计数,计数到某个终点值时(方式 1 时是65535) ,产生溢出中断,自动去运行定时中断服务程序;注意,整个计数、溢出后去执行中断服务程序,都是单片机系统在后台自动完成的,不需要人工干预!4、定时器的定时时间,应该是(终点值-初始值)x 机器周期。对于工作在方式 1 和 12MHz 时钟的单
2、片机,最大的计时时间是(65535-0 )x1uS=65.535ms。这个时间也是一般的 51 单片机定时器能够定时的最大定时时间,如果需要更长的定时时间,则一般可累加多定时几次得到,比如需要 1 秒的定时时间,则可让系统定时 50ms,循环 20 次定时就可以得到 1s 的定时时间。5、定时器定时得到的时间,由于是系统后台自动进行计数得到的,不受主程序中运行其他程序的影响,所以相当精确;6、使用定时器,必须先用 TMOD 寄存器设定 T0/T1 的工作方式,一般设定在方式 1 的情况比较多,所以可以这样设定:TMOD=0x01(仅设 T0 为方式 1,即 16 位)、TMOD=0x10( 仅
3、设 T1 为方式 1,即 16 位) 、TMOD=0x11(设 T0 和 T1 为方式 1,即都为 16 位)。7、使用定时器,必须根据需要的定时时间,装载相应的初始值,而且在中断服务程序中,很多情况下得重新装载初始值,否则系统会从零开始计数而引起定时失败;8、要使用定时器前,还必须打开总中断和相应的定时中断,并启动之:EA=1(开总中断) 、ET0=1(开定时器 0 中断)、TR0=1(启动定时器 0)、ET1=1(开定时器 1 中断) 、TR1=1( 启动定时器 1);9、注意中断服务程序尽可能短小精干,不要让它完成太多任务,尤其尽量避免出现长延时,以提高系统对其他事件的响应灵敏度./定时
4、器基本例程-1(未使用定时器,一个灯每隔 500ms 亮灭一次)/这是个特意安排的例程,以便与下面的例程 2 进行对比#include sbit led=P27;void delay_ms(unsigned int xms); /ms 级延时子程序/=void main()led=1; /上电初始化,led 灯不亮while(1)led=!led;delay_ms(500);/=void delay_ms(unsigned int xms) /ms 级延时子程序 unsigned int x,y; for(x=xms;x0;x-)for(y=130;y0;y-);/-/定时器基本例程-2(使用
5、定时器,一个灯每隔 500ms 亮灭一次)#include sbit led=P27;unsigned char num;void delay_ms(unsigned int xms); /ms 级延时子程序/=void main()led=1; /上电初始化,led 灯不亮TMOD=0x01; /设定定时器 0 为工作方式 1TH0=(65536-50000)/256; /装载初始值, 12MHZ 晶振 50ms 数为 50000TL0=(65536-50000)%256; /EA=1; /开总中断ET0=1; /开定时器 0 中断TR0=1; /启动定时器 0while(1)delay_m
6、s(8000);/=void delay_ms(unsigned int xms) /ms 级延时子程序 unsigned int x,y; for(x=xms;x0;x-)for(y=130;y0;y-);/- void led_flash() interrupt 1 /使用了定时中断 0 的 led 闪烁子函数 TH0=(65536-50000)/256; /装载初始值,12MHZ 晶振 50ms 数为 50000TL0=(65536-50000)%256; /num+;if(num=10)num=0;led=!led;/定时器基本例程-3/(使用定时器 T1,单片机整个口接的 8 个灯每
7、隔 500ms 亮灭一次)#include #define led_port P0 /宏定义,具体的端口尽量不要出现在主函数和主函数中unsigned char num;void delay_ms(unsigned int xms); /ms 级延时子程序/=void main()led_port=0xff; /上电初始化,所有 led 灯不亮TMOD=0x10; /设定定时器 1 为工作方式 1(16 位方式)TH1=(65536-50000)/256; /装载初始值, 12MHZ 晶振 50ms 数为 50000TL1=(65536-50000)%256; /EA=1; /开总中断ET1=
8、1; /开定时器 1 中断TR1=1; /启动定时器 1while(1)delay_ms(8000); /这句表明定时中断的运行是在系统后台自动运行的,不需要主函数“操心”/=void delay_ms(unsigned int xms) /ms 级延时子程序 unsigned int x,y; for(x=xms;x0;x-)for(y=130;y0;y-);/- void led_flash() interrupt 3 /使用了定时中断 1 的 8 灯闪烁子函数 TH1=(65536-50000)/256; /装载初始值,12MHZ 晶振 50ms 数为 50000TL1=(65536-5
9、0000)%256; /num+; /计数if(num=10) /计够 10 次,时间就是 10x50ms=500msnum=0; /清零,以便进行下一次 500ms 的 10 次计数led_port=led_port; /整个口接的 led 灯亮灭状态翻转/-/定时器基本例程-4/(同时使用定时器 T0 和定时器 T1,单片机某个口的灯和某个口接的 8 个灯每隔 500ms亮灭一次)#include sbit led=P27;#define led_port P0 /宏定义,具体的端口尽量不要出现在主函数和主函数中unsigned char num_0,num_1;void delay_ms
10、(unsigned int xms); /ms 级延时子程序/=void main()led=1; /上电初始化,led 灯不亮led_port=0xff; /上电初始化,该口所有 led 灯不亮TMOD=0x11; /设定定时器 0 和定时器 1 都为工作方式 1(16 位方式)TH0=(65536-50000)/256; /装载初始值, 12MHZ 晶振 50ms 数为 50000TL0=(65536-50000)%256; /TH1=(65536-50000)/256; /装载初始值, 12MHZ 晶振 50ms 数为 50000TL1=(65536-50000)%256; /EA=1;
11、 /开总中断ET0=1; /开定时器 0 中断TR0=1; /启动定时器 0ET1=1; /开定时器 1 中断TR1=1; /启动定时器 1while(1)delay_ms(8000); /这句表明定时中断的运行是在系统后台自动运行的,不需要主函数“操心”/=void delay_ms(unsigned int xms) /ms 级延时子程序 unsigned int x,y; for(x=xms;x0;x-)for(y=130;y0;y-);/-void led_flash() interrupt 1 /使用了定时中断 0 的 led 闪烁子函数 TH0=(65536-50000)/256;
12、 /装载初始值,12MHZ 晶振 50ms 数为 50000TL0=(65536-50000)%256; /num_0+; /计数if(num_0=10) /计够 10 次,时间就是 10x50ms=500msnum_0=0; /清零,以便进行下一次 500ms 的 10 次计数led=!led; /led 灯亮灭状态翻转/- void led_all_flash() interrupt 3 /使用了定时中断 1 的 8 灯闪烁子函数 TH1=(65536-50000)/256; /装载初始值,12MHZ 晶振 50ms 数为 50000TL1=(65536-50000)%256; /num_
13、1+; /计数if(num_1=10) /计够 10 次,时间就是 10x50ms=500msnum_1=0; /清零,以便进行下一次 500ms 的 10 次计数led_port=led_port; /整个口接的 led 灯亮灭状态翻转/-/定时器基本例程-5/设定定时器 T0 工作在方式 1 的计数应用状态,/单片机 T0 口(P3.4)接一个按键充当外部脉冲源,/系统对进来的脉冲(每按一次键得一脉冲)进行计数,/计数的结果用接在单片机 P0 口的 8 个 LED 灯表示出来/(大家也可以改成用 1602LCD 来显示,这样更直观)/广西民大物电学院 李映超 2010 年 4 月 14 日
14、#include #define led_port P0 /宏定义,具体的端口尽量不要出现在主函数和主函数中/=void main()TMOD=0x05; /设定定时器 0 为工作方式 1、计数器TH0=0; /清零TL0=250; /TR0=1; /启动定时器 0 进行计数while(1)led_port=TL0; /将计数结果送去显示(用 8 个 LED 灯显示) ,/这里仅显示 16 位计数器的低 8 位定时器 0 仍旧工作在计数器状态,增加定时器 1 工作在定时状态,得到 1s 的定时时间,定时时间到后,将定时器 0 计数得到的脉冲数去显示,则这个脉冲数就是所输入的外部信号的频率,从而构成一个简单而准确的频率计!不过,这个简单的“频率计” 能够计量的信号频率(脉冲数) ,受单片机中断响应速度的影响,一般只能达到单片机系统时钟晶振的 1/24,所以要能够测量更高的频率,必须使用前置分频器,对更高频率的待测输入信号进行预分频!