| CODE |
;****************************************************** .include "1200def.inc" ;****************************************************** ; ;8 channel PWM routine. All the actiion is during the interrupt time (nothing happens ;during non-interrupt time except waiting for interrupts). There is only ;one suroutine, and its called before the interrupt, so this only uses one ;level of the stack (and an AT90S1200 doesn''t have much stack space to start with). ; ;This can be made faster by changing the interrupt timer reload value. $ED looks safe. ;It can also go faster (have a higher minimum pulse fequency) if there are fewer ;PWM channels or less resolution on the pulse width ;. .def tempcounter = r1 ;variable used to reverse order of bits .def pwmvalue = r2 ;variable used to reverse order of bits .def pwmvalue0 = r3 ;duty cycle .def pwmvalue1 = r4 ;duty cycle .def pwmvalue2 = r5 ;duty cycle .def pwmvalue3 = r6 ;duty cycle .def pwmvalue4 = r7 ;duty cycle .def pwmvalue5 = r8 ;duty cycle .def pwmvalue6 = r9 ;duty cycle .def pwmvalue7 = r10 ;duty cycle .def oldticks = r11 ;variable used to decide when to make a pulse .def ticks = r12 ;relative interrupt number mod 8 .def bout = r19 ;temporary buffer for output port b .def temp = r20 ;scratch register for non-interrupt times .def itemp = r21 ;scratch register for interrupt times ;having separate scratch registers saves stack space and time. .ORG $0000 rjmp start .ORG $0002 rjmp timerservice rjmp start rjmp start rjmp start start: ldi temp, $01; use temp to initaize prescaler to divide by 1 out TCCR0, temp ldi temp,$E0; use temp to initialize counter out TCNT0,temp ldi temp, $02; use temp to initialize TIMSK out TIMSK,temp ldi temp, $FF;set port B as output port out DDRB,temp ldi temp,$02 ;Enable timer interrupt out TIMSK,temp ldi temp,$00 mov ticks,temp ldi temp,$00; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue0, pwmvalue ldi temp,$01; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue1, pwmvalue ldi temp,$02; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue2, pwmvalue ldi temp,$0A; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue3, pwmvalue ldi temp,$80; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue4,pwmvalue ldi temp,$A0; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue5, pwmvalue ldi temp,$E0; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue6, pwmvalue ldi temp,$FF; test value for pwm value mov pwmvalue,temp rcall reversepwmvalue mov pwmvalue7, pwmvalue sei ; enable interrupts loop: ;wait here for interrupt rjmp loop ;REVERSE BIT ORDER OR PWMVALUE. Midifies pwmvalue, uses temp reversepwmvalue: ; reverse bit order in pwmvale. ldi temp,$08 ; 8 times through loop because there are 8 bits mov tempcounter,temp rotateagain: rol pwmvalue ror temp dec tempcounter brne rotateagain mov pwmvalue,temp ret timerservice: ldi itemp,$b4;set 75 clocks until next interrupt out TCNT0,itemp out portb,bout;transfer portb buffer to port b andi bout,$00;preset all PWM bits to zero mov oldticks,ticks;copy interrupt counter to temp inc ticks ;increment interrupt timer eor oldticks,ticks;do X-OR and AND to find bits that changed to 1 (result in temp) and oldticks,ticks;do AND to find bits that just changes to a 1 ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 0 mov itemp,oldticks and itemp,pwmvalue0;AND to find if ones in data correspond to this interrupt count change breq dontset0 ; if ones present, set lsb in portb buffer ori bout,$01 dontset0: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 1 mov itemp,oldticks and itemp,pwmvalue1;AND to find if ones in data correspond to this interrupt count change breq dontset1 ; if ones present, set lsb in portb buffer ori bout,$02 dontset1: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 2 mov itemp,oldticks and itemp,pwmvalue2;AND to find if ones in data correspond to this interrupt count change breq dontset2 ; if ones present, set lsb in portb buffer ori bout,$04 dontset2: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 3 mov itemp,oldticks and itemp,pwmvalue3;AND to find if ones in data correspond to this interrupt count change breq dontset3 ; if ones present, set lsb in portb buffer ori bout,$08 dontset3: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 3 mov itemp,oldticks and itemp,pwmvalue4;AND to find if ones in data correspond to this interrupt count change breq dontset4 ; if ones present, set lsb in portb buffer ori bout,$10 dontset4: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 3 mov itemp,oldticks and itemp,pwmvalue5;AND to find if ones in data correspond to this interrupt count change breq dontset5 ; if ones present, set lsb in portb buffer ori bout,$20 dontset5: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 3 mov itemp,oldticks and itemp,pwmvalue6;AND to find if ones in data correspond to this interrupt count change breq dontset6 ; if ones present, set lsb in portb buffer ori bout,$40 dontset6: ; OUTPUT PWM COMB WAVEFORM TO PORTB BIT 3 mov itemp,oldticks and itemp,pwmvalue7;AND to find if ones in data correspond to this interrupt count change breq dontset7 ; if ones present, set lsb in portb buffer ori bout,$80 dontset7: reti;finished with interrupt service |