51单片机定时器

定时器的工作原理
定时器的工作模式
定时器的时钟
中断系统

中断的流程
STC89C52的中断资源
AT89C52的中断资源

定时器相关寄存器

中断程序的编写

第一个中断程序案例使用模块化编程的方法
1:中断头文件

cpp 复制代码
#ifndef __TIMER0_H_
#define __TIMER0_H_
void Timer0_Init(void);


#endif

2:中断实现函数

cpp 复制代码
#include <REGX52.H>

// 第一步:初始化定时器
void Timer0_Init(void){
		// firt 配置定时器的工作模式TMOD
		//	TMOD = 0x01;//0000 0001 这个写法会引发一种小的错误:当同时使用两个定时器时数据会被刷新
	  // 这个方法可以很好的解决数据刷新问题,也就是吧TMOD的低四位清0,高四位保持不变
	  // 1010 0011 & 1111 0000 也就是吧TMOD的低四位清0,高四位保持不变
  	TMOD = TMOD&0xF0; 
	  // 把TMOD的低四位设置为1,然后高四位保持不变
	  TMOD = TMOD | 0X01; 
  	TF0 = 0;
	  TR0 = 1;  // 当TR0的值为1时表示中断开启
	  // 高八位和低八位0~65535每次间隔1微秒计数加1总共的定时时间
	  TH0 = (65535-1000)/256;
	  TL0 = (65535-1000)%256;
    // 配置中断
	  ET0 = 1;
	  EA = 1;
	  PT0 = 0;
}

/*
   todo 定时器模块化一秒的模版(中断函数模版)

   // 第二步:中断函数的使用
   void Timer0_Routime() interrupt 1{
				static unsigned int T0Count;
	      // 每次中断以后要重新赋初始值
				TH0 = (65535-1000)/256;
				TL0 = (65535-1000)%256;
	      T0Count++;// 每次中断一次程序就统计一次
	      if(T0Count >= 1000){
					  T0Count = 0;
				    P1_0 = ~P1_0;
				}	
  }
   
*/

主函数代码
主函数调用中断点亮其中的一个led灯

c 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
#include "Key.h"

unsigned char KeyNum;

void main(){
//	 Timer0_Init();
   while(1){
			
	 }
}

// 第二步:中断函数的使用
void Timer0_Routime() interrupt 1{
				static unsigned int T0Count;
	      // 每次中断以后要重新赋初始值
				TH0 = (65535-1000)/256;
				TL0 = (65535-1000)%256;
	      T0Count++;// 每次中断一次程序就统计一次
	      if(T0Count >= 1000){
					  T0Count = 0;
				    P1_0 = ~P1_0;
				}	
}

第二个案例实现独立键盘控制

1:头文件

c 复制代码
#ifndef __DELAY_H_
#define __DELAY_H_
void Delay(unsigned int xms);	
unsigned char Key();
#endif

2:c语言函数实现文件

cpp 复制代码
#include <REGX52.H>
#include "Delay.h"

// 独立按键模块化编程
unsigned char Key(){
    unsigned char KeyNumber = 0;
	  
	  if(P3_1 == 0){
			 Delay(20);
			 while(P3_1 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 1;
		 }
		
		 if(P3_2 == 0){
			 Delay(20);
			 while(P3_2 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 2;
		 }
		 
		  if(P3_0 == 0){
			 Delay(20);
			 while(P3_0 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 3;
		 }
			
			 if(P3_3 == 0){
			 Delay(20);
			 while(P3_3 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 4;
		 }
	   return KeyNumber;

}

3:c语言主函数文件

c 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
#include "Key.h"

unsigned char KeyNum;

void main(){
//	 Timer0_Init();
   while(1){
			KeyNum = Key();
		  if(KeyNum == 1){
			  P1_1 = ~P1_1;
			}
			if(KeyNum == 2){
			  P1_2 = ~P1_2;
			}
			if(KeyNum == 3){
			  P1_3 = ~P1_3;
			}
			if(KeyNum == 4){
			  P1_4 = ~P1_4;
			}
	 }
}

// 第二步:中断函数的使用
//void Timer0_Routime() interrupt 1{
//				static unsigned int T0Count;
//	      // 每次中断以后要重新赋初始值
//				TH0 = (65535-1000)/256;
//				TL0 = (65535-1000)%256;
//	      T0Count++;// 每次中断一次程序就统计一次
//	      if(T0Count >= 1000){
//					  T0Count = 0;
//				    P1_0 = ~P1_0;
//				}	
//}

案例三:实现按第一个独立键盘按钮改变流水灯的运动方向

1:延时函数的头文件

c 复制代码
#ifndef __DELAY_H_
#define __DELAY_H_
void Delay(unsigned int xms);	

#endif

2:独立键盘的头文件

c 复制代码
#ifndef __DELAY_H_
#define __DELAY_H_
		void Delay(unsigned int xms);	
		unsigned char Key();
#endif

3:独立键盘的c语言文件

c 复制代码
#include <REGX52.H>
#include "Delay.h"

// 独立按键模块化编程
unsigned char Key(){
    unsigned char KeyNumber = 0;
	  
	  if(P3_1 == 0){
			 Delay(20);
			 while(P3_1 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 1;
		 }
		
		 if(P3_2 == 0){
			 Delay(20);
			 while(P3_2 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 2;
		 }
		 
		  if(P3_0 == 0){
			 Delay(20);
			 while(P3_0 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 3;
		 }
			
			 if(P3_3 == 0){
			 Delay(20);
			 while(P3_3 == 0){ // 检测是否松手
			 }
			 Delay(20);
			 KeyNumber = 4;
		 }
	   return KeyNumber;

}

4:c语言主函数实现文件

c 复制代码
#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "Timer0.h"
#include "Key.h"

unsigned char KeyNum,LEDMode;

void main(){
	 P1 = 0xfe;
   Timer0_Init();
   while(1){
			KeyNum = Key();
		  if(KeyNum == 1){
				LEDMode++;
				if(LEDMode >= 2){
				   LEDMode = 0;
				}
			}

	 }
}

// 第二步:中断函数的使用
void Timer0_Routime() interrupt 1{
				static unsigned int T0Count;
	      // 每次中断以后要重新赋初始值
				TH0 = (65535-1000)/256;
				TL0 = (65535-1000)%256;
	      T0Count++;// 每次中断一次程序就统计一次
	      if(T0Count >= 500){
					  T0Count = 0;
				    if(LEDMode == 0){
							  // 循环左移
						    P1 = _crol_(P1,1);
						}
						if(LEDMode == 1){
							  // 循环右移
								P1 = _cror_(P1,1);
						}
				}	
}

...

相关推荐
朝九晚五ฺ1 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
自由的dream1 小时前
Linux的桌面
linux
xiaozhiwise2 小时前
Makefile 之 自动化变量
linux
意疏4 小时前
【Linux 篇】Docker 的容器之海与镜像之岛:于 Linux 系统内探索容器化的奇妙航行
linux·docker
BLEACH-heiqiyihu4 小时前
RedHat7—Linux中kickstart自动安装脚本制作
linux·运维·服务器
一只爱撸猫的程序猿4 小时前
一个简单的Linux 服务器性能优化案例
linux·mysql·nginx
lantiandianzi6 小时前
基于单片机的多功能跑步机控制系统
单片机·嵌入式硬件
哔哥哔特商务网6 小时前
高集成的MCU方案已成电机应用趋势?
单片机·嵌入式硬件
跟着杰哥学嵌入式6 小时前
单片机进阶硬件部分_day2_项目实践
单片机·嵌入式硬件