PIC16F877A单片机 (外部中断与定时器Timer0的综合使用)

本文详细介绍了如何在单片机PIC16F877A中结合定时器Timer0和外部中断实现LED灯的控制,包括定时闪烁和按键中断操作。通过设置中断触发条件、配置定时器和中断服务程序,实现精确的时间控制和外部事件响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PIC16F877A单片机 (外部中断与定时器Timer0的综合使用)

1 实现原理

见前面的定时器0和外部中断的内容

2 实现电路图

在这里插入图片描述

3 源代码

/*----------------函数功能:
	  定时器0+外部中断的运用
功能1:LED0灯一直闪烁;
功能2:没有按键按下时,LED1灯灭。有按键按下时,LED1灯亮。
--------------------------*/


#include<pic.h>// 调用PIC16f87XA单片机的头文件
//#include"delay.h"//调用延时子函数



__CONFIG(0xFF32);//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关
//__CONFIG(HS&WDTDIS&LVPDIS);



/*-----------宏定义--------------*/
#define  uint  unsigned int
#define  uchar unsigned char




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.
	TRISB0=1;				// 设置RB0/INT口为输入,按键
	TRISD0=0;				// 设置RD0口为输出,    LED0
	TRISD1=0;				// 设置RD1口为输出,    LED1


	// 1 = Port pin is > VIH,即高电平  ;  0 = Port pin is < VIL,即低电平
	RD0=0;					// 设置数据方向 RD0为输出
	RD1=0;	
	//RB0=0;

	


	/******************定时器TMR0初始化************************/
	// Timer mode is selected by clearing bit T0CS. 定时器模式通过将T0CS清零(T0CS=0)来选择。
	// In Timer mode, the Timer0 module will increment every instruction cycle (without prescaler)。
	// Counter mode is selected by setting bit T0CS. 计数器模式通过将T0CS置一(T0CS=1)来选择。
	// In Counter mode, Timer0 will increment either on every rising or falling edge of pin RA4/T0CKI
	// The incrementing edge is determined by the  Timer0  Source  Edge  Select  bit,  (T0SE=1). 
	// Clearing bit T0SE selects the rising edge.计数器模式下,此时要选择上升沿(T0SE=0)触发还是下降沿(T0SE=1)触发;
	T0CS=0;					//TMR0时钟源选择位   如果T0CS=0,TMR0的时钟源 选择 内部指令周期(fosc/4)
	// 下面两行语句选择计数器模式下的上升沿触发
	//T0CS=0;				//计数器模式
	//T0SE=0;				//上升沿触发 



	// There is only one prescaler available which is mutually exclusively shared between 
	// the Timer0 module and the Watchdog Timer.
	// The PSA and PS2:PS0 bits determine the prescaler assignment and prescale ratio.
	//不要预分频器
	//PSA=1;				//预分频器分配给WDT(看门狗),也就是1:1分频  此时PS0~PS2无效
	//要预分频器  下面四条指令代替上面一条指令
	PSA=0;					//预分频器分配位
	PS0=0;					//预分频 1:8,三个比特位的对应编码为010
	PS1=1;					// 来八个系统时钟,计数寄存器的值+1
	PS2=0;



	//The TMR0 interrupt is generated when the TMR0 register overflows from FFh to 00h.
	//定时2000us=250us*8(八分频),初值TMR0=256-250=6	
	TMR0=0x06; 				//8位计数寄存器赋初值
	
	

	// This overflow sets bit TMR0IF(T0IF). 通过T0IF=1来说明计数寄存器溢出了
	T0IF=0;					//TMR0的溢出中断标志位 清零,从而计数寄存器满的时候,T0IF产生一个上升沿。



	//The interrupt can be masked by clearing bit TMR0IE(T0IE).通过将T0IE来屏蔽中断
	//T0IE=1;				//TMR0IE 中断允许控制位 置一
	TMR0IE=1;				//TMR0IE=T0IE  和上一条语句等价





	/******************外部中断初始化********************/
	// External interrupt on the RB0/INT pin is edge triggered,
	// either rising if bit INTEDG (OPTION_REG<6>) is set or falling if the INTEDG bit is clear.
	INTEDG=1;				// 设置RB0/INT为上升沿触发


	
	INTF=0;					// RB0/INT的中断标志位清零



	// This interrupt can be disabled by clearing enable bit, INTE
	INTE=1;					// RB0/INT的溢出中断标志允许位置一




	//****************开全局中断设置*******************/
	// A global interrupt enable bit, GIE (INTCON<7>),enables (if set) all unmasked interrupts
	// or disables (if cleared) all interrupts
	// 外部中断RB0/INT设置了中断允许,此处要开全局中断
	GIE=1;					//总中断允许
	// 外部中断RB0/INT设置了中断允许,此处要允许外设中断
	PEIE=1;					// 允许外设中断
	


	while(1)				// 死循环,单片机初始化后,就一直运行这个死循环
	{

	}
	
}


/********************中断服务程序**********************/
void interrupt ISR(void)//PIC单片机的所有中断都是这样一个入口
{
	// The TMR0 interrupt is generated(T0IF==1) when the TMR0 register overflows from FFh to 00h.
	// 计数器寄存器由全1变为全0的时候,T0IF==1.
	if(T0IF==1)						//需要进一步判断是否为T0中断    
	{

		//定时器中断后,要重置初值,以备下次中断
		TMR0=0x13;	



		// Bit TMR0IF must be cleared in software by the Timer0 module Interrupt Service Routine
		// before re-enabling this interrupt. 解释了为什么要清零
		//溢出中断标志位清零     只有T0IF出现上升沿,才会产生中断,所以中断发生之后要清零。		
		T0IF=0;			
		


		// 执行中断处理程序,也就是中断产生了,我们想要执行什么功能
		if(++i>250)				//2ms中断一次,再计次250次后就是500ms
		{
			i=0;
			RD0=!RD0;			// 取反  实现一秒的闪烁
		}
		
	}


	// When a valid edge appears on the RB0/INT pin, flag bit, INTF(INTCON<1>), is set.
	else if(INTF==1)			// 需要进一步判断是否RB0/INT的中断标志位   
	{
		// The interrupt flag bit(s) must be cleared in software before 
		// re-enabling interrupts to avoid recursive interrupts
		//溢出中断标志位清零     如果INTF出现上升沿,则产生中断,所以中断发生之后要清零。
		INTF=0;			

		

		// 执行中断处理程序,执行中断产生时想要执行的功能
		RD1=1;					// 外部中断发生时,LED灯亮

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值