定时器中断实现计数

这个程序写了好几次,但每次重写的时候,感觉又无从下手。

在写这个程序时,先把每个寄存器及其功能又全部熟记和理解,这个程序是凭自己的理解写出来的,每个步骤该干嘛,该解决哪些问题。

#include "reg51.h"

typedef unsigned int u16;

// 数字 0 ~ 9
unsigned char digit[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

/**
    实现每隔3秒,数码管数字0~9
**/

/**
	要设置中断,需要先解决一下问题:
	(1) 要设置什么中断?
	    中断C51有5个: T1  T0  TI/RI  INT0  INT1


	定时器/计数器中断设置:
	(1) 要使用哪个中断?T0 ? T1
	    由TMOD寄存器和TCON寄存器共同决定:
		GATE=0 && (TR0=1 || TR1=1)
		GATE=0 && (TR0=1 || TR1=1) && 外部中断(INT0/INT1)
	(2) 使用哪个工作方式
		由TMOD寄存器的M1和M1决定  (共4中方式可选择)
	(3) 定时或记数多少? 即确定初始值
		由时钟频率 和 要计数的值决定.  12个时钟周期为一个机器周期
	(4) 打开中断:
		a) 打开某个定时器中断
		b) 打开总中断
	(5) 启动定时器工作
	(6) 设置中断函数
**/

void init()
{
	// GATE: 0  ==> 哪个定时器有TCON的TRX决定
	// C/T : 0  ==> 为定时器模式
	// M0M1: 01	==> 工作方式1 为16位定时器/计数器
	TMOD = 0x01;
	TH0  = 0x3C;  // 初始值 定时50ms中断一次
	TL0  = 0xB0;
	ET0  = 1;  // 打开t0中断
	EA = 1; // 打开总中断
	TR0  = 1;	  // 启动定时器1开始工作  (这个应该放到中断全部设置完毕后,作为一个开关再设置)
}

u16 index = 0;

// 显示数字
void Show()
{
	P0 = digit[index];
}

void main()
{
	init();
	while(1){
		Show();	
	}	
}

// 中断处理函数
void timer0() interrupt 1
{
	static u16 num = 0; // 一次中断50ms, 60次中断为3s
	num++;
	if(60 == num) {
		num = 0;
		index++;
		if(index == 10)
			index = 0;
	}
}

发表评论