0

首先,我不能用 C 编码,它必须只是汇编。其次,我几乎不懂汇编,所以你可能不得不为我笨拙。我目前正在研究改变 PWM 的占空比(我相信这会改变亮度?)。我在这个假设中正确吗?我想慢慢地把亮度增加到满,然后慢慢地减少它,不断地。我的时间非常有限,因为我以为我已经弄清楚了,但显然我没有。我的代码如下,如果有人能解释我做错了什么,我将不胜感激!

#include "msp430.h"                     ; #define controlled include file

        NAME    main                    ; module name

        PUBLIC  main                    ; make the main label visible
                                        ; outside this module
        ORG     0FFFEh
        DC16    init                    ; set reset vector to 'init' label

        RSEG    CSTACK                  ; pre-declaration of segment
        RSEG    DATA16_HEAP
        RSEG    DATA16_N
X       DW      0d                      ; create X
Y       DW      1000-1d                 ; create Y
        RSEG    CODE                    ; place program in 'CODE' segment

init:   MOV     #SFE(CSTACK), SP        ; set up stack

main:   NOP                             ; main program
        MOV.W   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
        bis.b   #01000000b, &P1DIR      ; Set P1.6 to output direction
        bis.b   #01000000b, &P1SEL      ; P1.6 to TA0.1
        mov.w   #1000-1, &CCR0          ; PWM Period
        mov.w   #OUTMOD_7, &CCTL1       ; CCR1 reset/set
        mov.w   #100, &CCR1              ; CCR1 PWM duty cycle
        MOV.W   #CCIE, &TACCTL0         ; TACCRO interrupt enabled
        mov.w   #TASSEL_2 + MC_1, &TACTL; SMCLK, up mode
        bis.w   #CPUOFF+GIE, SR         ; Low-power mode and 
                                        ; global interrupt enabled
        JMP $                           ; jump to current location '$'
                                        ; (endless loop)
TA0_ISR:
        CLRN
        CMP     #1000-1, X
        JN INCX                         ; if X less than period, increment
        CLRN
        CMP     #Y, 0d                  ; if y > 0, decrement
        JN DECY
        MOV.W   #1000-1, &Y             ; if neither, set y to period

DECY:    
        DEC.W   Y                       ; decrement y
        MOV.W   #Y, &CCR1               ; set y to duty cycle
        CLRN
        CMP     #Y, 0d                  ; if y is greater than 0, reti
        JN FIN
        MOV.W   #0, &X                  ; else, set x to 0

INCX: 
        INC.W   X                       ; increment x
        MOV.W   #X, &CCR1               ; set x to duty cycle

FIN:
        RETI                            ; Return from interrupt
; The following specifies the timer interrupt vector
        COMMON  INTVEC                  ; Interrupt Vectors
        ORG     TIMER0_A0_VECTOR        ; Timer_A0 Vector
        DW      TA0_ISR                 ; Define a word with value TA0_ISR
        END
4

0 回答 0