⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 muscle.asm

📁 Embedded magazine source code in the year 1990
💻 ASM
字号:
; Sample program: Microcontroller-Manipulated Metal Muscles
;
; Copyright (C) Brett Glass 1990
;
; Commercial use by permission only
;

; Serial port and timer parameters

SCONINI EQU     01010010b       ; Set UART for 8 bits, no interprocessor
                                ; communication features, ready to transmit.
PCONINI EQU     01000000b       ; No double baud rate; give access to FE

T1CONBITS       EQU     11001100b       ; Timer 1 bits in TCON
T1MODBITS       EQU     11110000b       ; Timer 1 bits in TMOD
T1AUTORELMOD    EQU     00100000b       ; Set this bit in TMOD for Timer 1
                                        ;  auto-reload mode

TH1INI  EQU     -104    ; 300 baud -- Constant for Timer 1 (.1-.2% error)

T0CONBITS       EQU     00110011b       ; Timer 0 bits in TCON
T0MODBITS       EQU     00001111b       ; Timer 0 bits in TMOD
T0AUTORELMOD    EQU     00000010b       ; Set this bit in TMOD for Timer 0
                                        ;  auto-reload mode

TH0INI          EQU     11111100b       ; Make Timer 0 overflow and
                                        ; reload every 4 counts, making
                                        ; a divide-by-4 prescaler.

CMODINI EQU     00000100b       ; Initialize PCA to use Timer 0 as
                                ; a prescaler

PCM     EQU     01000010b       ; Set a PCA module for PCM mode

; Initial stack pointer

INITSP  EQU     7Fh     ; Use the top 128 bytes of RAM for the
                        ; stack. This is not possible on all 8051
                        ; derivatives, so you may need to change
                        ; this equate in your system.

DEACTIVATE  EQU     P0.0,BIT ; Deactivates Biometal driver
LED     EQU         P0.1,BIT ; In my test setup, this bit lights an
                             ; LED when cleared. Used to monitor
                             ; serial transmit.

        ; PCA Register definitions (AVCASE does not include these)

CCON    EQU     0D8h    ; PCA Counter Control Register
CMOD    EQU     0D9h    ; PCA Counter Mode Register
CL      EQU     0E9h    ; PCA Counter Low
CH      EQU     0F9h    ; PCA Counter High
CCAPM0  EQU     0DAh    ; Compare/Capture Module 0 Mode
CCAP0L  EQU     0EAh    ; Compare/Capture Register 0 Low
CCAP0H  EQU     0FAh    ; Compare/Capture Register 0 High
CCAPM1  EQU     0DBh    ; Compare/Capture Module 1 Mode
CCAP1L  EQU     0EBh    ; Compare/Capture Register 1 Low
CCAP1H  EQU     0FBh    ; Compare/Capture Register 1 High
CCAPM2  EQU     0DCh    ; Compare/Capture Module 2 Mode
CCAP2L  EQU     0ECh    ; Compare/Capture Register 2 Low
CCAP2H  EQU     0FCh    ; Compare/Capture Register 2 High
CCAPM3  EQU     0DDh    ; Compare/Capture Module 3 Mode
CCAP3L  EQU     0EDh    ; Compare/Capture Register 3 Low
CCAP3H  EQU     0FDh    ; Compare/Capture Register 3 High
CCAPM4  EQU     0DEh    ; Compare/Capture Module 4 Mode
CCAP4L  EQU     0EEh    ; Compare/Capture Register 4 Low
CCAP4H  EQU     0FEh    ; Compare/Capture Register 4 High

CR      EQU     CCON.6,BIT      ; Define CR (Counter Run) for PCA

