发新帖本帖赏金 22.00元(功能说明)我要提问
返回列表
打印
[PIC®/AVR®/dsPIC®产品]

自学PIC汇编笔记

[复制链接]
楼主: GeekyGeek
手机看帖
扫描二维码
随时随地手机跟帖
41
GeekyGeek|  楼主 | 2015-11-6 22:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
本帖最后由 GeekyGeek 于 2015-11-7 16:44 编辑

又有好多天没更新了,不是在偷懒,是最近写的一个汇编程序碰到古怪的问题,
目前有workround的方法,运行的很好。
实现的是轮询是否按键被按下,按下了灯就全灭,释放了灯就全亮,带防抖功能,
代码如下:
;/******************************************/
          ;/* Main Program */
;/*-----------------------------------------*/
;/* OSC:      8 MHz (external crystal)      */
;/* Feature:      TIMR0 timing 1 ms         */
;/*              debounce KEY(RB0) input   */
;/*        KEY pressed, PORTD output 0x00   */
;/*        KEY release, PORTD output 0xFF   */
;/*        Repeat                           */
;/*******************************************/
LIST P=16F877A#include "p16F877A.inc"
; /*CONFIG BITS*/
; /*__config 0x3F32*/
__CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
  UDATA     0xA0
          FLAG      res 1
          STATE_KEY res 1
          TEMP      res 1
          COUNTER   res 1
          START     res 1
            LOW_TH    res 1
          HIGH_TH   res 1
    CBLOCK          0x70
          W_TEMP
          STATUS_TEMP
          PCLATH_TEMP
          FSR_TEMP
ENDC
TIME_             EQU            H'00'
DEBOUNCE_    EQU           H'01'
KEY_               EQU            H'01'

org          00H
         goto    MAIN
org          04H
          goto    TMR_ISR
TMR_ISR
      banksel          W_TEMP
      movwf      W_TEMP
      swapf      STATUS,W
      clrf       STATUS
      movwf      STATUS_TEMP
      movf          FSR,W
      movwf          FSR_TEMP
      movf       PCLATH,W
      movwf      PCLATH_TEMP
      clrf       PCLATH
      banksel          INTCON
      bcf          INTCON,TMR0IF
      banksel          TMR0
      movlw          06H
      movwf      TMR0
      banksel     FLAG
      ;bsf          FLAG,TIME_
      movf          FLAG,W
      iorlw          01H
      movwf          FLAG
EXTIN
      banksel PCLATH_TEMP
      movf           PCLATH_TEMP,W
      movwf          PCLATH
      movf            FSR_TEMP,W
      movwf            FSR
      movf            STATUS_TEMP,W
      movwf            STATUS
      swapf           W_TEMP,F
      swapf           W_TEMP,W
      retfie
MAIN
      banksel          FLAG
        movlw          00H
      movwf          FLAG
            movlw          32H
      movwf          START
      movlw          64H
      movwf          HIGH_TH
      movlw          0H
     movwf          LOW_TH
     movf          START,W
      movwf          COUNTER
           banksel          PORTB
      movf          PORTB,W
      andlw          02H
      banksel          STATE_KEY
      movwf          STATE_KEY
      banksel          OPTION_REG
      movlw      02H
      movwf      OPTION_REG
            banksel    TMR0
      movlw          06H
      movwf      TMR0
      banksel          INTCON
      clrf          INTCON
      bsf          INTCON, TMR0IE
      bsf          INTCON, GIE
      banksel          TRISD
      clrf          TRISD
      banksel     PORTD
      clrf          PORTD
LOOP
      banksel          FLAG
      btfss          FLAG,TIME_
      goto        LOOP
            bcf          FLAG,TIME_
           btfss          FLAG,DEBOUNCE_
      goto          Check_Debounce_
      nop
      goto          Do_Debounce_
      nop
LED
            btfss          STATE_KEY,KEY_
     goto          LED_OFF
      nop
      goto          LED_ON
      nop
      goto          LOOP
LED_ON
      banksel          PORTD
      movlw          0FFH
      movwf          PORTD
      goto       LOOP
LED_OFF
      banksel          PORTD
      movlw          00H
      movwf          PORTD
      goto       LOOP
Check_Debounce_
      banksel          PORTB
      movf          PORTB,W
      banksel          STATE_KEY
      andlw      02H
      xorwf          STATE_KEY,W
            movwf          TEMP
            btfss          TEMP,KEY_
      goto        LED
      nop
            ;bsf          FLAG,DEBOUNCE_
      movf          FLAG,W
      iorlw          02H
      movwf          FLAG
      nop
      goto        LED
