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 + -
显示快捷键?