zoukankan      html  css  js  c++  java
  • 51单片机寄存器组的设置(转)

    源:http://www.cnblogs.com/bingoo/p/3460437.html

    大家都知道51单片机有的寄存器R0-R7共有四组。最近1年来,我在与新手朋友交流时发现,很多朋友对寄存器组的使用时经常出现问题。虽然这并不是多难的问题,但如果出现错误,也会造成很严重的后果。

        首先介绍一下51的寄存器组:

        通过设置PSW寄存器的第3位和第4位可以任意切换寄存器组。在进入中断前,切换寄存器组,可以方便的保护原寄存器组的数据不被中断里的语句破坏,很方便。

    RS1 RS0             字节地址

     0   0   0组寄存器  00H~07H

     0   1   1组寄存器  08H~0FH

     1   0   2组寄存器  10H~17H

     1   1   3组寄存器  18H~1FH

     RS1=PSW.4 RS0=PSW.3

    常见错误有三种:

    1、为中断函数指定了第0组寄存器 

        C程序: void int0() interrupt 0 using 0

        编译后的汇编如下:

        PUSH  ACC 

        PUSH  B

        PUSH  DPH

        PUSH  DPL

        PUSH  PSW

        MOV   PSW,#0x00  

        。。。。。。

        因为main()函数使用的就是第0组寄存器,中断程序会改变寄存器组的数据。主程序运行时,随时都有可能产生中断,等中断返回主程序时,寄存器R0-R7的值已经被改变了。这是非常严重的错误。而且故障时有时无,错误也是莫明其妙。

    2、中断优先级不同,寄存器组号相同

        C程序: void int0()  interrupt  0  using  1  //低优先级中断

                 void T0()  interrupt  1  using  1  //高优先级中断 

        因为高优先级的中断可以打断正在执行的低级中断,转向持行高级中断。这就是所谓的中断的中断。与第1种错语一样,高级中断的程序,会改变低级中断正在使用的寄存器。

    3、不写using 。严格的说,这样写不能算是错误。但这是相当不好的习惯。

        C程序: void int0()  interrupt  0

        编译后的汇编如下:

        PUSH  ACC 

        PUSH  B

        PUSH  DPH

        PUSH  DPL

        PUSH  PSW

        MOV   PSW,#0x00  

        PUSH  0x00

        PUSH  0x01

        PUSH  0x02

        PUSH  0x03

        PUSH  0x04

        PUSH  0x05

        PUSH  0x06

        PUSH  0x07

        。。。。。。

        没用using指定寄存器组,编译器就默认分配了第0组寄存器,然后又用8条语句把第0组的R0-R7保存到栈中,退出中断时还需要8个弹栈。这样“笨拙”的写法,占用了程序空间32个字节、占有堆栈8个字节。也许高级版本的编译器会改进吧,搞单片机的还是规矩些好。

        

    经验总结:

        1、写中断程序一定要用using语句指定寄存器组。第1、2、3组都可以,不能是0.

        2、51单片机的中断有两个优先级。一个中断不会打断另一个相同优先级的中断。这样相同级别中断可以使用同一个组。比如:低优先级的中断函数都用 using 1,高优先级的中断都用 using 2 。这样不会冲突。

        下面是一个正常的例子:

        C程序: void int0() interrupt 0 using 1

        编译后的汇编如下:

        PUSH  ACC 

        PUSH  B

        PUSH  DPH

        PUSH  DPL

        PUSH  PSW

        MOV   PSW,#0x08  

            。。。。。。

        

        就是这么简单。虽然这点事儿对老鸟不算什么问题,但新手朋友犯此错误的可不少。我遇到的就不下15个了。今天我写这个贴子,也是为所有新手提个醒。到处救火不如防患于未燃。

  • 相关阅读:
    2017ICPC南宁补题
    H. The Game of Life
    I
    Twice Equation
    (贪心+队列)String
    Marcin and Training Camp
    莫比乌斯函数模版
    HDU-1695 莫比乌斯反演
    Steps to One DP+莫比乌斯反演
    Educational Codeforces Round 62 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/LittleTiger/p/3969620.html
Copyright © 2011-2022 走看看