Do_Debounce_
      banksel          PORTB
      btfsc          PORTB,KEY_
      goto          Count_Up
      goto       LED
      goto          Count_Dw
      goto       LED
Count_Up
      banksel          COUNTER
      incf          COUNTER
            movf          HIGH_TH,W
      subwf          COUNTER,W
      banksel          STATUS
      btfss      STATUS,Z
      goto       LED
      banksel          START
      movf          START,W
      movwf          COUNTER
      ;bsf          STATE_KEY, KEY_
      movf          STATE_KEY
      movlw          02H
      movwf          STATE_KEY
      ;bcf          FLAG,DEBOUNCE_
      movf          FLAG
      andlw          0FDH
      movwf          FLAG
            goto       LED
Count_Dw
      banksel     COUNTER
      decf          COUNTER
            movf          LOW_TH,W
      subwf          COUNTER,W
      banksel          STATUS
      btfss          STATUS,Z
      goto       LED
      movf          START,W
      movwf          COUNTER
      ;bcf          STATE_KEY,KEY_
      movf          STATE_KEY
      andlw          0FDH
      movwf          STATE_KEY
      ;bcf          FLAG,DEBOUNCE_
      movf          FLAG
      andlw          0FDH
      movwf          FLAG
            goto       LED
      END


      新学了iorlw,btfsc,decf 三条PIC汇编指令
上面的代码UDATA那段如果0xA0改成0x20,运行怎么都不对,按下键,灯不灭。大家有没有遇到类似问题啊?虽然改成0xA0没问题了,但是还是不知道什么原因造成的。
仿真结果如下






Debounce.png (152.63 KB )

Debounce.png

使用特权

评论回复

打赏榜单

21ic小喇叭 打赏了 3.00 元 2015-11-23

42
zhoujunfeng| | 2015-11-6 22:36 | 只看该作者
想实现什么功能?

使用特权

评论回复
43
GeekyGeek|  楼主 | 2015-11-7 12:43 | 只看该作者
本帖最后由 GeekyGeek 于 2015-11-7 15:59 编辑
zhoujunfeng 发表于 2015-11-6 22:36
想实现什么功能?

具体功能:RB1接了按键,按键按下,RB1 = 0, 按键释放 RB1 = 1,
               TMR0定时1ms, 每1ms, 都去读取RB1的值,
               如果RB1=1, COUNTER++(初始值=50), 到COUNTER=100, 则确认按键释放, PORTD=0xFF, 灯全亮
               如果RB1=0, COUNTER--(初始值=50), 到COUNTER=0,则确认按键按下, PORTD=0x00, 灯全灭
               这样可以实现防抖
具体的功能全都实现了。
只是发现一个问题不知道具体原因,
就是上面的代码UDATA 那行如果后面写的地址是0xA0, 则按键按下,灯全灭,释放灯全亮,和预期的一样,没有问题。
如果UDATA后面写的地址是0x20, 则灯一直全亮,按键按下,灯也不灭。和预期的不一样,不知道为什么。

使用特权

评论回复
44
GeekyGeek|  楼主 | 2015-11-14 17:50 | 只看该作者
本帖最后由 GeekyGeek 于 2015-11-16 21:44 编辑

LIST P=16F877A#include "p16F877A.inc"
__CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
UDATA 0x20
      TEMP  res 1
      XTEMP res 1
      FLAG  res 1
      STATUS_TEMP res 1
      STATE res      1
OVER_      EQU   H'0000'
LOWER_      EQU   H'0001'
UPPER_  EQU   H'0002'
UNDER_      EQU   H'0003'
RECV_      EQU   H'0004'
Z_      EQU   H'0002'
C_      EQU   H'0000'
RET      EQU   H'0000'
  radix DEC
  #define FOSC          8000000
#define BAUDRATE    9600
#define USE_BRGH    1
#define UPP_LOW          ('a'-'A')
ifndef USE_BRGH
       #define UBRG ((((FOSC / BAUDRATE) / 32) - 1) / 2)
else
       #define UBRG ((((FOSC / BAUDRATE) / 8) -1) / 2)
endif
if UBRG > 256       error spbrg_value is out of range
endif
if UBRG == 0       error spbrg_value might be out of range
endif
org          00H
          goto    MAIN
MAIN
          call CommInit
