精华内容
下载资源
问答
  • 51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能,keil将其翻译成汇编以后,肯定要使用R0~R7;对于51的...

    注:本文参考自https://blog.csdn.net/q2631837575/article/details/78776567

    51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能,keil将其翻译成汇编以后,肯定要使用R0~R7;对于51的中断服务函数,它没有形参,也不用返回值,但是一般肯定有局部变量,这时就需要用到R0~R7了;试想,在执行普通函数时,R0~R7已经被使用了,在执行普通函数时,一旦发生中断,而中断函数也需要使用R0~R7,那怎么办?我们最先想到的是,在执行中断服务函数前先把R0~R7入栈(像累加器A、状态PSW等也要入栈这个不用说大家也知道),在中断服务完成后把R0~R7出栈,然后就能恢复现场,回到普通函数中去了,但是这8个Rn不能直接入栈,PUSH R0这样的语句是不允许的,要想R0入栈只能用两句:MOV A R0; PUSH A;这样的后果是,每次工作寄存器入栈都需要2*8=16条汇编语句才能完成,再加上A、B、PSW等寄存器入栈等,相当于每次中断都要消耗大量的时间来出栈入栈,影响程序速度。如何解决这一问题呢?51提供了这样一种机制,切换工作寄存器组,过程如下:

        普通函数的执行过程中正在使用BANK0的R0~R7,执行过程中突然发生了中断,而中断函数也想使用R0~R7,在执行中断服务函数前,我们切换工作寄存器组,切换的具体方法就是直接修改PSW的RS两个比特位,而不必把BANK 0入栈,本文开头的例子中using 2,就是说,在进入外部中断0的服务函数前,先入栈CPU寄存器,再把工作寄存器组由0切换成2,在退出中断服务后,先由BANK2切换回BANK0,并弹出CPU寄存器,由于BANK0和BANK2处在不同的RAM空间,互相不干扰,切换回BANK0之后就把那个普通函数的现场给恢复了。


    补图(过程图)

    展开全文
  • CC2530(51单片机内核)的IO口只能同时检查上升沿或者下降沿,因此使用两个IO口并联,获取相同的信号来检测开关的电平变化,一个检测上升沿,一个检测下降沿。 实验中发现,当开关按下时,瞬间

    工作中要通过CC2530检测交流电的开关状态,并做出相应的操作。

    原本以为是一个很简单的事情,却为此测试了两三天才算完成。

    首先我们的硬件设计可能比较简陋。所以很多事情得通过软件来规避问题。


    CC2530(51单片机内核)的IO口只能同时检查上升沿或者下降沿,因此使用两个IO口并联,获取相同的信号来检测开关的电平变化,一个检测上升沿,一个检测下降沿。

    实验中发现,当开关按下时,瞬间会同时产生上升沿和下降沿,然后再趋于稳定,因此每次不是仅进入一个IO的中断,而是两个都会触发,因此必须靠延时和电平检测来保证后续操作的正确性。

     延时去抖动的时间要经过时间测试做相应的调整,过长的话,开关的灵敏性可能就很低,按键按了之后很久才会看到正确的现象,太短的话容易发生误操作。



    展开全文
  • 51单片机——中断

    2019-04-19 16:27:32
    ## 51单片机——中断器 ** 计算机正在执行当前程序,有中断信号到来时,则停止当前程序的执行 ,转到终端服务子函数中执行,执行完返回当前程序执行,该过程称为中断中断源 称为终端类型 ,单片机能够识别的...

    51单片机——中断器

    中断

       计算机正在执行当前程序,有中断信号到来时,则停止当前程序的执行 ,转到终端服务子函数中执行,执行完返回当前程序执行,该过程称为中断。
       中断源  称为终端类型 ,单片机能够识别的中断种类和个数 
       串口中断 :两个外部中断  定时器中断
       中断服务子函数 :  中断信号产生后,cpu 需要执行的函数
       中断函数 必须烧写到固定地址  以便于终端产生时  能够调用到中断函数
       中断函数 有特殊的修饰符 或者需要注册  
    

    中断服务函数一般形式:
    函数类型 函数名(形式参数) interrupt n using n**
    关键词interrupt 后面的n 是中断信号,对于51单片机啊,n的取值为0~4,编译器从8xn+3处产生中断向量。
    具体看下图:
    AT89C51中断号和中断向量
    注:中断函数不能传递参数

    话不多说,上电路图代码

    点击button1,这个时候中断信号通过P3.2发送给主程序,立即停止主程序运行,去执行中断函数,待中断函数执行完,主程序继续执行
    点击button1,这个时候中断信号通过P3.2发送给主程序,立即停止主程序运行,去执行中断函数,待中断函数执行完,主程序继续执行

    代码:

    #include<reg51.h>
    #include<intrins.h>
    void fun()
    {
    int i=0,j=0;
    for(i;i<200;i++)
    {
    for(j=0;j<100;j++)
    {;}
    }
    }
    void intfun() interrupt 0
    {
    P2 =0xff;;
    fun();
    P2 = 0x00;
    fun();
    P2 =0xfe;
    fun();
    }

    int main()
    {
    EA = 1;// 总中断
    EX0 = 1;//允许外部中断
    IT0 =1; // 选择外部中断
    P1 =0xfe;
    while(1)
    {
    P1= crol(P1,1);
    fun();
    }
    return 0;
    }

    第一次写博客,有错误大家指出,一起进步,希望有大佬带我飞
    qq:1226337916

    展开全文
  • 51单片机串口中断实验 串口向外部发送“齐鲁工业大学”六个字,一个汉字占用两个字节,六个字占用12个字节。 #include <reg51.h> unsigned char s[] = "齐鲁工业大学"; // 延时函数 void ...

    51单片机串口中断实验


     串口向外部发送“齐鲁工业大学”六个字,一个汉字占用两个字节,六个字占用12个字节。

     #include <reg51.h>
    
     unsigned char s[] = "齐鲁工业大学";
    
    
    // 延时函数
    void Delay10ms(unsigned int c)
    {
       unsigned char a, b;
    
        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
        for (;c>0;c--)
        {
            for (b=38;b>0;b--)
            {
                for (a=130;a>0;a--);
            }          
        }       
    }
    
    
    // 初始化串口中断
    void UsartInit()
    {
        EA=0; //总中断关闭
        SCON = 0x50; // 控制寄存器
        PCON = 0x80;  // 记住就行,0x80
        TMOD = 0x20; // TMOD设置定时计数器的工作方式和功能 ,采用定时器1,工作方式2
        TH1 = 0xF3;     // 设置高八位
        TL1 = 0xF3;     // 设置低八位
        TR1=1;    // 使定时器1开始工作
        ES=1;  // 开启串口中断
        EA=1;  // 开启总中断权限
    }
    
    // 主函数
    void main()
    {
        // 初始化
        UsartInit();
        while(1)
        {      unsigned int i;
            // 发送数组数据
            for(i=0;i<12;i++)
            {
                // 将SBUF中的数据发送出去
                SBUF = s[i];
                // 如果发送完成,TI自动置1
                while(!TI);
                // 发送完成,软件置0
                TI=0;
            }
            //延时
            Delay10ms(10);
        }
    }

      

     


     

     优化之前代码,封装发送方法。

    #include <reg51.h>
    #include <stdio.h>
    
    unsigned char s[] = "齐鲁工业大学";
    
    
    // 延时函数
    void Delay10ms(unsigned int c)
    {
       unsigned char a, b;
    
        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
        for (;c>0;c--)
        {
            for (b=38;b>0;b--)
            {
                for (a=130;a>0;a--);
            }          
        }       
    }
    
    
    // 初始化串口中断
    void UartInit()
    {
        EA=0; //总中断关闭
        SCON = 0x50; // 控制寄存器
        PCON = 0x80;  // 记住就行,0x80
        TMOD = 0x20; // TMOD设置定时计数器的工作方式和功能 ,采用定时器1,工作方式2
        TH1 = 0xF3;     // 设置高八位
        TL1 = 0xF3;     // 设置低八位
        TR1=1;    // 使定时器1开始工作
        ES=1;  // 开启串口中断
        EA=1;  // 开启总中断权限
    }
    
    // 封装发送方法
    void UartSend(char *Data,char len)
    {
        unsigned int i;
        // 发送数组数据
        for(i=0;i<len;i++)
        {
            // 将SBUF中的数据发送出去
            SBUF = *Data++;
            // 如果发送完成,TI自动置1
            while(!TI);
            // 发送完成,软件置0
            TI=0;
        }
        //延时
        Delay10ms(10);
    }
    
    // 主函数
    void main()
    {
        // 初始化
        UartInit();
        while(1)
        {      
            // 调用封装的发送函数
            UartSend(s,12);
        }
    }

     


     串口接收消息,然后将消息从串口发送出去

    #include <reg51.h>
    #include <stdio.h>
    
    unsigned char s[] = "齐鲁工业大学";
    
    
    // 延时函数
    void Delay10ms(unsigned int c)
    {
       unsigned char a, b;
    
        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
        for (;c>0;c--)
        {
            for (b=38;b>0;b--)
            {
                for (a=130;a>0;a--);
            }          
        }       
    }
    
    
    // 初始化串口中断
    void UartInit()
    {
        EA=0; //总中断关闭
        SCON = 0x50; // 控制寄存器
        PCON = 0x80;  // 记住就行,0x80
        TMOD = 0x20; // TMOD设置定时计数器的工作方式和功能 ,采用定时器1,工作方式2
        TH1 = 0xF3;     // 设置高八位
        TL1 = 0xF3;     // 设置低八位
        TR1=1;    // 使定时器1开始工作
        ES=1;  // 开启串口中断
        EA=1;  // 开启总中断权限
    }
    
    // 封装发送方法
    void UartSend(char *Data,char len)
    {
        unsigned int i;
        // 发送数组数据
        for(i=0;i<len;i++)
        {
            // 将SBUF中的数据发送出去
            SBUF = *Data++;
            // 如果发送完成,TI自动置1
            while(!TI);
            // 发送完成,软件置0
            TI=0;
        }
        //延时
        Delay10ms(10);
    }
    
    
    // 接收,串口中断
    void Uart() interrupt 4
    {
        unsigned char rev;
        rev = SBUF;
        RI=0; // 接收中断标志位置0;
        SBUF = rev;
        while(!TI);
        TI = 0;       // 发送中断标志位置0;
    }
    
    // 主函数
    void main()
    {
        // 初始化
        UartInit();
        while(1)
        {      
            // 调用封装的发送函数
            // UartSend(s,12);
        }
    }

     

     


     

    实验相关寄存器


     

    转载于:https://www.cnblogs.com/wjw1014/p/10115052.html

    展开全文
  • 51单片机中断嵌套

    千次阅读 2019-11-27 10:00:22
    int1,默认这两个引脚接到key3与key4,通过按键接到p3^0,p3 ^1,返回到主函数,可以验证低级中断无法打断高级中断,以及中断返回。地址设置包含在函数里,无需单独设置。 #include<reg52.h> //对单片机各端口、...
  • 51单片机中断问题

    2010-07-22 21:17:00
    51单片机里,如果只使能一个外部中断时,可以在其子程序中加入延时函数,但如果两个外部中断均使能时,要不不加延时,要加的话,顶多只能在一个子程序中加一个延时函数。如果两个子程序都加的话,会产生莫名其妙的...
  • (2)用接在两个外部中断上的按键调整方波信号的频率,一个按键使得频率增加,一个按键使得频率减少,频率范围和频率变化步长自定; (3)按键改变频率的同时将频率值通过串口发送给上位机,在上位机的串口调试助手...
  • 函数主要分为部分: 1、 主函数部分:主函数的作用主要是识别哪一按键被按下,并且根据被按下的按键,执行相应的状态!比如按下等号键就把次加数累加起来显示出来   首先主函数调用KeyDriver函数进行...
  •  单片机中断,我感觉说白了就是,咋们的单片机在执行某段程序时,突然有人说要执行他的,然后单片机就去执行他的程序,然后完事了之后就会再回到原来执行的那段程序继续执行,就像我们写了两个函数,我在第一个函数...
  • 关键词:MCS-51单片机 中断优先级 软扩展 C51引言众所周知,MCS-51系统只提供“二级中断嵌套”,而大多数嵌入式系统希望有多于级的优先级别。因为一般来说,系统都有掉电中断,且应置为最高优先级,这样所有其它...
  • 51单片机自学笔记

    2016-07-27 22:24:19
    9.3 51单片机串行口171, 9.3.1 数据格式的设置171, 9.3.2 波特率的设置173, 9.3.3 成功设置串口初始化的步骤总结174, 9.4 51单片机“眉来眼去”174, 9.4.1 查询方式收发数据174, 9.4.2 中断方式收发数据178, ...
  • 51单片机开发指导3

    2011-10-17 22:08:50
    第三大部分讨论了C语言程序设计问题。C语言程序设计步骤与汇编语言基本...定义了特殊的重入函数和中断函数;除了一般的指针,还提供了存储器指针等。在此部分还给出了C51编程的部分技巧。最后列举了C51相关的库函数。
  • 1.1.6 at89c51单片机中断 1.1.7 at89c51单片机的时钟电路和时序 1.1.8 at89c51的工作方式 1.1.9 at89c51的程序封锁位 1.2 at89c2051单片机 1.3 stc51单片机 1.3.1 stc51单片机的特点 1.3.2 典型代表型号...
  • CPU在执行的过程中,一般来说都是在执行主程序(main函数里面的代码)。... MCS-51 单片机中,有两个外部中断(INT0与INT1),中断有两种方式低电平触发与负跳变(下降沿)触发。 下面通过讲IN...
  • 51单片机堆栈的介绍

    千次阅读 2018-02-06 09:26:57
    51单片机的单片机的堆栈是在内部RAM中开辟的。这句话表明了堆栈的位置。  那么堆栈到底有什么作用? 堆栈主要是为子程序调用和中断操作而设立的,因此对应有项功能:保护断点和保护现场。 单片机的程序...
  • 在Arduino里也有两个函数millis()和micros(),可以分别获得Arduino程序从上电以来累计运行时间的毫秒数和微秒数。我们可以利用51单片机的定时器中断实现这个功能。 具体实现的思路是设置1个长整型的全局时间变量...
  • 这次做课设整体不太顺利,因为学校的...这是个串口收发寄存器,教科书里面稀奇的是,接收、发送寄存器是两个寄存器,分别是接收寄存器、发送寄存器,不过两个寄存器的名字是一样的。可能你会疑问,他们不冲突矛盾????
  • 51单片机两个定时器分别是定时器0和1,再同时使用时的注意事项: /*定时器0的配置函数*/ void ConfigTimer0() { TMOD&=0xF0;//清空控制位 TMOD|=0x01;//设定Timer0工作在模式1,从而不影响定时器1的设定 ...
  • 准备使用两个定时器和外部中断,但在调试的时候发现当开启定时器1时程序卡死 理论上定时器0和外部中断都不会被低级的定时器1打断,但是程序还是不动了 最后分析发现是没有写定时器1的中断服务函数,即使设置了其为...
  • 一般来说,我们都是采用定时器1的模式2(自动重装模式)来作为波特率发生器的,同理,定时器1的中断也就被我们遗弃了,因为为了波特率产生的时候不会受到干扰(如果定时器1有中断函数,那么处理中断函数会关闭定时器...
  • 然而由于程序只能按顺序依次执行,缺乏灵活性,只能使用中断函数实时地处理一些较短的任务,在较复杂的应用中使用极为不便。嵌入式多任务操作系统的出现解决了这问题。在多任务系统中可以同时执行多并行任务,...
  • 这些要求就对定时器提出了要求,但是我的51单片机只有两个定时器,其中一个又有debug口的波特率产生之用。于是乎我可以用的定时器就只剩下了一个。怎么办?可能大家都只能用变量在定时中断函数去做多了任务就行了,...
  • 两个 16 位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3. 一个串行通信接口;(SCON,SBUF) 4. 一个中断控制器;(IE,IP) 针对 AT89C52 单片机,头文件 AT89x52.h 给出了 SFR 特殊功能寄存器所有端口的...
  • 2.按下按键时可能会出现动态扫描停止的情况,即只出现一数字,此时只需把动态扫描的函数放在中断函数中即可解决问题; 3.在制作时钟时,动态扫描的消影后的延时(加亮度)的时间应尽可能的短,因为在用中断函数...
  • 这里主要是对使用keil环境下,提高51单片机软件精度的问题给出自己的一点小看法,参阅了文章利用 Keil Cx51实现T0的精确定时,使用文章中的方法的确是可以提高软件精度,可是一碰到中断函数中语句较多,且main函数...
  • 6-3-3 两个外部中断 167 6-3-4 键盘中断 170 6-4 实时练习 172 第7章 定时器/计数器的应用 174 7-1 8x51的定时器/计数器 175 7-1-1 mcs-51的定时器/计数器 175 7-1-2 定时器/计数器方式寄存器tmod 175...
  • 最简单DIY的51蓝牙遥控小车设计方案 访问地址是:https://www.cirmall.com/circuit/20328源码里面有舵机控制部分的程序,但是被我注释掉了,由于舵机控制还是比较复杂,这里还是开一专题来讲解51单片机如何控制180...
  • 高手支招:请问用C语言编程使51单片机的数码管左移循环显示0-7的程序怎么编呀由于我不懂得用中断和定时,请程序里不要用那两个函数,谢谢(*^__^*) 嘻嘻…… 悬赏分:0 - 解决时间:2010-7-31 18:09 问题补充:这个是...
  • //上电消隐 dp高位 防止极短时间内出现两个数字的重叠 ReadRTC();//读取时钟 ReadRTC1(); F0= 0; if(second>= 60) F0 = 1; //错误 if(minute>= 60) F0 = 1; //错误 if(hour >= 24) F0= 1; //错误...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
热门标签
关键字:

51单片机两个中断函数