📄 auto_pwm.psm
字号:
;
;**************************************************************************************
; Main program
;**************************************************************************************
;
; Provides a pattern of interest on the LEDs :-)
;
; Each LED increases intensity in 8 steps and then decreases intensity in 8 steps until it is off.
; The middle LEDs (LD2 to LD5) each start to turn on when either neighbour is turned half on and increasing
; to provide the effect of a passing a 'wave' of light passing from side to side. The pair of LEDs at each
; (LD0, Ld1 and LD6, LD7) are required to reflect the 'wave' so that the pattern continues.
;
; I'm sure this code cold be written in more elegant way, but I leave that as an exercise to you :-)
;
warm_start: LOAD s2, 03 ;simple delay loop (time will be increased by ISR processing)
delay_s2_loop: LOAD s1, FF
delay_s1_loop: LOAD s0, FF
delay_s0_loop: SUB s0, 01
JUMP NC, delay_s0_loop
SUB s1, 01
JUMP NC, delay_s1_loop
SUB s2, 01
JUMP NC, delay_s2_loop
;
;Pattern generation
;
FETCH s0, LED0_sequence ;read sequence for LED0
COMPARE s0, 00
JUMP Z, test_LED0_start
SUB s0, 20 ;Count longer to ensure end stops then reset count if maximum
JUMP Z, update_LED0
ADD s0, 20
inc_LED0: ADD s0, 01 ;increment counter
JUMP update_LED0
test_LED0_start: FETCH s1, LED1_sequence ;start LED0 if LED1 = 4
COMPARE s1, 04
JUMP Z, inc_LED0
update_LED0: STORE s0, LED0_sequence
CALL LED_to_duty
STORE s1, PWM_channel0
;
FETCH s1, LED0_sequence ; refresh LED1 if LED0 = 11 (0B hex) to reflect wave
COMPARE s1, 0B
JUMP NZ, normal_LED1
LOAD s0, 04
JUMP update_LED1
normal_LED1: FETCH s0, LED1_sequence ;read sequence for LED1
COMPARE s0, 00
JUMP Z, test_LED1_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED1
ADD s0, 10
inc_LED1: ADD s0, 01 ;increment counter
JUMP update_LED1
test_LED1_start: FETCH s1, LED0_sequence ;start LED1 if LED0 = 11 (0B hex) to reflect wave
COMPARE s1, 0B
JUMP Z, inc_LED1
FETCH s1, LED2_sequence ;start LED1 if LED2 = 4
COMPARE s1, 04
JUMP Z, inc_LED1
update_LED1: STORE s0, LED1_sequence
CALL LED_to_duty
STORE s1, PWM_channel1
;
FETCH s0, LED2_sequence ;read sequence for LED2
COMPARE s0, 00
JUMP Z, test_LED2_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED2
ADD s0, 10
inc_LED2: ADD s0, 01 ;increment counter
JUMP update_LED2
test_LED2_start: FETCH s1, LED1_sequence ;start LED2 if LED1 = 4
COMPARE s1, 04
JUMP Z, inc_LED2
FETCH s1, LED3_sequence ;start LED2 if LED3 = 4
COMPARE s1, 04
JUMP Z, inc_LED2
update_LED2: STORE s0, LED2_sequence
CALL LED_to_duty
STORE s1, PWM_channel2
;
;
FETCH s0, LED3_sequence ;read sequence for LED3
COMPARE s0, 00
JUMP Z, test_LED3_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED3
ADD s0, 10
inc_LED3: ADD s0, 01 ;increment counter
JUMP update_LED3
test_LED3_start: FETCH s1, LED2_sequence ;start LED3 if LED2 = 4
COMPARE s1, 04
JUMP Z, inc_LED3
FETCH s1, LED4_sequence ;start LED3 if LED4 = 4
COMPARE s1, 04
JUMP Z, inc_LED3
update_LED3: STORE s0, LED3_sequence
CALL LED_to_duty
STORE s1, PWM_channel3
;
FETCH s0, LED4_sequence ;read sequence for LED4
COMPARE s0, 00
JUMP Z, test_LED4_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED4
ADD s0, 10
inc_LED4: ADD s0, 01 ;increment counter
JUMP update_LED4
test_LED4_start: FETCH s1, LED3_sequence ;start LED4 if LED3 = 4
COMPARE s1, 04
JUMP Z, inc_LED4
FETCH s1, LED5_sequence ;start LED4 if LED5 = 4
COMPARE s1, 04
JUMP Z, inc_LED4
update_LED4: STORE s0, LED4_sequence
CALL LED_to_duty
STORE s1, PWM_channel4
;
FETCH s0, LED5_sequence ;read sequence for LED5
COMPARE s0, 00
JUMP Z, test_LED5_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED5
ADD s0, 10
inc_LED5: ADD s0, 01 ;increment counter
JUMP update_LED5
test_LED5_start: FETCH s1, LED4_sequence ;start LED5 if LED4 = 4
COMPARE s1, 04
JUMP Z, inc_LED5
FETCH s1, LED6_sequence ;start LED5 if LED6 = 4
COMPARE s1, 04
JUMP Z, inc_LED5
update_LED5: STORE s0, LED5_sequence
CALL LED_to_duty
STORE s1, PWM_channel5
;
FETCH s1, LED7_sequence ; refresh LED6 if LED7 = 11 (0B hex) to reflect wave
COMPARE s1, 0B
JUMP NZ, normal_LED6
LOAD s0, 04
JUMP update_LED6
normal_LED6: FETCH s0, LED6_sequence ;read sequence for LED6
COMPARE s0, 00
JUMP Z, test_LED6_start
SUB s0, 10 ;reset count if maximum
JUMP Z, update_LED6
ADD s0, 10
inc_LED6: ADD s0, 01 ;increment counter
JUMP update_LED6
test_LED6_start: FETCH s1, LED5_sequence ;start LED6 if LED5 = 4
COMPARE s1, 04
JUMP Z, inc_LED6
update_LED6: STORE s0, LED6_sequence
CALL LED_to_duty
STORE s1, PWM_channel6
;
FETCH s0, LED7_sequence ;read sequence for LED7
COMPARE s0, 00
JUMP Z, test_LED7_start
SUB s0, 20 ;Count longer to ensure end stops then reset count if maximum
JUMP Z, update_LED7
ADD s0, 20
inc_LED7: ADD s0, 01 ;increment counter
JUMP update_LED7
test_LED7_start: FETCH s1, LED6_sequence ;start LED7 if LED6 = 4
COMPARE s1, 04
JUMP Z, inc_LED7
update_LED7: STORE s0, LED7_sequence
CALL LED_to_duty
STORE s1, PWM_channel7
JUMP warm_start
;
;
; Convert LED sequence number into PWM intensity figure
;
; LEDs duty cycle values are 0,1,2,4,8,16,32 and 64 because they appear to give what
; appears to be a fairly liner change in intensity and provides a simple way to set
; the duty value.
;
; Provide sequence value in register s0 and intensity will be
; returned in register s1.
;
; s0 s1
; 00 00
; 01 01
; 02 02
; 03 04
; 04 08
; 05 10
; 06 20
; 07 40
; 08 80
; 09 40
; 0A 20
; 0B 10
; 0C 08
; 0D 04
; 0E 02
; 0F 01
; 10 00 and zero for all larger values of s0
;
LED_to_duty: LOAD s1, 00
COMPARE s0, 00 ;test for zero
RETURN Z
LOAD s1, 01 ;inject '1'
go_up_loop: SUB s0, 01
RETURN Z
SL0 s1 ;multiply by 2
JUMP C, go_down
JUMP go_up_loop
go_down: LOAD s1, 40
go_down_loop: SUB s0, 01
RETURN Z
SR0 s1 ;divide by 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -