精华内容
下载资源
问答
  • 51单片机外部中断拓展(两个以上的外部中断

    千次阅读 多人点赞 2021-05-14 14:17:03
    而很多现实场景需要有多外部中断同时进行,这时候单片机自带的外部中断端口可能就不够用了,那么,怎么解决这问题呢,本文将会用最典型的51单片机为例,介绍种较简单的拓展外部中断的方法。

    前言

    为什么要拓展外部中断

    在很多单片机中,外部中断的个数都是有限的,而很多现实场景需要有多个外部中断同时进行,这时候单片机自带的外部中断端口可能就不够用了,那么,怎么解决这个问题呢,本文将会用最典型的51单片机为例,介绍两种较简单的拓展外部中断的方法。

    解决方案

    例题

    按下按键1执行程序a;按下按键2执行程序b,按下按键3执行程序c,按下按键4执行程序d; 注意:

    1. 每个按键具有独立性,例如按键2执行完后还能按下按键1,继续执行按键1的程序;
    2. 程序有独立性,例如:在执行按键1的程序过程中,按下其他按键,可以跳到其他按键的程序,不必等待按键1程序执行完

    第一种 外部中断的硬件拓展

    设计思路:外部中断的前提是在P3.2或者P3.3引脚收到外部中断请求。所以只要能让这里的中断源在触发的同时也能触发P3.2或者P3.3引脚,中断成立。

    实现代码: (没有特殊要求,正常写就行)

    #include <reg51.h>
    unsigned char key;
    sbit K1=P1^0;
    sbit K2=P1^1;
    sbit K3=P1^2;
    sbit K4=P1^3;
    
    void one(){}
    void two(){}
    void three(){}
    void four(){}
    
    void main()
    {
    	IT0=0;
    	EX0=1; 
    	EA=1;
    	while(1)
    	{
    		switch(key)
    		{
    			case 1:one();break;
    			case 2:two();break;
    			case 3:three();break;
    			case 4:four();break;
    		}
    	}
    }
    void Int0()	interrupt 0
    {
    	if(K1==0)
    	{
    		while(K1==0);
    		key=1;
    	}
    	if(K2==0)
    	{
    		while(K2==0);
    		key=2;
    	}
    	if(K3==0)
    	{
    		while(K3==0);
    		key=3;
    	}
    	if(K4==0)
    	{
    		while(K4==0);
    		key=4;
    	}
    }
    

    PDS仿真图:(这个是重点)

    在这里插入图片描述
    这里我是将P3.2引脚通过二极管与按键接在了一起,这样每次按下按键的同时,这条电路为通路,P3.2引脚被接地,中断信号有效,则中断成功。

    第二种 用定时器/计数器代替外部中断

    因为单片机的定时器/计数器本质上就是个加一计数器,当T0或者T1溢出的时候会请求中断。所以根据这个原理,先把定时器/计数器设置成计数模式,初始值为满值,把外部中断源输入到P3.4或者P3.5引脚,这样每输入一个下降沿,都将TF0/TF1置1,中断成立。

    实现代码:

    #include <reg51.h>
    unsigned char key;
    sbit K1=P3^2;
    sbit K2=P3^4;
    sbit K3=P3^3;
    sbit K4=P3^5;
    void one(){}
    void two(){}
    void three(){}
    void four(){}
    
    void main()
    {
    	TMOD=0xee;
    	TH0=0xff;
    	TL0=0xff;
    	TH1=0xff;
    	TL1=0xff;
    	TR0=1;
    	TR1=1;
    	ET0=1;
    	ET1=1;
    
    	IT0=0;
    	EX0=1;
    	IT1=0;
    	EX1=1;
    	 
    	EA=1;
    
    	while(1)
    	{
    		switch(key)
    		{
    			case 1:one();break;
    			case 2:two();break;
    			case 3:three();break;
    			case 4:four();break;
    		}
    	}
    }
    
    void Int0()	interrupt 0
    {
    	if(K1==0)
    	{
    		while(K1==0);
    		key=1;
    	}
    }  
    void t0() interrupt 1
    {
    	if(K2==0)
    	{
    		while(K2==0);
    		key=2;
    	}
    }
    
    void Int1()	interrupt 2
    {
    	if(K3==0)
    	{
    		while(K3==0);
    		key=3;
    	}
    }
    void t1() interrupt 3
    {
    	if(K4==0)
    	{
    		while(K4==0);
    		key=4;
    	}
    }
    
    

    PDS仿真图:(注意引脚)

    在这里插入图片描述
    这里我先将两个定时器/计数器设置为工作方式2并且储值设满(因为是八位的所以最大计数值= 2^8=256),当接在P3.4或者P3.5引脚有电平发生负跳变时(即按钮按下),对应计数器加1产生溢出,发出中断请求,同时,计数器恢复初值(满值)。这样,P3.4或者P3.5引脚每输入一个下降沿(即按钮按下),都将会让对应计数器发出中断请求。

    总结

    以上就是单片机外部中断拓展的两种思路,这两种方法比较容易理解也较容易实现,但是各有各的利弊。

    方法一的利弊

    方法一在代码上没有过多的要求,按照平时书写就能实现。
    缺点在于成品的连接,在一般的单片机学习板上并没有能实现这种方法的连接,所以只能用仿真来模拟。
    优点是程序简洁,占用内存小,而且没有中断源数量的限制,甚至可以只使用一个中断触发端口(P3.2/P3.3),其余的I/O端口都可以作为中断源。

    方法二的利弊

    缺点是程序繁琐,调用资源多,而且有中断源数量的限制,最多只能有“中断端口数+定时器/计数器端口数”个中断源。
    优点是接线简单明了,在一般的单片机学习板上就能实现,不用额外接线。

    后记
    本人是电竞专业大一在读,从高中开始自学c语言和单片机,第一次发文难免有不足之处,如果有哪里不对的地方还请各位大大不吝指教

    展开全文
  • 中断处理程序:在响应一特定中断的时候,内核会执行一函数,该函数叫做中断处理程序。产生中断的每一设备都有一相应的中断处理程序。中断处理程序是被内核调用来响应中断的,他们运行于中断上下文中,该上下...

    Linux中断知识汇总:

    【深入理解Linux内核】【中断】内容汇总帖


    目录

    什么是中断处理程序?

    注册中断处理程序

    编写中断处理程序

    编写中断处理程序的注意事项

    为什么在中断里不可以睡眠?

    为什么在中断里不可以使用耗时很长的函数?


    什么是中断处理程序?

    中断处理程序:在响应一个特定中断的时候,内核会执行一个函数,该函数叫做中断处理程序。产生中断的每一个设备都有一个相应的中断处理程序。中断处理程序是被内核调用来响应中断的,他们运行于中断上下文中,该上下文中的代码不可阻塞。

    我们一般把中断处理分为两个部分。中断处理程序是上半部——接收到一个中断就立即开始执行,通常用于做有严格时限的工作。能够被允许稍后运行的工作会被推迟到下半部去。此后在合适的时机,下半部会被运行。


    注册中断处理程序

    int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
    
    具体说明:
    irq是要申请的硬件中断号。
    handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。
    irqflags是中断处理的属性:
        若设置了IRQF_DISABLED (老版本中的SA_INTERRUPT,本版zhon已经不支持了),则表示中断处理程序是 快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;
        若设置了IRQF_SHARED (老版本中的SA_SHIRQ),则表示多个设备共享中断;
        若设置了IRQF_SAMPLE_RANDOM(老版本中的SA_SAMPLE_RANDOM),表示对系统熵有贡献,对系统获取随机数有好处。(这几个flag是可以通过或的方式同时使用的)
    devname设置中断名称,通常是设备驱动程序的名称  在cat /proc/interrupts中可以看到此名称。
    dev_id在中断共享时会用到,一般设置为这个设备的设备结构体或者NULL。

    编写中断处理程序

    static inqreturn_t intr_handler(int irq, void *dev)
    
    
    具体说明:
    第一个参数irq就是这个处理程序要响应的中断号。如今这个参数已经没什么用了,可能只是在打印日志信息时会用到。
    第二个参数dev是一个通用指针,它在与中断处理程序注册时传递给request_irq的产生dev必须一致。dev可能指向中断处理程序使用的一个数据结构。
    中断处理程序可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED。当不是在注册处理函数期间产生源,返回IRQ_NONE。当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HALDLED。
    linux下的中断处理函数无需考虑重入,默认中断嵌套功能是不开启的。

    编写中断处理程序的注意事项

    • 不可以执行耗时的任务】代码执行效率尽量高,代码一定要简洁,尽量少调用其他函数,尽量避免增加中断的执行时长,中断处理需要快进快出。
      1. 不可以使用耗时很长的函数,因为中断会关闭调度,中断的优先级高于任何任务的优先级,长时间的中断处理会影响到系统的响应速度,使整个系统的任务无法政策运行,造成很多的任务超时,容易导致很多不可预知的后果。【可以使用中断底半部解决】
      2. 对于一些必须的操作可以放在中断中处理,其他的以异步执行的方式,放到中断底半部中解决。
    • 不可以睡眠或者放弃CPU】中断处理程序中不可以睡眠,不可以使用可能引起睡眠的函数,也不可以使用可能会引起睡眠的锁。
      1. 不可以使用metux等引起休眠的锁。可以使用自旋锁,但必须保证自旋等待时间足够短。【可以使用自旋锁解决】
      2. 不可以使用会引起休眠的函数。比如ssleep(), msleep(), kmalloc, copy_to_user(), copy_from_user() 等。
    • 中断是不可重入函数】同一时刻同一中断只能在一个CPU上被触发,中断被响应后会被关闭该中断,相同的中断处理函数不能同时在多个处理器上运行。


    为什么在中断里不可以睡眠?

    从系统调度的角度来说,调度的触发方式有几种(主动触发、睡眠、唤醒、中断退出时的判断),而在进入中断之前,系统调度会被关闭。在调度函数schedule()中,也会首先判断是否在中断上下文,如果是则直接退出。此时一旦睡眠或者放弃CPU,这时内核无法调度别的进程来执行,系统就会死掉。


    为什么在中断里不可以使用耗时很长的函数?

    因为中断会关闭调度,中断的优先级高于任何任务的优先级,长时间的中断处理会影响到系统的响应速度,使整个系统的任务无法政策运行,造成很多的任务超时,容易导致很多不可预知的后果。【可以使用中断底半部解决】

     

    展开全文
  • 32 配置两个串口透传 中断函数配置

    千次阅读 2021-10-07 23:12:57
    本文主要是记录 在中断函数内部怎么进行配置 (基于寄存器编写) void USART1_IRQHandler(void) //串口1中断服务 { if(USART1->SR & (1<<5)) //接收到数据 { USART2->DR = USART1->DR; //向...

    本文主要是记录 在中断函数内部怎么进行配置 (基于寄存器编写)

    void USART1_IRQHandler(void) //串口1中断服务
    {
    
     if(USART1->SR & (1<<5)) //接收到数据
     { 
      USART2->DR = USART1->DR; //向串口2发送
     }else if(USART1->SR & 0x40){ //发送一字节完成
    
        USART1->SR &= ~0x40;//清发送完成标志
    
     }
    }
    
    
    
    void USART2_IRQHandler(void) //串口2中断服务
    {
     if(USART2->SR & (1<<5)) //接收到数据
     { 
      USART1->DR = USART2->DR; //向串口1发送
     }else if(USART2->SR & 0x40){ //发送一字节完成
    
        USART2->SR &= ~0x40;//清发送完成标志
    
     }
    }
    

    经过本人测试 完全没有任何问题

    展开全文
  • if(flag) //以下几if分别用来选取不同的频率 if(tt==10) { tt=0; fre=50000; beep=~beep; } if(flag>=40&&flag) { tt=0; fre=50000; beep=~beep; } if(flag>=80&&flag) { tt=0; fre=10000; beep=~beep; } if(flag...

    #include//52单片机头文件#include//包含有左右循环移位子函数的库#defineuintunsignedint//宏定义#defineucharunsignedchar//宏定义sbitbeep=P2^3;uchartt;uint...

    #include //52单片机头文件

    #include //包含有左右循环移位子函数的库

    #define uint unsigned int //宏定义

    #define uchar unsigned char //宏定义

    sbit beep=P2^3;

    uchar tt;

    uint fre,flag;

    void main() //主函数

    {

    fre=50000;

    beep=0;

    TMOD=0x11;//设置定时器0,定时器1为工作方式1

    TH0=(65536-fre)/256;

    TL0=(65536-fre)%256;

    TH1=(65536-50000)/256;

    TL1=(65536-50000)%256;

    EA=1;//开总中断

    ET0=1;//开定时器0中断

    ET1=1;

    TR1=1;

    TR0=1;//启动定时器0

    while(1);//等待中断产生

    }

    void timer0() interrupt 1 //定时器0中断

    {

    TR0=0; //进中断后先把定时器0中断关闭,防止内部程序过多而造成中断丢失

    TH0=(65536-fre)/256;

    TL0=(65536-fre)%256;

    tt++;

    if(flag<40) //以下几个if分别用来选取不同的频率

    if(tt==10)

    {

    tt=0;

    fre=50000;

    beep=~beep;

    }

    if(flag>=40&&flag<80)

    {

    tt=0;

    fre=50000;

    beep=~beep;

    }

    if(flag>=80&&flag<120)

    {

    tt=0;

    fre=10000;

    beep=~beep;

    }

    if(flag>=120&&flag<160)

    {

    tt=0;

    fre=5000;

    beep=~beep;

    }

    if(flag>=160&&flag<200)

    {

    tt=0;

    fre=2500;

    beep=~beep;

    }

    if(flag>=200&&flag<240)

    {

    tt=0;

    fre=1250;

    beep=~beep;

    }

    if(flag>=240&&flag<280)

    {

    tt=0;

    fre=625;

    beep=~beep;

    }

    if(flag>=280&&flag<320)

    {

    tt=0;

    fre=312;

    beep=~beep;

    }

    if(flag>=320&&flag<360)

    {

    tt=0;

    fre=156;

    beep=~beep;

    }

    TR0=1;

    }

    void timer1() interrupt 3 //定时器1中断用来产生2秒时间定时

    {

    TH1=(65536-50000)/256;

    TL1=(65536-50000)%256;

    flag++;

    if(flag==360)

    {

    flag=0;

    fre=50000;

    }

    }

    程序如上所述,望能解释一下!!

    展开

    展开全文
  • 诊断代码却显示执行了32次外部中断服务函数,也就是说一次中断事件,产生了中断。以下将这种问题简称为中断执行异常问题。 期间排除掉红外遥控硬件电路、软件配置、红外遥控头输出波形、CPU勘误等可能性。 最后...
  • 直接访问寄存器和端口定义sfr P0 0x80sfr P1 0x81sfr ADCON;...在使用了interrupt 1 关键字之后,会自动生成中断向量在 ISR中不能 与其他 “后台循环代码”(the background loop code) 共享局部变量,因为连接器...
  • 初始化编程时只高5位,低3位0。低3位的实际值由外设所连接的IRi引脚编号决定,并由8259自动填写,比如连接IR5,则低3位为5。 ICW3进行级联方式设置。只有系统存在2片以上8259时启用,否则不用。 ICW4
  • )运算符允许你连续执行多命令,而不管前面的每命令是否成功,例如,打开终端窗口(在Ubuntu和Linux Mint中 Ctrl Alt T),然后,在一行中键入以下三命令,用分号分隔,然后按Enter,这会列出当前目录(ls ),找出...
  • 说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机...中断的优先级有两个:查询优先级和执行优先级。什么是查询优级呢?我们从datasheet或书上看到的...
  • 完整的中断处理过程应该包括

    千次阅读 2020-12-23 01:30:11
    外部设备发出中断请求信号要具备以下两个条件:(1)外部设备的工作已经告一段落。例如输入设备只有在启动后,将要输入的数据送到接口电路的数据寄存器(即准备好要输入的数据)之后,才可以向CPU发出中断请求。(2)系统...
  • 6.STC15W408AS单片机外部中断

    千次阅读 2021-07-15 09:29:24
    STC15W408AS单片机有4外部中断,它们分别是:外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)。 外部中断0(INT0)和外部中断1(INT1)触发有种触发方式,上升沿或下降沿均可触发方式 和仅...
  • 关于STM32F407一次事件触发中断

    千次阅读 2021-01-03 22:29:49
    关于STM32F407一次事件触发中断问题描述“bug的提出”“bug的解决”功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一适合你的列表创建一表格...
  • 中断优先级

    千次阅读 2021-07-25 04:32:43
    为使系统能及时响应并处理发生的所有中断,系统根据引起中断事件的重要性和紧迫程度,硬件将中断源分为若干级别,称作中断优先级。在实际系统中,常常遇到多个中断源同时请求中断的情况,这时CPU必须确定首先为哪...
  • 中断中断处理流程

    千次阅读 2020-12-20 04:41:20
    1. 中断概念中断是指由于...硬件中断导致处理器通过一上下文切换(context switch)来保存执行状态(以程序计数器和程序状态等寄存器信息为主);软件中断则通常作为CPU指令集中的一指令,以可编程的方式直接指...
  • 按键中断实验 概述 1.1 资源概述 开发板:正点原子STM32F103zet6...key3:灯亮,再按一下灯灭 反正就是按一下按键,灯的状态就反转 2、使用外部中断库函数流程 3、具体部分代码 exti.c #include "exti.h" #include
  • 1、熟悉51单片机的5个中断源; 2、掌握外部中断中断初始化和中断服务函数的程序编写方法,编程实现实现数码管上显示外部中断计数。 【实验内容】 1、用Proteus绘制硬件原理图,并设置元件参数; 2、用
  • 文章目录第八章 中断系统8.1 中断的基本概念8.1.1 中断概念的引入及描述中断方式示意(以输入中断为例)**中断**的定义8.1.2 中断源及中断分类中断的分类8.1.3 中断类型码中断类型码中断向量中断向量表中断向量表的...
  • ZYNQ-多中断控制

    千次阅读 2021-12-04 17:45:37
    前言 我发现很多的讲解都是单个中断的控制是如何实现...软件生成的中断被路由到一个或者两个CPU中 SPI 共享中断 共享的外设中断(SPI)是由PS和PL中的各种I/O和内存控制器生成的,它们被路由到其中一个或两个cpu。来自P
  • 满意答案 dky1583 2016.01.11 采纳率:46% 等级:7 已帮助:260人 ORG 0000H LJMP MAIN ORG 0003H LJMP LEDST ORG 0100H MAIN:...按按钮,则开始用中断控制三种流水灯的花样3.三种花样闪烁三次返回主程序 00分享举报
  • 中断函数写法的比较

    2021-01-14 05:04:11
    单片机程序,中断是免不了的。我比较喜欢用C单片机程序,简单而且可读性高,当然程序效率没有汇编的高。目前过51单片机跟AVR单片机的C程序,最近在看MSP430的书。用C不同的单片机程序其实都是大同小异,因此...
  • 1、安卓微信双卡方法:准备工作从上图我们可以看到,小编在自己的手机上已经安装了两个不同版本的微信。通常在自己的手机上安装同一应用程序时,无论是安装相同版本还是安装不同版本,后安装的应用都会将先安装的...
  • 设计中断服务子程序需要首先明确以下几问题。中断服务子程序设计的任务中断服务子程序设计的基本任务有下列4条:(1)设置中断允许控制寄存器IE,允许相应的中断请求源中断。(2)设置中断优先级寄存器IP,确定并分配...
  • #include "DSP280x_Device.h" #include "DSP280x_Examples.h" interrupt void ECAN0INTA(void) ;...现在数据能从上位机发送到dsp的输入引脚上了,但是dsp就是不进入接受中断。请高手帮忙一下。跪谢!
  • 8051单片机实战分析(以STC89C52RC为例) | 01 - 点亮一LED 8051单片机实战分析(以STC89C52RC为例) | 02 - LED延时约5s闪烁 8051单片机实战分析(以STC89C52RC为例) | 03 - LED流水灯 8051单片机实战分析(以...
  • 单片机有两个16位的可编程的定时器/计数器`T0`和`T1`,可用作定时或延时,它们具有`两种工作模式`(计数模式和定时模式)和`四种工作方式`(工作方式0、工作方式1、工作方式2、工作方式3),定时器/计数器的核心部件...
  • 定时器中断函数的使用

    千次阅读 2021-05-19 18:41:36
    同样定时器0的中断函数使能如下 至于“interrupt”后面的数字为什么是1,请再看我们以前给过大家的这个图的中断函数编号就明白了 这些编号是为了区分哪些硬件资源的相关中断函数,如果我们同时使用两个定时器,那么...
  • c语言中的中断函数注意事项单片机_C语言函数_中断函数(中断服务程序)在开始写中断函数之前,我们来一起回顾一下,...(8051有3个内部中断源T0,T1,串行口,2个外部中断源INT0,INT1(这两个低电平有效,上面的那个...
  • 外部中断NMI中断.ppt

    千次阅读 2020-12-28 21:29:32
    * 1、数据总线驱动器 和CPU的DB相连,用于传送CPU给8259的命令、8259的状态、和中断类型号n。 2、读写控制逻辑接收CPU送来的读写命令信号、片选信号、端口选择信号A0。A0用来选择8259的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 632,351
精华内容 252,940
关键字:

中断两个字怎么写