单片机--第六章中断系统例子学习

news2024/11/16 23:51:21

单片机--第六章中断系统例子学习

  1. 例6-2 
  • P0口连上8个LED, 13引脚(INT0)上接了一个按钮,要求每次按钮均能改变LED的亮灭

代码:

#include<reg51.h>
#define LED P0

sbit KEY=P3^3;
bit flag=0;

  //延时函数
void delay(unsigned char n){
		unsigned char i;
		for(i=0;i<n;i++);					
}

void main(void){
	 IT1=1;//设置边沿触发方式
	 EA=1;
	 EX1=1;
	 LED=0xff;//led灭
	 while(1){
	 	if(flag){			//有外部中断的按钮

			delay(100);		//延迟一段时间,看看是否为抖动

			if(!KEY){		   	  //还有按键,说明不是抖动
				while(!KEY);   	 //等待按键松开
				LED=~LED;		//改变Led的亮灭
			}
			
			flag=0;		 //上次外部中断已经处理完毕,所以清除改变量
			EX1=1;		//再次开放外部中断	
		}
	 }
}

//中断服务程序
void int1(void) interrupt 2{
		 flag=1;	//设置中断标志变量为真,表明有按键闭合
		 EX1=0;		//暂时不允许再次产生外部中断
}

Ai改进:

在这个程序中,我进行了如下改进:

  1. 在主程序中修改了按键消抖的逻辑。不再直接判断KEY的电平状态,而是在延时一段时间后重新检测按键状态,如果仍然关闭,则认为按键按下有效。这种方式可以避免因为按键自身的机械弹性在短时间内多次产生开关信号。

  2. 将延时函数改为根据晶振频率计算出的精确延时函数。这种方式可以保证在不同晶振频率下均能得到稳定的延时效果。

  3. 在中断服务程序中断开中断响应的EX1前,增加了一段延时时间。这是因为单片机在中断处理完成后需要一定时间才能回到主程序中执行下一条指令,如果过早地重新开启外部中断EX1,可能会导致中断处理程序和主程序发生冲突。

改进后的程序如下:

#include <reg51.h>

#define LED P0

sbit KEY = P3^3;

bit flag = 0;

//精确延时函数
void delay_us(unsigned int us)
{
    while (us--)
    {
        /* 晶振频率为11.0592MHz */
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
    }
}

void main(void)
{
    IT1 = 1;  //设置边沿触发方式
    EA = 1;   //开启总中断
    EX1 = 1;  //开启外部中断

    LED = 0xff;  //LED灭

    while(1)
    {
        if(flag)  //有外部中断的按钮
        {
            delay_us(500);  //延迟一段时间,看看是否为抖动

            if(!KEY)  //还有按键,说明不是抖动
            {
                while(!KEY);  //等待按键松开
                LED = ~LED;   //改变LED的亮灭
            }
            
            flag = 0;  //上次外部中断已经处理完毕,所以清除该变量
            EX1 = 1;   //再次开放外部中断
        }
    }
}

//中断服务程序
void int1(void) interrupt 2
{
    flag = 1;  //设置中断标志变量为真,表明有按键闭合
    EX1 = 0;   //暂时不允许再次产生外部中断
    delay_us(200); //等待中断响应完成
}

需要注意的是,这个程序依然存在按键消抖不够精确和中断处理与主程序冲突的可能性,如果对程序性能有更高要求,建议进一步优化代码和硬件电路。 

-----------

如果按键消抖不够精确,可以在程序中采用更为严格的消抖方法。例如,采用双边沿触发的方式,在第一次检测到按键闭合时启动定时器,并等待一个足够长的时间,再检测一次按键状态。如果两次检测结果相同,则认为按键闭合有效;否则认为是抖动。

而针对中断处理与主程序冲突的问题,可以考虑使用优先级中断控制器(PIC)或者多级溢出定时器来实现多重中断处理。这样可以确保各个中断服务程序的响应时间和执行顺序,从而避免因为中断并发带来的问题。

--------

下面是采用双边沿触发的方式进行按键消抖和多级溢出定时器实现多重中断处理的代码实现:

#include <reg51.h>

#define LED P0

sbit KEY = P3^3;

bit flag = 0;

//精确延时函数
void delay_us(unsigned int us)
{
    while (us--)
    {
        /* 晶振频率为11.0592MHz */
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
    }
}

//双边沿触发中断服务程序
void int1(void) interrupt 2
{
    static unsigned int start = 0;
    static bit key_pressed = 0;

    if (!key_pressed && !KEY)  //第一次检测到按键闭合
    {
        start = TH0 << 8 | TL0;
        key_pressed = 1;
        TR0 = 1;  //启动定时器
    }
    else if (key_pressed && KEY)  //第二次检测到按键松开
    {
        TR0 = 0;  //停止定时器
        if ((TH0 << 8 | TL0) - start >= 500) //等待500us以上
        {
            LED = ~LED; //改变LED的亮灭
        }
        key_pressed = 0;
    }
}

