首页 > 其他分享 >单片机学习笔记 14. 定时/计数器_中断

单片机学习笔记 14. 定时/计数器_中断

时间:2024-12-01 22:31:08浏览次数:6  
标签:P0 定时器 14 数码管 中断 单片机 计数器 DU

更多单片机学习笔记:
单片机学习笔记 1. 点亮一个LED灯
单片机学习笔记 2. LED灯闪烁
单片机学习笔记 3. LED灯流水灯
单片机学习笔记 4. 蜂鸣器滴~滴~滴~
单片机学习笔记 5. 数码管静态显示
单片机学习笔记 6. 数码管动态显示
单片机学习笔记 7. 独立键盘
单片机学习笔记 8. 矩阵键盘按键检测
单片机学习笔记 9. 8×8LED点阵屏
单片机学习笔记 10. 中断系统(理论)
单片机学习笔记 11. 外部中断
单片机学习笔记 12. 定时/计数器_定时
单片机学习笔记 13. 定时/计数器_计数


目录

0、实现的功能

1、Keil工程

2、代码实现


0、实现的功能

​        解决独立按键判断时,松手检测时只显示一位数码管的问题。用定时器中断的方式去一直进行动态扫描,每5ms就要动态扫描。

1、Keil工程

        定时器中断和外部中断很相似。
        当定时器溢出时,硬件会自动TF0置1,同时请求中断。上两节用的是查询的方式--软件清零;可以等CPU响应中断后,硬件自动清零TF0

        定时器0的中断入口是1

2、代码实现

        把上节的用定时中断的方式写一下,代码如下:

#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit WE = P2^7;
sbit DU = P2^6;
uchar mSec, Sec;//毫秒和秒的存储变量

uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f} ;

//延时模块
void delay(uint z)
{
	uint x;
	uint y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0; y--);
}

void display(uint i)
{
	uchar bai, shi , ge;
	bai = i / 100;
	shi = i % 100 /10;
	ge = i % 10;

	//第一个数码管
	P0 = 0xff;
	WE = 1;
	P0 = 0xfe;
	WE = 0;

	DU = 1;
	P0 = table[bai];
	DU = 0;
	delay(5);

	//第二个数码管
	P0 = 0xff; 		//清除断码,让位锁存器哪个都不选
	WE = 1;//位选锁存打开
	P0 = 0xfd;//选第二个管
	WE = 0;	//关上位选锁存器,进入锁存

	DU = 1;//段选锁存打开
	P0 = table[shi];		//亮shi
	DU = 0;//进入锁存
	delay(5); 		//延时5ms

	//第三个数码管
	P0 = 0xff; 		//清除断码,让位锁存器哪个都不选
	WE = 1;//位选锁存打开
	P0 = 0xfb;//选第三个管
	WE = 0;	//关上位选锁存器,进入锁存

	DU = 1;//段选锁存打开
	P0 = table[ge];		//亮ge
	DU = 0;//进入锁存
	delay(5); 		//延时5ms
}

//定时器0初始化,定时50ms
void timer0Init()
{
	EA = 1;//打开总中断
	ET0 = 1;//打开定时器0溢出中断
	TR0 = 1; //启动定时器0
	TMOD = 0x01;//启动定时器0的工作模式1:16位定时
	TH0 = (65535 - 46082) / 256; //取65535-46082的高八位
	TL0 = (65535 - 46082) % 256;//取65535-46082的低八位
}

void main()
{
	timer0Init();//定时器0初始化
	while(1)
	{
		display(Sec);
	}
}

//定时器0中断函数
void timer0() interrupt 1
{
	TH0 = 0x4b;
	TL0 = 0xfd;//重新定时50ms
	mSec++;//到了50ms就加1
	if(mSec == 20)//如果已经过了20个50ms 也就是1s
	{	
		mSec = 0;//mSec清零
		Sec++;//秒就加1		
	}
}

        独立按键的代码中,当按下按键时,三位数码管只显示一位;松开按键时,才显示三位。这是因为按下的时候CPU一直在 while(!key_s2) 这里,没有去做别的事情(Display),Display是显示三位数码管的,所以按下的时候是不会显示三位数码管的,只会显示一位。
        此时动态扫描就失效了。想要在按下的时候仍然可以进行动态扫描,可以用定时器中断的方式完成。

        1. 从始至终都要一直循环扫描三位数码管,扫描的间隔是5ms,也就是代替了Delay(5)。所以定时器要定时5ms。定时溢出后就向CPU请求中断,跳转到中断程序:重新定时5ms+显示按键按下的次数num
        2.主函数中判断按键是否被按下,按下的话num就+1

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
uchar num;//数码管显示的值
uchar mSec, Sec;//毫秒和秒储存变量

//共阴数码管段选表0-9
uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
//数码管位选码
uchar code SMGwei[] = {0xfe, 0xfd, 0xfb};

void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--); 		
} 

