超易学单片机入门(七)incf和decf

    下面我们学习两个新指令incf和decf,它们都是对某一个寄存器进行增1或减1操作,例句中假如我们要操作的寄存器是09H。

    movlw    02H   '常数2进入W  
    movwf    09H   '把w内的数2复制到09H 这个寄存器  
                   '现在09H寄存器内存储的数是2 
    incf     09H   '寄存器09H内存储的数增加1   
                   '现在09H内存储的数变成3 
    decf     09H   '寄存器09H内存储的数减掉1 
                   '现在09H内存储的数变成2

    movlw    0FFH  '常数255进入W  
    movwf    09H   '把w 内的数255复制到09H这个寄存器  
                   '现在09H 寄存器内存储的数是255 
    incf     09H   '寄存器09H内存储的数 增加1   
                   '现在09H内存储的数变成0 
    decf     09H   '寄存器09H内存储的数 减掉1 
                   '现在09H内存储的数又变成255

    如果你事先定义好了地址为09H的这个寄存器里存储的数字大小代表电视机节目频道的话,你会很喜欢这两个指令的。并且当节目频道到达最大值255或最小值0的时候无需担心,寄存器在0时减1会得255,255状态下增1会得0。

    至于为什么会这样,学过环形计数器的人不会感到奇怪的。你要是没有学过计数器电路也不要紧,记住一个寄存器的最大存储数值是255=0FFH就可以了,加减法都会导致它“进位”。

    当然控制音量时这个程序不能使用,因为它在0和255之间变化,音量忽大忽小怎们行。为解决这个问题,我们必须再学习两条指令incfsz和decfsz。

    它们与上两个功能基本相同,不同的是:寄存器增1或减1操作以后,该指令会自动判定寄存器内的结果是否为零,如果不为零,继续正常执行该指令后面的语句.但如果结果为零的话,则程序会"跳一步".绕过紧挨着它下面的一条指令,继续执行更下面的语句,举例子说明。

    假定我们操作的寄存器还是09H:  
    
   movlw    0FDH   '常数253进入W  
   movwf    09H    '把w 内的数253 复制到09H 这个寄存器  
                   '现在09H 寄存器内存储的数是253 
   incfsz    09H   '寄存器09H内存储的数 增加1,结果变成254结果不等于0,故程序继续执行下一指令 
   nop             '该句得到执行(因为上一句寄存器09H的计算结果不等于0)   
   incf      09H   '寄存器09H内存储的数 增加1,结果是255 
   incfsz    09H   '寄存器09H内存储的数 增加1,结果变成0   
                   '因为结果等于0,故程序要跳过下面的一句(不运行下面的一句). 
   incf      09H      '由于上一句的存在并结果为0,该句得不到执行,被忽略 
   incf      09H      '程序跳入这一句继续运行 寄存器09H内存储的数 增加1 
   nop                  '因此现在 09H寄存器存储的数是1 
   nop                  '继续运行 
        . 
        . 
        . 
      思考题:设计一段程序代码,当用户连续按下音量减小键后,判定音量寄存器09H的存储音量数值, 
防止该寄存器的值从0 变成255,以免震惊到用户。
        . 
        . 
        . 
SMALL_SOUND:  nop    '标号可以任意写的,此前用户一旦按下音量减,就把程序引导到这一句上来 
              decfsz    09H   '寄存器09H内存储的数 减1,如果结果为0 就跳一步   
              goto      OK    '如果上一句结果不为0,执行该句后,程序去了ok语句  
              movlw     01H   '跳到这一步说明寄存器结果是0 
              movwf     09    '强行把 09H内的数值写成1,仍然是小音量,这样音量不会被因为 减小而变成255

OK:        nop     '继续运行    
      . 
      . 
    思考题:利用decfsz 指令设计一段延时代码,使得延时时间可以在10个机器周期到65535个机器周期之间,可以通过程序任意控制在这个例子中,设我们要控制的延时时间大约是24086个及其周期,用16进制表是就是 5E16 H. 如果用到通用寄存器,请使用 0AH, 0BH

yanshi:       movlw              5EH             ' 常数5E进W 标号是延时 
              movwf              0BH             '0B寄存器数为5EH 
              movlw              16H              '常数16进W 
              movwf              0AH              '0A寄存器数为16H

jixu:         decfsz             0AH             '0A寄存器内的数减1,如果结果为0跳步                 
               goto                jixu              '结果不为0,继续  
         
               decfsz             0BH            '0B寄存器内的数减1,如果结果为0跳步                 
               goto                jixu               '结果不为0,继续   
         
               nop             '延时完毕 
        . 
        .      
           
    你现在可以只用这几个简单句子完成任意时间的延时程序了。

永不止步步 发表于02-13 10:07 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67410个|学分:308117个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号