51单片机定时器/计数器中断的定义与外部中断

然后就是如何使用计数器中断了C为Couter,计数器模式,T为Timer,定时器模式;T上面有横杠,说明是0有效;Timer模式的时候,使用系统内部时钟输入;Couter模式的时候,使用T0/1引脚输入;

首先,定时器的计数是加1,而不是减1。当加到最大值时,再次加1就会变成0,此时会触发计数器中断。 51中常用16位计数器,最大值为65535。如果要计数1000次,那么计数器分配应该为65535-1000+1(达到最大值后需要再加一次。 )计数器的初始值放在两个8位寄存器中,它们是TH0和TL0(计数器0的高8位和低8位)。 计数器1使用TH1和TL1,原理是一样的。

65535-1000+1=64536=0xFC18

所以

TH0=0xFC;

TL0=0x18;

上面我们要求计时器计数 1000 次,但我们想要的是固定的持续时间,而不是固定的次数。 一千次有多长? 我们需要计算计数器加 1 所需的时间。

计数器加1需要1个机器周期,1个机器周期等于6个状态周期和12个振荡周期。 如果51芯片的频率为12MHz,那么振荡周期为1/12M秒,机器周期为12×1/12M秒,即1/1M秒,即1/1000000秒,即1微秒。

计数1000次是1毫秒;

然后就是如何使用计数器中断

计数器中断定义和外部中断定义具有相同的格式,如下:

void timer0() interrupt 1

一旦定义完毕,就该让它正常工作了。

	TMOD=0x11; //这种计数器0和1的工作模式,高4位设置计数器1,低4位设置计数器0,我们都设置在工作模式1上。
	EA=1;  //中断的全局是能开关,使用任何中断都需要打开
	ET0=1; //计数器0中断允许控制位
	ET1=1; //计数器1中断允许控制位
	TR0=1; //计数器工作开关,1-开始工作; 0-停止工作
	TR1=1; //同上

TMOD各字段含义:

GATE:为1时,与INT0/1引脚一起控制计数器0/1。 我们默认使用0,不受INT0/1控制;

C/T:C为Couter,计数器模式,T为Timer,定时器模式; T上方有横条,表示0有效; 在Timer模式下,使用系统内部时钟输入; 在Couter模式下,使用T0/1引脚输入;

M1M0两位构成4种工作模式:

以下是实现LED状态每秒翻转的完整代码实现:

#include
typedef unsigned char u8;
typedef unsigned int u16;
sbit LED1=P2^0;
sbit LED2=P2^1;
void timerInit()
{
	TMOD=0x11;
	EA=1;  
	ET0=1; 
	ET1=1;
	TR0=1;
	TR1=1;
	TH0=0xFC;
	TL0=0x6A;
	TH1=0xFC;
	TL1=0x6A;
}
void timer0() interrupt 1
{
	static u16 counter=0;
	if(counter==1000)
	{
		LED1=~LED1;
		counter=0;
	}
	counter++;
	TH0=0xFC;
	TL0=0x6A;
}
void timer1() interrupt 3
{
	static u16 counter=0;
	if(counter==1000)
	{
		LED2=~LED2;
		counter=0;
	}
	counter++;
	TH1=0xFC;
	TL1=0x6A;
}
void main()
{
	timerInit();
	while(1);
}

我们代码中的计数值不是0xFC18,而是0xFC6A,因为我使用的单片机频率不是12MHz,而是11.018398MHz。

单片机

如何选择合适的晶振?时候需要注意哪些细节?

2024-5-10 22:03:15

单片机

18个免登陆直接下载的神仙壁纸网站,让自己天天焕新

2024-5-10 23:02:56

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索