void display(uchar i)
{
	static uchar wei;//静态变量wei 在下次进入该子函数中wei仍然保持上一次的值 		
	P0 = 0XFF;//清除断码
	WE = 1;//打开位选锁存器
	P0 = SMGwei[wei];
	WE = 0;//锁存位选数据
	switch(wei)
	{
		case 0: DU = 1; P0 = SMGduan[i / 100]; DU = 0; break;
		case 1: DU = 1; P0 = SMGduan[i % 100 / 10]; DU = 0; break;	
		case 2: DU = 1; P0 = SMGduan[i % 10]; DU = 0; break;		
	}
	wei++;
	if(wei == 3)
		wei = 0;
}
//定时器0初始化
void timer0Init()
{
	EA = 1;	//打开总中断
	ET0 = 1;//打开定时器0中断
	TR0 = 1;	 //启动定时器0
	TMOD = 0X01; //定时器工作模式1,16位定时模式
	TH0 = 0xED;
	TL0 = 0xFF; //定时5ms
}

void main()//main函数自身会循环
{	
	timer0Init();//定时器0初始化
	while(1)
	{
		if(key_s2 == 0)//判断S2是否被按下
		{
			delay(20);//按键消抖
			if(key_s2 == 0)
			{
				if(num != 120)
				num++;
				while(!key_s2);//松手检测
			}	
		}
		if(key_s3 == 0)//判断S3是否被按下
		{
			delay(20);//按键消抖
			if(key_s3 == 0)
			{
				if(num > 0)
					num--;
				while(!key_s3);//松手检测
			}	
		}
	}	
} 

//定时器0中断函数
void timer0() interrupt 1
{
	TH0 = 0xED;
	TL0 = 0xFF; //再定时5ms
	display(num); //数码管显示函数	
} 

实物展示:
 

标签:P0,定时器,14,数码管,中断,单片机,计数器,DU
From: https://blog.csdn.net/u014087103/article/details/144170299

相关文章

  • 单片机学习笔记 15. 串口通信(理论)
    更多单片机学习笔记:单片机学习笔记1.点亮一个LED灯单片机学习笔记2.LED灯闪烁单片机学习笔记3.LED灯流水灯单片机学习笔记4.蜂鸣器滴~滴~滴~单片机学习笔记5.数码管静态显示单片机学习笔记6.数码管动态显示单片机学习笔记7.独立键盘单片机学习笔记8.矩阵键盘按......
  • 51单片机从入门到精通:理论与实践指南综合应用——实战篇(七)
    学完了入门篇和常用资源篇,接下来就进入了综合篇——实战篇了。大概是三个案例,写三篇博客给大家讲解,希望可以帮助大家。在生活的道路上,每一个人都会遇到挑战与困难,这些时刻或许会让前路显得模糊不清,甚至让人感到无助和迷茫。但请记住,正是这些艰难的时光塑造了更加坚强、更有智......
  • 2024-2025-1 20241416 《计算机基础与程序设计》第十周学习总结
    这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 <作业要求的链接>(https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10)这个作业的目标 信息系统数据库与SQL人工智能与专家系统人工神经网络模拟与离散事件排队系统天气与地震模型图形图像......
  • 2024-2025-1 20241413 《计算机基础与程序设计》第十周学习总结
    班级链接https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP作业要求https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10作业目标信息系统数据库与SQL人工智能与专家系统人工神经网络模拟与离散事件排队系统天气与地震模型图形图像教材学习内容......
  • leetcode 1456. 定长子串中元音的最大数目
    1456.定长子串中元音的最大数目法一:借助队列classSolution{public:intmaxVowels(strings,intk){intsize=s.size(),resMax=0;queue<bool>qVowel;for(inti=0;i<k;i++){if(s[i]=='a'||s[i]==......
  • 2024-2025-1 20241421 刘庆安《计算机基础与程序设计》第十周学习总结
    这个作业属于哪个课程2024-2025-1-计算机基础与程序设计)这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10这个作业的目标信息系统、数据库与SQL、人工智能与专家系统、人工神经网络、模拟与离散事件、排队系统、天气与地震模型、图形图像......
  • 2024-2025-1 20241411王思棋《计算机基础与程序设计》第十周学习总结
    作业信息|这个作业属于哪个课程|https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP||-- |-- ||这个作业要求在哪里|https://www.cnblogs.com/rocedu/p/9577842.html#WEEK10||这个作业的目标|信息系统、数据库与SQL、人工智能与专家系统、人工神经网络、模拟与离散事件......
  • 2024-2025-1 20241423 《计算机基础与程序设计》第10周学习总结
    作业信息这个作业属于哪个课程[2024-2025-1-计算机基础与程序设计]https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP这个作业要求在哪里[2024-2025-1计算机基础与程序设计第一周作业]https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP/homework/13276......
  • 2024-2025-1 20241314 《计算机基础与程序设计》第十周学习总结
    2024-2025-120241314《计算机基础与程序设计》第十周学习总结作业信息这个作业属于哪个课程2024-2025-1-计算机基础与程序设计这个作业要求在哪里2024-2025-1计算机基础与程序设计第十周作业这个作业的目标信息系统数据库与SQL人工智能与专家系统人工神经网......
  • 2024-2025-1 20241417 《计算机基础与程序设计》第十周学习总结
    2024-2025-120241417《计算机基础与程序设计》第十周学习总结作业信息这个作业属于哪个课程<班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里<作业要求的链接>2024-2025-1计算机基础与程序设计第十周作业这个作业的目标<信息系统,数据库与SQL,......