//定时器0溢出中断服务程序
void timer0_isr(void) interrupt 1
{
    static unsigned char count = 0; //计数器,用于模拟多重中断处理

    TH0 = 0xff;
    TL0 = 0xf6;  //定时500us
    count++;

    if (count == 1)  //优先级最高的中断处理程序
    {
        //处理程序1
    }
    else if (count == 2)  //次高优先级中断处理程序
    {
        //处理程序2
    }
    //其他中断处理程序
    
    count = 0;  //重置计数器
}

void main(void)
{
    TMOD = 0x01;  //使用定时器0,工作在方式1
    TH0 = 0xff;
    TL0 = 0xf6;   //定时500us
    TR0 = 0;
    ET0 = 1;      //开启定时器0中断

    IT1 = 3;      //设置双边沿触发方式
    EX1 = 1;      //开启外部中断

    EA = 1;       //开启总中断

    LED = 0xff;   //LED灭

    while(1)
    {
        //主程序代码
    }
}

 需要注意的是,在这个程序里,我们使用了两个中断服务程序:int1()timer0_isr()。其中,int1()用于处理按键双边沿触发事件,实现精确的消抖;timer0_isr()用于处理定时器0溢出事件,模拟多重中断处理。同时,我们还通过IT1 = 3指令将外部中断1设置为双边沿触发方式。这样,只有在按键闭合时才会产生中断请求,从而避免了按键抖动对程序的影响。


 仿真实现

按下按钮后松开:

 过程视频:

单片机中断例6-2仿真


2.例6-3

http://t.csdn.cn/PtJkaicon-default.png?t=N2N8http://t.csdn.cn/PtJka

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux学习笔记——网络基础

文章目录 计算机网络发展过程独立模式网络互联局域网LAN广域网WAN 计算机网络协议的概念网络协议协议分层OSI七层模型TCP/IP五层(或四层)模型网络传输基本流程数据包封装和分用各层间通信IP地址MAC地址端口 计算机网络发展过程 独立模式 计算机之间相互独立; 网络互联 多台计…

Docker笔记3 | 在Ubuntu下安装Docker

3 | 在Ubuntu下安装Docker 1 支持环境2 卸载旧的docker3 安装Docker3.1 添加HTTPS 传输的软件包以及 CA 证书3.2 添加软件源的 GPG 密钥3.3 添加 Docker 软件源3.4 安装Docker3.5 自动安装 4 Docker启动和验证是否安装ok4.1 启动Docker4.2 docker 用户组建立4.3 验证docker 1 支…

Shell在日常工作中的应用实践

作者&#xff1a;京东物流 李光新 1 Shell可以帮我们做什么 作为一名测试开发工程师&#xff0c;在与linux服务器交互过程中&#xff0c;大都遇到过以下这些问题&#xff1a; •一次申请多台服务器&#xff0c;多台服务器需要安装相同软件&#xff0c;配置相同的环境&#x…

Redis复制详解

Redis复制&#xff08;replica&#xff09; 前言 redis复制是什么&#xff1f; 就是主从复制&#xff0c;master以写为主&#xff0c;slave以读为主&#xff0c;当master数据发生变化时&#xff0c;自动将新的数据异步同步到其他slave数据库。 redis复制能做什么&#xff1f…

算法篇——字符串大集合(js版)

344.反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 链接&#xff1a;https://leetcode.cn/problems/r…

SWCF QA集锦待查收 (车联网与V2X、自动驾驶、5G毫米波、射频测试、频谱监测与规划等)

感谢大家的观看与支持&#xff01;我们为大家整理了本次发布会中的演讲资料&#xff0c;汇总了直播过程中的热点问题并请讲师进行了详细解答&#xff0c;在此整理分享给大家&#xff01; 演讲Q&A Q&#xff1a;目前5G天线支持最大的MIMO是多少&#xff1f; A&#xff1a;…

为什么会是植物神经紊乱 如何辨别

很多人都认为&#xff0c;疾病一定能通过仪器检查出来&#xff0c;很多时候去医院检查的时候&#xff0c;大多都需要进行各种的仪器检查&#xff0c;但是当仪器都检查不出来的时候&#xff0c;大家就认为没有生病。其实&#xff0c;当出现浑身不适的时候&#xff0c;检查检查不…

LeNet网络简介

