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);
						}
				}	
}

...

相关推荐
欢乐熊嵌入式编程27 分钟前
智能手表固件升级 OTA 策略文档初稿
嵌入式硬件·学习·智能手表
xq51486333 分钟前
Linux系统下安装mongodb
linux·mongodb
柒七爱吃麻辣烫34 分钟前
在Linux中安装JDK并且搭建Java环境
java·linux·开发语言
欢乐熊嵌入式编程34 分钟前
智能手表 MCU 任务调度图
单片机·嵌入式硬件·智能手表
【云轩】1 小时前
电机密集型工厂环境下的无线通信技术选型与优化策略
经验分享·嵌入式硬件
孤寂大仙v1 小时前
【Linux笔记】——进程信号的产生
linux·服务器·笔记
sword devil9001 小时前
将arduino开发的Marlin部署到stm32(3D打印机驱动)
stm32·单片机·嵌入式硬件
GodKK老神灭1 小时前
STM32 变量存储
stm32·单片机·嵌入式硬件
深海蜗牛2 小时前
Jenkins linux安装
linux·jenkins
愚戏师2 小时前
Linux复习笔记(三) 网络服务配置(web)
linux·运维·笔记