Steve Meisel

PWM - period change problems

Discussion created by Steve Meisel on Nov 14, 2006
Latest reply on Nov 19, 2006 by bigmac
 
Would someone please look at my code and tell me why I am having trouble with the interrupts.
I am trying to vary the duty cycle of a pwm signal from an analog input.  Duty cycle is 20% at 0 V and 80% at full scale input.
 
Thanks,
 
Steve
 
 
 
 
 
 
       XDEF Entry, main, irq_TIMCH0, irq_TIMOvr, irq_isr
;*******************************************************************************
; Registers definition
;*******************************************************************************

   Include 'derivative.inc'  ; Include derivative-specific definitions
CURRPOS EQU $00FE                  ; Current Valve Position stored in RAM
         
;*******************************************************************************
DEFAULT_ROM             SECTION
;*******************************************************************************
; Peripheral Initialization
;*******************************************************************************
init:
       bset 0, CONFIG1                 ; Disables COP
       mov #$49, CONFIG2               ; Enables external oscillator and IRQ/RST pin  
       mov #$02, OSCSTAT               ; Enables external clock generator
       mov #$FF, DDRB                  ; Configures port B as output          
       mov #$21, ADSCR                 ; Enables ADC channel 1
       mov #$60, ADICLK                ; Bus clock / 8
       rts
       
;*****************************************************************************
;   PWM INITIALIZATION
;*****************************************************************************
;**********************************************************************************************
;      PWM INITIALIZATION
;**********************************************************************************************
pwm_init:
       BSET    TSC_TSTOP,TSC           ; TSTOP - Stop the timer
       BSET    TSC_TRST,TSC            ; TRST - Reset the count
               
       MOV     #$68,   TMODH           ; Set the PWM period (150Hz) - high byte
       MOV     #$2A,   TMODL           ;                            - low byte
       
       MOV     #$14,   TCH0H           ; Set initial output to 20% duty cycle (pulse width)
       MOV     #$D5,   TCH0L
       
                                       ; 80% = 5355h
                                       ; 20% = 14D5h
                                       ; 16MHz / 4 = 4MHz e-clock
                                       ; Oscillator is 16MHz. 16M/4=4Mz e-clock
                                       ; 4M/150 = 26667(682Ah) = period
                                       ; TMODH & TMODL = 682A
                                       ; 26667 * .8 = 21333 (5355h)
                                       ; 26667 * .2 = 5333  (14D5h)
                                       ; 21333-5333 = 16K   (3E80h)
                                       ; 16K/128 = 125      (7Dh)   conversion constant
                                     
       
       BCLR    TSC0_MS0B,TSC0                                                                       
       BSET    TSC0_MS0A,TSC0          ; Unbuffered output compare       
       
       BSET    TSC0_TOV0,TSC0
       
       BSET    TSC0_ELS0B,TSC0         ; ELS0B - Set the output polatity to 1
       BSET    TSC0_ELS0A,TSC0         ; ELS0A - Clear the output on compare
       
       BCLR    TSC_TSTOP,TSC           ; Restart the TIM
       
       BSET    PTB_PTB4,PTB            ; debug - set #4 led
       
       rts
;*******************************************************************************
;
;       MAIN CODE
;
;*******************************************************************************
Entry:
main:
       rsp                             ; SP <- 0xFF
       cli                             ; Enables global interrupts
       bsr init                        ; Peripheral initialization
       bsr pwm_init                    ; Initialize the PWM @ TCH0 unbuffered
       MOV #$00,CURRPOS                ; Initialize the current valve position to 0
       
main_loop:
       
       LDA ADR                         ; load ACC with the AD value
       CMP CURRPOS                     ; Compare the input with the previous positon
       BLO SHORTER                     ; Decrease the PWM period
       BHI LONGER                      ; Increase the PWM period
       BCLR    TSC0_CH0IE,TSC0         ; Disable the interrupt
       BCLR    TSC_TOIE,TSC            ; Disable the interrupt
       BRA main_loop                   ; Loop forever
       
SHORTER BSET    TSC0_CH0IE,TSC0         ; Enable CH0 output compare interrupt
       WAIT
       BRA main_loop

LONGER  BSET    TSC_TOIE,TSC            ; Enable TIM overflow interrupts
       WAIT
       BRA main_loop
 
;********************************************************************************
;
;       PWM PERIOD CHANGE INTERRUPTS
;
;********************************************************************************
irq_TIMCH0:                             ; TIM channel 0 output compare interrupt - shorter period
       
       JSR NEW_PERIOD
       BCLR    PTB_PTB7,PTB            ; debug - clear #7 led
       BSET    PTB_PTB0,PTB            ; debug - set   #0 led
       RTI
       
       
irq_TIMOvr:                             ; TIM overflow interrupt - longer period
       JSR NEW_PERIOD
       BCLR    PTB_PTB0,PTB            ; debug - clear #0 led
       BSET    PTB_PTB7,PTB            ; debug - set   #7 led
       RTI               
 

NEW_PERIOD:
       LDA ADR
       CLRH
       STA CURRPOS                     ; Store current valve postion in memory
       LDX #$7D                        ; V/DIV constant (125d)
       MUL                             ; Multiplys A and X result -> A-low byte, X-high byte
       ADD #$D5                        ; Add to get low byte (213d)
       STA TCH0L                       ; Store low byte - PWM period
       TXA                             ; Get the high byte from the MUL instruction
       ADC #$14                        ; Add from memory and carry bit to get the high byte(20d)
       STA TCH0H                       ; Store high byte - PWM period
       RTS

 

Outcomes