LOOP
          movlw   0FFH
          banksel FLAG
          movwf   FLAG
                    call Receive
                    movwf   STATE
          btfss   STATE,RET
          goto    LOOP
                    call OverAlphabet
                    banksel FLAG
          btfsc   FLAG,OVER_
          goto    XSEND
                    call UnderAlphabet
                    banksel FLAG
          btfsc   FLAG,UNDER_
          goto    XSEND
                    call UpperAlphabet
         banksel FLAG
          btfsc   FLAG,UPPER_
          goto    XSEND
                    call LowerAlphabet
XSEND
          call Send
          goto LOOP
CommInit
       banksel TRISC
       bcf     TRISC,TRISC6
       bsf     TRISC,TRISC7
       movlw      (UBRG & 0xff)
       banksel SPBRG
       movwf      SPBRG
              movlw      90H
       banksel  RCSTA
       movwf      RCSTA
       ifdef      USE_BRGH
       movlw      24H
       else
       movlw      20H
       endif
      banksel      TXSTA
       movwf      TXSTA
              banksel      PIR1
       bcf      PIR1,RCIF
       return
CommExit
       banksel      RCSTA
       clrf      RCSTA
       banksel  TXSTA
       clrf      TXSTA
       return
Receive
      banksel      PIR1
       btfss      PIR1,RCIF
       retlw      0
       banksel      RCREG
       movfw      RCREG
       banksel      TEMP
       movwf      TEMP
       movwf      XTEMP
       retlw   1
OverAlphabet
       movlw      'z'
       banksel      TEMP
       subwf      TEMP,W
       movfw      STATUS
       banksel      STATUS_TEMP
       movwf      STATUS_TEMP
              btfss      STATUS_TEMP,Z_
                    goto Non_z                                               
            movlw      UPP_LOW                  ;/*  = 'z'   */
                    banksel  TEMP
       subwf      TEMP
       return
Non_z
          banksel      XTEMP
       movfw      XTEMP
       movwf      TEMP
       btfsc   STATUS_TEMP,C_            ;/*  != 'z'  */
           return                          ;/*  >'z'  */
       banksel      FLAG
       bcf      FLAG,OVER_            ;/*  <'z' */
       return
UnderAlphabet
       movlw      'A'
       subwf      TEMP,W
       movfw      STATUS
       banksel      STATUS_TEMP
       movwf      STATUS_TEMP
          btfss      STATUS_TEMP,Z_
          goto    Non_A                  
    movlw      UPP_LOW                  ;/*  = 'A'   */
       banksel  TEMP
       addwf      TEMP
       return
Non_A
        banksel      XTEMP                    ;/*  != 'A'  */
       movfw      XTEMP
       movwf      TEMP
       btfss   STATUS_TEMP,C_
                   return                          ;/*  <'A'  */
       banksel      FLAG
       bcf      FLAG,UNDER_            ;/*  >'A' */
       return
UpperAlphabet
       movlw      'Z'
       banksel      TEMP
       subwf      TEMP,W
       movfw      STATUS
       banksel      STATUS_TEMP
       movwf      STATUS_TEMP
              btfss      STATUS_TEMP,Z_
                    goto Nup_Z                                             
              movlw      UPP_LOW                  ;/*  = 'Z'   */
       banksel  TEMP
       addwf      TEMP
       return
Nup_Z
          banksel      XTEMP
       movfw     XTEMP
       movwf      TEMP
       btfss   STATUS_TEMP,C_            ;/*  != 'Z'  */
           goto    DoUpper                  ;/*  <'Z'  */
       banksel      FLAG
       bcf      FLAG,UPPER_            ;/*  >'Z' */
       return
DoUpper
       movlw    UPP_LOW
       addwf      TEMP
       return      
LowerAlphabet
       movlw      'a'
       banksel      TEMP
       subwf      TEMP,W
       movfw      STATUS
       banksel      STATUS_TEMP
       movwf      STATUS_TEMP
              btfss      STATUS_TEMP,Z_
                    goto Nlw_a                                             
              movlw      UPP_LOW                  ;/*  = 'a'   */
       banksel  TEMP
       subwf      TEMP
       return
Nlw_a
          banksel      XTEMP
       movfw      XTEMP
       movwf      TEMP
       btfsc   STATUS_TEMP,C_            ;/*  != 'a'  */
           goto    DoLower                  ;/*  >'a'  */
       banksel      FLAG
       bcf      FLAG,LOWER_            ;/*  <'a' */
       return
DoLower
       movlw    UPP_LOW
      subwf      TEMP
       return       Send
             banksel  TEMP
       movfw      TEMP
       banksel      TXREG
      movwf      TXREG
       banksel      TXSTA