1. 背景 主要介绍LeNet网络预测在CIFAR-10图像数据集上的训练及预测。 2. CIFAR-10图像数据集简介 CIFAR-10是一个包含了6W张32*32像素的三通道彩色图像数据集&#xff0c;图像划分为10大类&#xff0c;每个类别包含了6K张图像。其中训练集5W张&#xff0c;测试集1W张。 数…

window环境rabbitMq安装

RabbitMQ是一个开源的遵循 AMQP协议实现的基于 Erlang语言编写&#xff0c;即需要先安装部署Erlang环境再安装RabbitMQ环境*需加注意的是&#xff0c;可根据两者版本号的对应表&#xff0c;安装相应版本的Erlang和RabbitMQ。 一、安装准备工具 版本查看地址&#xff1a;Rabbi…

mysql的启动关闭原理和实战、及常见的错误排查

前言 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#xff0c;关系…

日本政府官宣:投资42亿日元,量子计算要上“云”

引《日经新闻》报道&#xff0c;日本政府宣布将投资4.2亿日元&#xff08;约合2.18亿人民币&#xff09;来支持量子计算领域的发展。这笔资金将被用于扩大云计算平台上的共享量子计算能力&#xff0c;为企业提供更加高效的量子计算服务。该计划将由东京大学领导&#xff0c;支持…

【LeetCode: 1187. 使数组严格递增 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

STL——list、stack与queue

&#x1f4d6;作者介绍&#xff1a;22级树莓人&#xff08;计算机专业&#xff09;&#xff0c;热爱编程&#xff1c;目前在c&#xff0b;&#xff0b;阶段>——目标Windows&#xff0c;MySQL&#xff0c;Qt&#xff0c;数据结构与算法&#xff0c;Linux&#xff0c;多线程&…

Springboot 整合 Mybatis

创建SpringBoot项目 首先在IDEA中创建一个SpringBoot项目&#xff0c;注意Java Version 然后Packaging为Jar包形式&#xff0c;Type改为Maven形式。 在上图的下一步中可以选择相关依赖&#xff0c;也可以在项目里面的pom文件中自己添加相关依赖&#xff0c;然后进行import也可…

在外包搞了7年,废了.....

我以自身的经验告诫大家&#xff0c;不要去外包&#xff0c;原因&#xff1a; 无法深入理解项目&#xff1a;由于外包公司通常只负责项目的某一个部分或某一个阶段&#xff0c;软件测试人员无法对整个项目进行深入了解&#xff0c;可能会影响到测试的全面性和准确性。 对测试要…

RB-PEG-NHS;NHS-PEG-Rhodamine罗丹明聚乙二醇琥珀酰亚胺 红色荧光染料罗丹明B功能化聚乙二醇

RB-PEG-NHS,罗丹明-聚乙二醇-活性脂 中文名称&#xff1a;罗丹明-聚乙二醇-活性脂 英文名称&#xff1a;RB-PEG-NHS 性状&#xff1a;固体或者粘稠液体&#xff0c;取决于分子量大小。 溶剂&#xff1a;溶于大部分有机溶剂&#xff0c;溶于水。 分子量&#xff1a;400、60…

【深度学习】RNN、LSTM、GRU

【深度学习】RNN、LSTM、GRU RNNLSTMGRU结语 RNN 和普通神经网络一样&#xff0c;RNN有输入层、输出层和隐含层&#xff0c;不一样的是RNN在不同的时间 t t t会有不同的状态&#xff0c;其中 t − 1 t-1 t−1时刻隐含层的输出会作用到 t t t时刻的隐含层。 RNN因为加入了时间…

强大的图像查看器:EdgeView mac中文

EdgeView mac中文版是mac上一款强大的图像查看软件&#xff0c;可以处理一些最流行的图像文件格式&#xff0c;同时还提供对导航杂志或漫画书的支持。EdgeView能够打开著名的图像文件格式主要包括JPG&#xff0c;GIF&#xff0c;PSD在内的多种格式文件&#xff0c;支持Retina显…

深度解析JavaScript自动化测试工具Cypress的工作运行原理

目录 引言 什么是Cypress&#xff1f; Cypress的工作原理 Cypress运行原理 Cypress和其他自动化测试工具有什么不一样&#xff1f; Cypress的缺点 【自动化测试工程师学习路线】 引言 在当今的软件开发中&#xff0c;自动化测试工具已成为不可或缺的一部分&#xff0c;…

负载均衡式在线OJ

目录 项目介绍所用技术与开发环境所用技术开发环境 项目各种安装升级 gcc安装 jsoncpp安装 cpp-httplib安装boost库安装与测试 ctemplate 项目宏观结构总体文件目录comm : 公共模块compile_run_server&#xff1a;编译和运行compiler.hpp编译runner.hpp 运行compiler_runner.hp…