$regfile = "m32def.dat" ' By Magic White Smoke $crystal = 8000000 $hwstack = 64 $swstack = 64 $framesize = 64 Pwm_port Alias PortC ' Port für PWM PWM_Dir Alias DDRC ' Data Direction Register PWM PWM_Dir = &hFF ' Als Ausgang Const PWM_Arr_Steps = 55 Dim Comp_Val(PWM_Arr_Steps) as Byte ' Vergleichswert der PWM Dim Next_OCR_Val(PWM_Arr_Steps) as Byte ' Nächster Compare Wert für OCR1A Dim PWM_settings(8) as Byte ' Werte der 8 PWM Kanäle Dim Ctr as Byte , CV as Byte , NO as Byte Dim Arr_Ctr as Byte , i as Byte On COMPARE1A TIMER1_COMPA Nosave ' Routine für Compare A Timer Interrupt Pwm_port = 0 ' 8 PWM Ausgänge auf 0 TCCR1B = 3 ' Prescaler 64, kein HW PWM Restore PWM_Tbl ' Vergleichswerte sowie Zeiten für OCR1A in Tabellen laden For Ctr = 1 to PWM_Arr_Steps Read CV : Read NO Comp_Val(Ctr) = CV Next_OCR_Val(Ctr) = NO Next Ctr OCR1A = 255 Set TCCR1B.CTC1 Set TIMSK.OCIE1A ' TimerA-Interrupt freigeben Enable Interrupts Const Wms = 10 Const Steps = 63 do For i = 0 to Steps PWM_settings(1) = i waitms Wms next i For i = Steps to 0 step -1 PWM_settings(1) = i waitms Wms next i For i = 0 to Steps PWM_settings(2) = i waitms Wms next i For i = Steps to 0 step -1 PWM_settings(2) = i waitms Wms next i For i = 0 to Steps PWM_settings(3) = i waitms Wms next i For i = Steps to 0 step -1 PWM_settings(3) = i waitms Wms next i Loop TIMER1_COMPA: $asm PUSH XH ' Verwendete Register und Statusregister sichern PUSH XL PUSH R21 PUSH R20 PUSH R19 PUSH R18 IN R18,$3F ' Sichere Statusregister PUSH R18 LDS R20,{Arr_Ctr} CLR R21 loadadr Next_OCR_Val(1) , X ADD XL, R20 ADC XH, R21 LD R18, X ' Wert von Next_OCR_Val(NO_Ctr) in R18 OUT OCR1AL , R18 CLR R21 loadadr Comp_Val(1) , X ADD XL, R20 ADC XH, R21 LD R18, X ' R18 enthält den PWM Vergleichswert CLR R21 LDS R19,{PWM_settings+0} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB0 ORI R21,&b00000001 NoPAB0: LDS R19,{PWM_settings+1} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB1 ORI R21,&b00000010 NoPAB1: LDS R19,{PWM_settings+2} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB2 ORI R21,&b00000100 NoPAB2: LDS R19,{PWM_settings+3} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB3 ORI R21,&b00001000 NoPAB3: LDS R19,{PWM_settings+4} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB4 ORI R21,&b00001000 NoPAB4: LDS R19,{PWM_settings+5} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB5 ORI R21,&b00001000 NoPAB5: LDS R19,{PWM_settings+6} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB6 ORI R21,&b00001000 NoPAB6: LDS R19,{PWM_settings+7} CP R18, R19 ' Vergleich Arr_Ctr <= pwm_settings(x), wenn nein Carry Clear BRCC NoPAB7 ORI R21,&b00001000 NoPAB7: OUT Pwm_port , R21 ' Port B setzen CPI R20 , PWM_Arr_Steps - 1 ' Arr_Ctr noch in R20, alle PWM Schritte ausgeführt ? BREQ PWM_ALL_DONE ' Ja INC R20 ' R20 um 1 erhöhen JMP PWM_CYCLE_END PWM_ALL_DONE: CLR R20 ' Alle Schritte erreicht, auf 0 setzen PWM_CYCLE_END: STS {Arr_Ctr}, R20 ' Arr_Ctr speichern POP R18 OUT SREG , R18 ' Statusregister wieder herstellen POP R18 POP R19 POP R20 POP R21 POP XL POP XH ' Verwendete Register und Statusregister sichern $end Asm Return End ' Tabelle für Zeitpunkt und Aufaddierung PWM_Tbl: Data _ 0 , 0 , 2 , 0 , 5 , 0 , 7 , 0 , 10 , 0 , 13 , 0 , 14 , 0 , 15 , 0 , 16 , 0 , 17 , 0 , 18 , 0 , 19 , 0 , 20 , 0 , 21 , 0 , 22 , 1 , _ 23 , 1 , 24 , 1 , 25 , 2 , 26 , 2 , 27 , 2 , 28 , 3 , 29 , 2 , 30 , 3 , 31 , 4 , 32 , 4 , 33 , 4 , 34 , 5 , 35 , 6 , 36 , 6 , _ 37 , 8 , 38 , 9 , 39 , 10 , 40 , 10 , 41 , 12 , 42 , 14 , 43 , 16 , 44 , 17 , 45 , 19 , 46 , 22 , 47 , 25 , 48 , 27 , _ 49 , 29 , 50 , 35 , 51 , 38 , 52 , 41 , 53 , 48 , 54 , 53 , 55 , 59 , 56 , 66 , 57 , 73 , 58 , 82 , 59 , 92 , _ 60 , 103 , 61 , 114 , 62 , 127