TxW
      btfss      TXSTA,TRMT
       goto      TxW
       return
           END
新接触指令是retlw.仿真如下:


Uart_lpbk.png (21.21 KB )

Uart_lpbk.png

使用特权

评论回复
45
GeekyGeek|  楼主 | 2015-11-14 18:36 | 只看该作者
上面的代码实现的功能是
串口loopback的程序,
串口接收到的字符经过简单处理再发送出去。
简单处理的方式如下:
大写的字母 转换为小写的字母
小写的字母转换为大写的字母
其他保持原样

使用特权

评论回复
46
GeekyGeek|  楼主 | 2015-11-15 21:25 | 只看该作者
本帖最后由 GeekyGeek 于 2015-11-16 21:41 编辑

今天写的汇编程序功能 是输入"l"或“L”  点亮LED

输入“d"或“D”  熄灭LED

代码如下:
;/******************************************/          ;/* Main Program */
;/*-----------------------------------------*/
;/* OSC:      8 MHz (external crystal)      */
;/* Feature:      UART LOOPBACK                */
;/*              Baud Rate 9600            */
;/*                L: turn on LED*/
;/*               D: trun off LED*/
;/*                                          */
;/*******************************************/
LIST P=16F877A
#include "p16F877A.inc"
; /*CONFIG BITS*/
; /*__config 0x3F32*/
__CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
UDATA 0xA0              ;/* 如果为0x20, 仿真得到的结果不对,不知道为什么
      TEMP  res 1
      XTEMP res 1
      INDX  res 1
      HEADER res 12
      PROMPT res 2
  radix DEC
  #define FOSC          8000000
#define BAUDRATE    9600
#define USE_BRGH    1
#define UPP_LOW          ('a'-'A')
          ifndef USE_BRGH
       #define UBRG ((((FOSC / BAUDRATE) / 32) - 1) / 2)
          else
       #define UBRG ((((FOSC / BAUDRATE) / 8) -1) / 2)
         endif
if UBRG > 256       error spbrg_value is out of range
endif
if UBRG == 0       error spbrg_value might be out of range
endif
org          00H
          goto    MAIN
MAIN
          call CommInit

           banksel TRISB
          bcf     TRISB,TRISB0

          banksel INDX
          movlw  0H
          movwf  INDX
          banksel TEMP
          movlw   0H
          movwf   TEMP

          banksel HEADER
          movlw 'S'
          movwf (HEADER)
          movlw 'H'
          movwf (HEADER + 1)
          movlw 'E'
          movwf (HEADER +2)
          movlw 'L'
          movwf (HEADER + 3)
          movlw 'L'
         movwf (HEADER + 4)
          movlw 'V'
          movwf (HEADER + 5)
          movlw '1'
          movwf (HEADER + 6)
          movlw '.'
          movwf (HEADER +7)
          movlw '0'
          movwf (HEADER + 8)
          movlw 0aH
          movwf (HEADER + 9)
          movlw 0dH
          movwf (HEADER + 10)
          movlw 0H
          movwf (HEADER + 11)

          movlw '>'
          movwf PROMPT
          movlw 0H          movwf (PROMPT+1)

          banksel HEADER
          movlw   HEADER
          movwf   FSR
XHead
          movlw   0CH
          subwf   INDX,W
          btfsc   STATUS,Z
          goto    LOOP

          movf    INDF,W
          movwf   TEMP
          call    Send
          incf    INDX,F
          incf    FSR,F
          goto    XHead

LOOP
          movf PROMPT,W
          movwf TEMP
          call Send
WAIT
          banksel      PIR1
            btfss      PIR1,RCIF
          goto WAIT
          banksel      RCREG
          movfw      RCREG
          banksel      TEMP
          movwf      TEMP

          movlw    'l'
          subwf   TEMP,W
          btfss   STATUS,Z
          goto    Cont1
          goto    ON
Cont1
         movlw   'L'
          subwf   TEMP,W
          btfss   STATUS,Z
          goto    Cont2
          goto    ON
Cont2
          movlw  'd'
          subwf  TEMP,W
          btfss  STATUS,Z
          goto   Cont3
          goto   OFF
Cont3
          movlw  'D'
          subwf  TEMP,W
          btfss  STATUS,Z
          goto   Cont4
          goto   OFF
ON     
     banksel PORTB
          bsf    PORTB,RB0
          goto  Cont4
OFF   
       banksel PORTB
          bcf     PORTB,RB0
          goto  Cont4
Cont4
          call Send
          movlw 0aH
          movwf TEMP
          call Send
          movlw 0dH
          movwf TEMP
          call Send
          goto LOOP

CommInit
       banksel TRISC
      bcf     TRISC,TRISC6
       bsf     TRISC,TRISC7
       movlw      (UBRG & 0xff)
       banksel SPBRG
       movwf      SPBRG
              movlw      90H
       banksel  RCSTA
       movwf      RCSTA
       ifdef      USE_BRGH
       movlw      24H
       else
       movlw      20H
       endif
       banksel      TXSTA
       movwf      TXSTA

       banksel      PIR1
       bcf      PIR1,RCIF
       return

Send
       banksel  TEMP
       movfw      TEMP
       banksel      TXREG
      movwf      TXREG
       banksel      TXSTA
TxW
       btfss      TXSTA,TRMT
       goto      TxW
       return
      
       END

   仿真结果如下:



Shell.png (95.55 KB )

Shell.png

使用特权

评论回复

打赏榜单

21ic小喇叭 打赏了 3.00 元 2015-11-23

47
wahe2008| | 2015-12-21 16:38 | 只看该作者
这不是一般人能看懂的

使用特权

评论回复
48
GeekyGeek|  楼主 | 2015-12-23 23:24 | 只看该作者
wahe2008 发表于 2015-12-21 16:38
这不是一般人能看懂的

写的不好,水平太菜, 是很难看。 :)

使用特权

评论回复
49
bjianyu| | 2016-5-24 00:24 | 只看该作者
学了一个月的汇编,其实感觉汇编比C好玩一些;也直接一些;
楼主能不能试着写一个让LED灯渐亮再渐变的程序;
不用PWM,用占空比的方式;

使用特权

评论回复
50
zhanzr21| | 2016-5-25 20:28 | 只看该作者
bjianyu 发表于 2016-5-24 00:24
学了一个月的汇编,其实感觉汇编比C好玩一些;也直接一些;
楼主能不能试着写一个让LED灯渐亮再渐变的程序 ...

PWM就是占空比控制

使用特权

评论回复
51
zhanzr21| | 2016-5-25 20:33 | 只看该作者
根據本人實際經驗, 用8位單片機的, 還是用匯編多一些. 我為這問題特意問過Microchip廠家的支持人員, 他也說8位的用匯編的多. 只不過用匯編的用戶找他們支持的比較少. 我想應該是搞匯編一般來說經驗豐富一些吧.

不過現在情況有點發展, 片子越來越便宜, 項目越來越趕, 我看好多老工程師開始搞C語言了. 其實本質上沒有很大差別. 用8位單片機的都是圍著寄存器,中斷進行的. 用了Macro之後, 匯編程序看起來跟C差不了多少

使用特权

评论回复
52
DDDDGGGG| | 2016-10-12 12:16 | 只看该作者
从百度遛弯遛到这里来的。既然来了就顶一下了。

使用特权

评论回复
53
LEDS| | 2017-11-3 21:27 | 只看该作者
顶楼主,谢谢偻主的分享。
正在学习PIC的汇编。

使用特权

评论回复
54
WangWangKing| | 2017-11-6 21:53 | 只看该作者
学习中。。。。。

使用特权

评论回复
55
zhoujunfeng| | 2017-11-23 21:40 | 只看该作者

使用特权

评论回复
56
copower| | 2018-3-3 22:19 | 只看该作者
大神求带

使用特权

评论回复
57
JLennon| | 2018-3-4 14:53 | 只看该作者
本帖最后由 JLennon 于 2018-3-5 09:49 编辑
GeekyGeek 发表于 2015-11-6 22:21
又有好多天没更新了,不是在偷懒,是最近写的一个汇编程序碰到古怪的问题,
目前有workround的方法,运行的 ...

我遇到过类似情况,你还有这个proteus工程文件吗?发给我,我调调。可能是bank切换导致未正确赋值到变量的地址。

使用特权

评论回复
58
dengdai1399| | 2019-3-19 13:55 | 只看该作者
兄弟,你学PIC汇编有什么好的教程给推荐一下!

使用特权

评论回复
59
z_jzhao| | 2019-5-28 14:06 | 只看该作者
请教一下,LIST P=16F877A  这句是起什么作用的?你是用的MPLAB X IDE吗?

使用特权

评论回复
60
manufact| | 2019-5-29 21:14 | 只看该作者
现在学汇编的很少了

使用特权

评论回复
发新帖 本帖赏金 22.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则