📄 wlc.asm
字号:
;; wait 20 ms MOV.W #radio_spin_time, R9
radio_spin:
DEC.W R9
JNZ radio_spin
;; get the temperature
MOV.W #RNGAUTO+CSOFF+12+VREF+CS, &ACTL
NOP NOP NOP NOP NOP NOP
;; spin until conversion finishes
waiting4:
BIT.B #ADIFG, &IFG2
JZ waiting4
;; Reset the flag to zero so it can trip next time
BIC.B #ADIFG, &IFG2
MOV &ADAT, temperature
; send the packet, protected with a checksum MOV.B #0, checksum
MOV.B #'U', R8
call #tx_byte
MOV.B #'U', R8
call #tx_byte
MOV.B #'U', R8
call #tx_byte
MOV.B #'U', R8
call #tx_byte
MOV.B #magic_1, R8
ADD.B R8, Checksum
call #tx_byte
MOV.B #magic_2, R8
ADD.B R8, Checksum
call #tx_byte
MOV.W vehicle_count, R9
SWPB R9
MOV.B R9, R8
ADD.B R8, checksum
call #tx_byte
SWPB R9
MOV.B R9, R8
ADD.B R8, checksum
call #tx_byte
MOV.W temperature, R9
SWPB R9
MOV.B R9, R8
ADD.B R8, checksum
call #tx_byte
SWPB R9
MOV.B R9, R8
ADD.B R8, checksum
call #tx_byte
MOV.W baseline, R9
SWPB R9
MOV.B R9, R8
ADD.B R8, Checksum
call #tx_byte
SWPB R9
MOV.B R9, R8
ADD.B R8, checksum
call #tx_byte
MOV.B checksum, R8
call #tx_byte
; power down radio and temp sensor
MOV.B #RADIO_POWER, &TPD
; done
JMP finished
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; Transmit byte function (tx_byte); * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *; This function assumes that the DATA_OUT pin is already in the idle line (high) ; state as an output, and that the transmitter is already powered up and the; transmitting frequency is selected.; It takes the byte in R8 and transmits it at 38.4 kb/s using NRZ serial.
tx_byte:
PUSH.W R8
PUSH.W R9
PUSH.W R10
; Initialize the bit counter MOV.B #8, R10
; Send start bit
BIC.B #DATA, &TPD
MOV.B #5,R9
wait12:
DEC.B R9
JNZ wait12
NOP
NOP
NOP
; Send the data, MSB first
next_bit:
RRC.B R8
JC bit_high
bit_low:
BIC.B #DATA, &TPD
NOP JMP bit_count
bit_high: BIS.B #DATA, &TPD NOP NOP NOP
bit_count:
MOV.B #4,R9
wait13: DEC.B R9
JNZ wait13
DEC.B R10
JNZ next_bit
; Send the (high) stop bit
NOP NOP NOP BIS.B #DATA, &TPD
MOV.B #6,R9
wait14:DEC.B R9
JNZ wait14
NOP
POP.W R10
POP.W R9
POP.W R8
RET
; Memory Allocation
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; Vechicle Detector; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;; This routine handles all the details of counting vehicles.
;; It takes an ADC value in R9. It keeps track of the current
;; count in the vehicle_count variable. External software can zero or
;; read this variable as required.
vehicle_detector:
;; check to see if we are taking an initial baseline
CMP.W #0, baseline_counter
JNZ integrate_baseline
;; adjust the baseline call #adjust_baseline
;; compute trigger points
MOV.W baseline, trigger_upper
ADD.W #upper_trigger_offset, trigger_upper
MOV.W baseline, trigger_lower
SUB.W #lower_trigger_offset, trigger_lower
MOV.W baseline, noise_upper
ADD.W #upper_noise_offset, noise_upper
MOV.W baseline, noise_lower
SUB.W #lower_noise_offset, noise_lower
;; This implements a two-sided baseline deviation trigger with hysteresis.;; Passing one trigger threshold followed by the other causes reset
CMP.W R9, trigger_upper ; is trigger_set_upper < adc_value?
JL upper_zone
CMP.W trigger_lower, R9 ; is adc_value < trigger_set_lower?
JL lower_zone
CMP.W R9, noise_upper ; outside noise band?
JL dead_zone
CMP.W noise_lower, R9 JL dead_zone
CMP.B #not_triggered, trigger_state ; if inside the noise band, check state
JEQ done
DEC.W zerocount ; if triggered, run a timeout clock
JZ timeout_expired
done: RET
dead_zone:
MOV.W #zero_timeout, zerocount
JMP done
timeout_expired: MOV.B #not_triggered, trigger_state ; time has expired --- no car --- reset state to untriggered
MOV.W #zero_timeout, zerocount
JMP done
lower_zone:
MOV.W #zero_timeout, zerocount
CMP.B #not_triggered, trigger_state ; we're in the lower zone: check state to see what to do
JEQ prime_lower_zone
CMP.B #triggered_on_rise, trigger_state
JEQ prime_lower_zone
CMP.B #waiting_for_dip, trigger_state
JEQ count_lower_zone
JMP done
prime_lower_zone:
MOV.B #waiting_for_rise, trigger_state
JMP done
count_lower_zone: MOV.B #triggered_on_dip, trigger_state
INC.W vehicle_count
JMP done
upper_zone: MOV.W #zero_timeout, zerocount
CMP.B #not_triggered, trigger_state ; we're in the lower zone: check state to see what to do
JEQ prime_upper_zone
CMP.B #triggered_on_dip, trigger_state
JEQ prime_upper_zone
CMP.B #waiting_for_rise, trigger_state
JEQ count_upper_zone
JMP done
prime_upper_zone:
MOV.B #waiting_for_dip, trigger_state
JMP done
count_upper_zone:
MOV.B #triggered_on_rise, trigger_state
INC.W vehicle_count
JMP done
integrate_baseline: RRA.W baseline ; this is a simple smearing filter: baseline = (baseline + sample) / 2
RRA.W R9
ADD.W R9, baseline
DEC.W baseline_counter
JMP done
; adusts the baseline based on state, so that it never gets too far off due to temp shiftsadjust_baseline:
CMP.B #not_triggered, trigger_state
JEQ fast_adjust
slow_adjust:
CMP.W R9, baseline ; is baseline < adc_value?
JL slow_adjust_less
slow_adjust_ge:
SUB.W #2, baseline_acc
JMP adjust
slow_adjust_less:
ADD.W #2, baseline_acc
JMP adjust
fast_adjust:
CMP.W R9, baseline ; is baseline < adc_value?
JL fast_adjust_less
fast_adjust_ge:
SUB.W #20, baseline_acc
JMP adjust
fast_adjust_less: ADD.W #20, baseline_acc
adjust: CMP.W #1000, baseline_acc ; is baseline_acc < 1000
JL adjust_less
CMP.W #3000, baseline_acc, ; is baseline_acc > 3000
JGE adjust_greater
JMP done_adjust
adjust_greater:
INC.W baseline
MOV.W #2000, baseline_acc
JMP done_adjust
adjust_less:
DEC.W baseline
MOV.W #2000, baseline_acc
done_adjust: RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -