0

First of all, I cannot code in C, it must be only assembly. Secondly, I only barely understand assembly, so you may have to dumb it down for me. I am currently working on is changing the duty cycle in a PWM (I believe this will change the brightness?). Am I correct in this assumption? I want to slowly increase the brightness to full, then slowly decrease it, continuously. I am very limited on time, because I thought I had this figured out, but apparently I do not. My code is below, if anyone could explain what I'm doing wrong, I would be very appreciative!

#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
  • If you're driving an LED, then yes, changing the PWM duty cycle will effectively change the visible brightness (at least for humans). – Brian Knoblauch Apr 29 '13 at 18:48
  • OK, so why is it that when I run this code, it stays at max brightness? And yes, I'm using LED 2 as the output. – Jaysen Stoudt Apr 29 '13 at 18:50
  • Some details on the syntax. If you want to refer to a variable in memory, use `&y`. When using `#y` you are using the *address of* y. There is no need to do a `CLRN` before a `CMP`. Also, if you want initialized variables in RAM, you have to manually set the values in your init code (or use the C startup suppled with the compiler). – Lindydancer Apr 29 '13 at 19:32
  • I've only used PWM with other microcontrollers, never on an MSP430, so I can't say until I've had a chance to go dig out my MSP430 and experiment. :-) I'm leaning towards a bad flag or misunderstanding on how it should be setup on this platform. – Brian Knoblauch Apr 29 '13 at 19:32
  • Brian, if you figure something out, please let me know. @Lindydancer, what do you mean "if you want initialized variables in RAM, you have to manually set the values in your init code"? – Jaysen Stoudt Apr 29 '13 at 19:36
  • The RAM of a microcontroller contains garbage, after power on. If you intend to place specific values in it, they must be initialized by the startup code. (The C startup code, supplied with the compiler, zeros the DATA16_Z segment and copies DATA16_ID from read-only memory to DATA16_I in RAM.) I suggest that you use `DS16` to reserve space in the `DATA16_N` segment and explicitly use `MOV.W` to set the values in your init routine. Alternatively, you could mimic the compiler and use the C startup code, but that might be more work than it's worth in this case. – Lindydancer Apr 30 '13 at 06:42

0 Answers0