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

...

相关推荐
弓弧名家_玄真君16 分钟前
Ubuntu 20.04.3 LTS 安装vnc (Xfce4 + Xvfb)
linux·运维·ubuntu
唐·柯里昂7981 小时前
野火鲁班猫5使用正点原子 RTL8188EUS Wifi模块驱动移植(Linux5.10 Debian系统) 解决zsh报错
linux·c语言·mcu·物联网·ubuntu·硬件工程·软件构建
源梦想1 小时前
机甲恐龙动作冒险网页小游戏Linux部署教程
linux·运维·服务器
Hoshino.411 小时前
从0开始学习Linux——第七部分:DNS(1)
linux·网络·学习
yiyeguzhou1002 小时前
论文解读:Overcoming the IOTLB wall for multi-100-Gbps Linux-based networking
linux·运维·服务器
Y淑滢潇潇2 小时前
RHCE Day 7 SHELL概述和基本功能
linux·前端·rhce
妄想出头的工业炼药师2 小时前
cuda如何安装卸载
linux·运维·服务器
柳鲲鹏2 小时前
LINUX下载编译libcamera
linux·运维·服务器
Embedded-Xin2 小时前
Linux架构优化——spdlog实现压缩及异步写日志
android·linux·服务器·c++·架构·嵌入式
皓月盈江2 小时前
STC12、STC15、STM32系列单片机控制16*64LED点阵屏显示,修改显示内容
单片机·嵌入式硬件·keil·stm32f103c8t6·stc12c5a60s2·stc15w4k32s4·led点阵屏程序源码