timer2.c

来自「太欣单片机STK6031的测试程序」· C语言 代码 · 共 176 行

C
176
字号

#include "STK6031.h"

//********************************************************************************
//定义数据类型
typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;

sbit P4_0 = P4^0;

//以下宏定义用来选择TIMER2 工作方式

#define CAP_RL   1

/*
********************************************************************************  
* 	函 数 名:InitMCU
* 	功能描述:初始化MCU,其中包括初始化各I/O口,CHIPCON,
                              CKCON
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/	

void InitMcu(void)
{
	P0		= 0xFF;      //初始化各I/O 口
	P1		= 0xFF;
	P2 		= 0xFF;
	P3		= 0xFF;
	P4 		= 0x0F;

	CHIPCON = 0x1A;  // 设置CPUCLK=XTAL1/3,允许访问片内AUX 存储器,禁止ALE 输出,允许低电压复位
	CKCON = 0x39;  // 设置TIMER0,TIMER1,TIMER2 的计数频率为CPUCLK/4, 设置MOVX 指令访问外部AUX 存储器的时间为3 个机器周期
	
}


#if CAP_RL

sbit P1_1 = P1^1;

uint16 Capturebuf[2];  
uint8 Eventtimes=0;    
uint8 Timesbuf[2];      
uint8 I=0;                  
uint32 Dtime;


/*
********************************************************************************
* 	函 数 名: Delay
* 	功能描述: 延时函数,延时的间隔是1ms
* 	输    入: Time	:控制延时的间隔
* 	返    回: 无
********************************************************************************
*/

void Delay(uint16 Time)
{
	uint8 i;

//	需要执行2000个指令周期
	while(Time--)  {
		i = 199;
		while(i--);   //这一段将执行10个指令周期
		}
}


/*
********************************************************************************  
* 	函 数 名:
* 	功能描述:定时/ 计数器T2 程序,中断方式
* 	输    入: 无
* 	返    回: 无
********************************************************************************
*/

//TIMER2 工作在允许捕获功能的定时模式,用来计算T2EX 脚输入脉冲周期
//设晶振为24M
//T2EX 脚脉冲周期计算公式0.5us*[65536*(Timesbuf[1]-Timesbuf[0])+Capturebuf[1]-Capturebuf[0]]

void TM2CPtimer(void)
{					
	EXEN2 = 1;  // T2 允许外部中断
	C_T2 = 0;  // T2 工作在定时模式
	CP_RL2 = 1;  //  T2 工作在捕获模式
	ET2 = 1;  // 允许T2 中断
	EA = 1;  // CPU 开中断
	TR2 = 1;      //  开启TIMER2,开始定时

// 下面指令用来模拟外部的输入脉冲	
	Delay(1);
	P1_1 = 0;
	Delay(20);
	P1_1 = 1;
	Delay(20);
	P1_1 = 0;
	Delay(1);
	
	Dtime = ((65536*(Timesbuf[1]-Timesbuf[0])+Capturebuf[1]-Capturebuf[0])/2000);
	TR2 = 0;
	ET2 = 0;
	
	while(1)
		{
			Delay(Dtime);
			P4_0 = ~P4_0;
		}
	
}

//中断程序5,定时中断2

void ISR_T2(void) interrupt INTERRUPT_TIMER2
{      
	if(TF2)    //  如果中断是溢出引起的则溢出次数+ 1
		{
		Eventtimes++;
		TF2 = 0;          // 清除TF2 溢出标志位	
		}
	if(EXF2)  // 如果中断是T2EX 脚下降沿信号触发的,则把当前捕获的结果存入寄存器
		{
		EXF2 = 0;   // 清除外部中断标志
		if(I<2)      // 该条件是为限制多于两次捕获而设
			{
			Capturebuf[I] = ((uint16)RCAP2H<<8) + RCAP2L;  // 把当前捕获的结果存入寄存器
			Timesbuf[I] = Eventtimes;  // 把溢出次数存入寄存器
			I++;   //指向下一个地址
			}
		} 
}	

void main(void)
{
	InitMcu();
	TM2CPtimer();
}


#else


//TIMER2 工作在不受T2EX 脚影响的自动装载初值模式
//设晶振为24M,需要定时时间为 5ms

void main(void)
{			
	InitMcu();
	EXEN2 = 0;  // T2 禁止外部中断
	C_T2 = 0;  // T2 工作在定时模式
	CP_RL2 = 0;  //  T2 工作在自动装载模式
	TH2 = 0xD8;  // 装入16 位计数初值,要产生5ms的定时需要计数10000次
	TL2 = 0xF0;  //  65536-10000=55536=D8F0H
	RCAP2H = 0xD8;   //  装载着TH2的初值,当溢出后自动向TH2 装载该初值
	RCAP2L =  0xF0;   //  装载着TL2的初值,当溢出后自动向TL2 装载该初值
	ET2 = 1;  // 允许T2 中断
	EA = 1;  // CPU 开中断
	TR2 = 1;      //  开启TIMER2,开始定时
	while(1);  //等待中断
}

//中断程序5,定时中断2

void ISR_T2(void) interrupt INTERRUPT_TIMER2
{      
	TF2 = 0;   //  清除溢出标志位TF2
	P4_0 = ~P4_0;
}	

#endif


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?