START:
        SETB    DEACTIVATE      ; Deactivate the PCM output to the wire
        CLR     LED             ; Turn LED on

        MOV     SCON,#SCONINI   ; Configure SCON
        MOV     PCON,#PCONINI   ; Configure PCON
        ANL     TCON,#LOW(NOT T1CONBITS)        ; Clear Timer 1 bits in TCON
        ANL     TMOD,#LOW(NOT T1MODBITS)        ; Clear Timer 1 bits in TMOD
        ORL     TMOD,#T1AUTORELMOD      ; Put Timer 1 in auto-reload mode
        MOV     TH1,#TH1INI     ; Set baud rate
        MOV     TL1,#TH1INI     ;  in both registers
        SETB    TR1             ; Start Timer 1 baud rate generator

        ANL     TCON,#LOW(NOT T0CONBITS)        ; Clear Timer 0 bits in TCON
        ANL     TMOD,#LOW(NOT T0MODBITS)        ; Clear Timer 0 bits in TMOD
        ORL     TMOD,#T0AUTORELMOD      ; Put Timer 1 in auto-reload mode
        MOV     TH0,#TH0INI     ; Set prescale count
        MOV     TL0,#TH0INI     ;  in both registers
        SETB    TR0             ; Start prescaler

        MOV     CMOD,#CMODINI   ; Configure PCA timer
        MOV     CCAPM0,#PCM     ; Set PCA module 0 to PCM mode
        MOV     CCAP0L,#0       ; Reset module's counter to 0
        MOV     CCAP0H,#0       ; Start the PWM counter at 0 (0% duty cycle)

        MOV     CL,#0           ; Zero PCA counter
        MOV     CH,#0
        SETB    CR              ; Start PCA via Counter Run bit

        MOV     SP,#INITSP      ; Move the stack
        MOV     DPTR,#INTROMSG  ; Send a message
        ACALL   SNDSTR
BEEP:
        MOV     A,#07h          ; Send an ASCII BEL character
        ACALL   SNDCHR
REPEAT:                         ; Interactive loop
        ACALL   GETCHR          ; Get a character
        ACALL   SNDCHR          ; Echo it
        CLR     C               ; Clear carry
        SUBB    A,#'0'          ; Subtract ASCII '0'
        JZ      ZERO            ; If '0', special processing
        JC      REPEAT          ; If less than '0', it wasn't a digit
                                ;  from '0' through '7', of course.
        CJNE    A,#8,NOTEIGHT   ; Compare nondestructively to the number '8'
        JMP     BEEP            ; A '8' is ignored
NOTEIGHT
        JNC     BEEP            ; Anything over '8' is ignored.
                                ; If execution reaches this point, we
                                ;  have a number corresponding to a
                                ;  digit between 1 and 7, inclusive.
        RL      A               ; Shift the number, multiplying it by 32
        RL      A               ; The maximum duty cycle is produced when
        RL      A               ;  a 7 is entered, in which case
        RL      A               ;  it's 7/8.
        RL      A
        MOV     CCAP0H,A        ; Move the count into the PWM register
        CLR     DEACTIVATE      ; Activate the output
        JMP     REPEAT
ZERO:
        SETB    DEACTIVATE      ; Deactivate Biometal driver
        MOV     CCAP0H,#0h      ; Set 0% duty cycle
        JMP     REPEAT

INTROMSG:
        DB      0DH,0AH
        DB      "Hit 1-7 to activate Biometal with different duty cycles."
        DB      0DH,0AH
        DB      "Hit 0 to deactivate Biometal."
        DB      0DH,0AH,0


SNDCHR  PROC                    ; Routine to send a character
        CLR     LED             ; Turn on the LED to indicate we are sending
        JNB     TI,$            ; Wait until the UART is ready
        CLR     TI              ; Mark it as not ready
        MOV     SBUF,A          ; Send character
        SETB    LED             ; Turn off the LED
        RET                     ; And return
SNDCHR  ENDPROC

        SNDSTR  PROC            ; Routine to send a string pointed to
                                ;  by R0. R0 destroyed on return.
        MOV     A,#0            ; Clear the accumulator
        MOVC    A,@A+DPTR       ; Get a character
        JNZ     L?SEND          ; If null, we're done
        RET
L?SEND:
        ACALL   SNDCHR          ; Otherwise send the character
        INC     DPTR            ; And increment the pointer
        JMP     SNDSTR
SNDSTR  ENDPROC

GETCHR  PROC                    ; Routine to get a character
        JNB     RI,$            ; Loop until character received
        CLR     RI              ; Clear received char flag right away
        JNB     RB8,GETCHR      ; If framing error (stop bit not a 1),
                                ;  reject character
        MOV     A,SBUF          ; Get char into A
        RET
GETCHR  ENDPROC

        END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -