📄 stmd.asm
字号:
; -----001 ; 001 = no prescaler, internal clock
; -----100 ; 011 = 1:64 prescaler, internal clock
; -----100 ; 110 = 1:256 prescaler, internal clock
; -----101 ; 111 = 1:1024 prescaler, internal clock
sts TCCR2B, temp1
clr temp1 ; clear some registers
sts TCNT2, temp1
sts OCR2A, temp1
sts OCR2B, temp1
; 8Mhz clock -> 125 ns instruction cycle
; 8 bit counter, 2^8 x 125 ns = 32 us
; with 1:1014 prescaler: 1024 x 32 us = 32.768 ms per rollover
; for 3 s delay: 3 s / 32.768 ms = 91.55 rollovers per 3 s
; -- calculate error for 92 rollovers: 92 * 32.768 ms = 3.015 s
.equ tim2_idlerolls_target = 92
ldi tim2_idlerolls, 0
; enable/disable timer/counter2 interrupts
ldi temp1, 0b00000001
; xxxxx--- ; reserved
; -----0-- ; 0 = timer/counter2 Output Compare B Match interrupt disabled
; ------0- ; 0 = timer/counter2 Output Compare A Match interrupt disabled
; -------0 ; 0 = timer/counter2 Overflow interrupt disabled
sts TIMSK2, temp1
; ************************************************************************
; configure external interrupts
ldi temp1, 0b00000010
; xxxx---- ; reserved
; ----00-- ; 00 = low level on INT1 generates interrupt request
; ------10 ; 10 = falling edge on INT0 generates interrupt request
sts EICRA, temp1
ldi temp1, 0b00000000
; xxxxxx-- ; reserved
; ------0- ; 0 = INT1 disabled
; -------0 ; 0 = INT0 disabled
out EIMSK, temp1
; ************************************************************************
; configure watchdog timer
wdr ; hit the dog
lds temp1, WDTCSR ; start timed sequence to set up WDTCSR
ori temp1, (1<<WDCE) | (1<<WDE)
sts WDTCSR, temp1
ldi temp1, 0b01000000
; 0------- ; 0 = watchdog interrupt flag clear (WDIF)
; -1------ ; 1 = watchdog interrupt enabled (WDIE)
; --0--000 ; 0--000 = 16 ms timeout (watchdog prescaler bits)
; --1--001 ; 1--001 = 8 sec timeout (watchdog prescaler bits)
; ---0---- ; watchdog change enable (WDCE)
; ----0--- ; 0 = Watchdog system reset disabled (WDE)
sts WDTCSR, temp1
; ************************************************************************
; initialize mode of stepping based on DIP switches
in temp1, PINC
andi temp1, 0b00000111 ; mask off the bits that don't pertain to stepping mode
cpi temp1, 0b111 ; full-step mode with both phases on?
brne next1
rcall init_full_both
next1:
cpi temp1, 0b110 ; full-step mode with one phase on?
brne next2
rcall init_full_wave
next2:
cpi temp1, 0b101 ; half-step mode?
brne next3
rcall init_half
next3:
cpi temp1, 0b100 ; quarter step mode?
brne next4
rcall init_quarter
next4:
cpi temp1, 0b011 ; sixth step mode?
brne next5
rcall init_sixth
next5:
cpi temp1, 0b010 ; eighth step mode?
brne next6
rcall init_eighth
next6:
cpi temp1, 0b001 ; tenth step mode?
brne next7
rcall init_tenth
next7:
cpi temp1, 0b000 ; twelfth or sixteenth step mode?
brne next8
rcall init_twelfth
; rcall init_sixteenth
next8:
sei ; enable interrupts after everything is configured
; ************************************************************************
Loop: ; loop here forever waiting for step interruputs
wdr
rcall enable_check ; drive enabled?
wdr ; hit the dog
rcall LED_check ; time to toggle LED?
wdr ; hit the dog
rcall test_mode_check ; test mode?
wdr ; hit the dog
rcall idle_cur_red_check ; check to see if idle current reduction should be turned on
rjmp Loop
; ************************************************************************
; ***** Subroutines ******************************************************
; ************************************************************************
; ************************************************************************
LED_check: ; check timer/counter0 rollovers to see if we should toggle the LED
cpi tim0_LEDrolls, tim0_LEDrolls_target
brsh toggle_led
ret
toggle_led:
sbi pind, alive_LED ; toggle the pin
clr tim0_LEDrolls ; reset rollover counter
ret
; ************************************************************************
enable_check: ; check to see if the drive is enabled *******************
; PD4 is the enable input from opto-isolator. It is pulled high through 270R when disabled
; and goes low when 5v is applied to input of opto-isolator to enable the drive
; If drive is disabled, we want to disable external INT0.
; PC3 is an input with internal pullup enabled, DIP switch to gnd.
; When drive is disabled (PD4 high) and PC3 is low, we will let the motors freewheel
; by setting M pins low (PortB) and brake pin(s) (PD6) low.
; When drive is disabled (PD4 high) and PC3 is high, we will enable motor braking
; by taking brake pin(s) PD6 high.
sbic PIND, enable_in ; drive enabled?
rjmp drive_disabled
drive_enabled:
cbi PORTD, brake_out ; braking off
sbi EIMSK, INT0 ; enable step interrupts
ret
drive_disabled:
cbi EIMSK, INT0 ; disable step interrupts
sbis PINC, brake_in ;
rjmp brake_on
freewheel:
clr temp1
out PORTB, temp1 ; M pins all low so motor can freewheel
cbi PORTD, brake_out ; braking off
ret
brake_on:
sbi PORTD, brake_out ; braking on
ret
; ************************************************************************
test_mode_check: ; is test mode active? Rotate motor, if yes
sbic PINC, test_in ; if it's clear, DIP switch is on so test mode is active
rjmp test_disabled
ldi temp1, 0b00000010 ; enable interrupt to periodically fire step signal
; --0----- ; 0 = input capture interrupt disabled
; xx-xx--- ; reserved
; -----0-- ; 0 = timer/counter2 Output Compare B Match interrupt disabled
; ------0- ; 0 = timer/counter2 Output Compare A Match interrupt disabled
; -------0 ; 0 = timer/counter2 Overflow interrupt disabled
sts TIMSK1, temp1
ret
test_disabled:
ldi temp1, 0b00000000 ; disable interrupt
; --0----- ; 0 = input capture interrupt disabled
; xx-xx--- ; reserved
; -----0-- ; 0 = timer/counter2 Output Compare B Match interrupt disabled
; ------0- ; 0 = timer/counter2 Output Compare A Match interrupt disabled
; -------0 ; 0 = timer/counter2 Overflow interrupt disabled
sts TIMSK1, temp1
ret
; ************************************************************************
idle_cur_red_check: ; is it time to reduce idle current?
cpi tim2_idlerolls, tim2_idlerolls_target
brsh reduce_current
ret
reduce_current:
cli ; disable interrupts while we reduce current and stop timer2
cbi portd, idle_red_out
clr temp1 ; disable timer2 interrupts
sts TIMSK2, temp1
sei ; interrupts back on
ret
; ************************************************************************
fault_trap: ; trap and log faults to EEPROM
cli ; prevent new interrupts from getting us out of the trap
ldi temp1, EE_PTR ; EE_PTR contains the address of the next empty space in EEPROM
rcall EEPROM_read
in temp3, EEDR ; store a copy of the address of the next empty space in EEPROM
in temp1, EEDR ; address to write to
mov temp2, fault_code ; data to write
rcall EEPROM_write
inc temp3 ; calculate the new address of the next empty space in EEPROM
breq infinite ; test zero flag for rollover, meaning EEPROM is full
ldi temp1, EE_PTR ; address to write to
mov temp2, temp3 ; data to write
rcall EEPROM_write
infinite:
cbi portd, alive_LED ; on to indicate fault
rjmp infinite ; spin forever...
; ************************************************************************
EEPROM_read: ; read EEPROM
; Call: Address to read contained in temp1
sbic EECR, EEPE ; wait for completion of previous write
rjmp EEPROM_read
out EEARL, temp1 ; setup low address byte
ldi temp1, 0 ; setup high address byte...
out EEARH, temp1 ; ...always zero as there are only 255 bytes on M48
sbi EECR, EERE ; start the read by writing EERE
ldi temp1, 0
out EEARH, temp1 ; point back to location 0...
out EEARL, temp1 ; ...to minimize chance of corruption
ret
; ************************************************************************
EEPROM_write: ; write EEPROM
; Call: Address to write contained in temp1
; Data to write contained in temp2
sbic EECR, EEPE ; wait for completion of previous write
rjmp EEPROM_write
out EEARL, temp1 ; setup low address byte
ldi temp1, 0 ; setup high address byte...
out EEARH, temp1 ; ...always zero as there are only 255 bytes on M48
out EEDR, temp2 ; setup data register
sbi EECR, EEMPE ; set master write enable
sbi EECR, EEPE ; set write enable
ldi temp1, 0
out EEARH, temp1 ; point back to location 0...
out EEARL, temp1 ; ...to minimize chance of corruption
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -