1 基本原理
2 实现代码
主要根据定时器2的逻辑框图和中断的逻辑框图来编写代码,这样代码的可读性强,也便于理解。但有些寄存器在框图中可能没有说明,所以也需要仔细阅读定时器0的官方文档,即基本原理部分。
/*----------------函数功能:
中断 定时器2
--------------------------*/
#include<pic.h>// 调用PIC16f87XA单片机的头文件
//#include"delay.h"//调用延时子函数
__CONFIG(0xFF32);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关
//__CONFIG(HS&WDTDIS&LVPDIS);
/*-----------宏定义--------------*/
#define uint unsigned int
#define uchar unsigned char
#define V0 RD0
uint i;
/*-----------子函数声明--------------*/
/*-----------主函数--------------*/
void main()
{
// The corresponding data direction register is TRISA.
// Setting a TRISA bit (= 1) will make the corresponding PORTA pi an input.
// Clearing a TRISA bit (= 0) will make the corresponding PORTA pin an output.
TRISD=0xfe; // 设置数据方向 RD7-RD1为输入,RD0为输出
// 1 = Port pin is > VIH,即高电平 ; 0 = Port pin is < VIL,即低电平
PORTD=0x00; // 端口赋初值
/********定时器TMR1初始化**********/
// 只有一个时钟,所以不用时钟选择
//TMR2CS=0; // TMR1时钟源选择内部指令周期(fosc/4)
// Timer2 is an 8-bit timer with a prescaler and a postscaler
//预分频器 The input clock (FOSC/4) has a prescale option of 1:1, 1:4 or 1:16
T2CKPS1=1;
T2CKPS0=1;//预分频 1:16,对应的编码为1X 1x = Prescaler is 16
// The match output of TMR2 goes through a 4-bit postscaler
// (which gives a 1:1 to 1:16 scaling inclusive)to generate a TMR2 interrupt
//后分频器 Timer2 Output Postscale Select bits
TOUTPS3=0;
TOUTPS2=0;
TOUTPS1=0;
TOUTPS0=0;//后分频 1:1,对应的编码为0000
// Timer2 can be shut-off by clearing control bit, TMR2ON
// TMR2ON: Timer2 On bit. 1 = Timer2 is on. 0 = Timer2 is off
TMR2ON=1; // 打开计数定时器TMR2,状态为ON
// Timer2 is an 8-bit timer
//8位计数寄存器给初值,在这里没有考虑中断所造成的时钟延迟13个指令周期
TMR2=256-250+13; // 定时250us*16(预分频,1:16)*1(后分频,1:1)=4000us. 13怎么来的,见Timer0
// The Timer2 module has an 8-bit period register, PR2.
// Timer2 increments from 00h until it matches PR2 and then resets to 00h on the next increment cycle.
// PR2 is a readable and writable register. The PR2 register is initialized to FFh upon Reset
PR2=0xff; // 比较器的初值
// The TMR2 interrupt, if enabled,is generated on overflow
// which is latched in interrupt flag bit, TMR2IF
TMR2IF=0; // 溢出中断标志位清零
// This interrupt can be enabled/disabled by setting/clearing TMR2 interrupt enable bit, TMR2IE
TMR2IE=1; //溢出中断标志允许位置一
PEIE=1; //外设中断允许位置一
//*********开全局中断设置
//定时器T0设置了中断允许,此处要开全局中断
GIE=1; // 总中断允许
while(1) // 死循环,单片机初始化后,就一直运行这个死循环
{
}
}
/*************中断服务程序***************/
void interrupt ISR(void) // PIC单片机的所有中断都是这样一个入口
{
// TMR2IF标志位为在计数寄存器由全1变为全0的时候,自动得到TMR2IF=1.
if(TMR2IF==1) // 需要进一步判断是否为定时器1的溢出中断标志位
{
//定时器中断后,要重置初值,以备下次中断
TMR2=256-250+13;
//溢出中断标志位清零 如果TMR2IF出现上升沿,则产生中断,所以中断发生之后要清零。
TMR2IF=0;
// 执行中断处理程序,执行中断产生时想要执行的功能
if(++i>125) //4ms中断1次,125次中断就是5000ms
{
i=0;
V0=!V0; // 取反 实现一秒的闪烁
}
}
}
为什么有下面两行语句,这是由中断决定的,如下图所示。
PEIE=1; //外设中断允许位置一
GIE=1; //总中断允许