Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
; 45 code words, 16 Flash data words (table);----------------------------------------------------------------------------------------------------------------
; CPU registers and constants
;
.nolist
.include "8535def.inc"
.list
;----------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------
; Useful equates
;
.equ a = 1 << PB0 ; 7-segment LED segment assignments:
.equ b = 1 << PB1 ;
.equ c = 1 << PB2 ; f
.equ d = 1 << PB3 ; e a
.equ e = 1 << PB4 ; g
.equ f = 1 << PB5 ; d b
.equ g = 1 << PB6 ; c
.equ h = 1 << PB7 ; Dummy segment to keep the unused PORTB.7 pin pulled up internally
.equ zero = a+b+c+d+e+f+h ; Seven-segment codes for 0..5, 7 digits (others are not used),
.equ one = a+b+h ; bit 7 set to 1 to keep the unused PORTB.7 pin pulled up internally
.equ two = a+c+d+f+g+h ;
.equ three = a+b+c+f+g+h ;
.equ four = a+b+e+g+h ;
.equ five = b+c+e+f+g+h ;
.equ seven = a+b+f+h ;
.equ xtal = 8000 ; XTAL frequency, KHz
.equ rate = 100 ; Sesnor polling rate, Hz (you may practically set 10 <= rate <= 10000)
.equ ndelay = (xtal*1000)/(3*5*rate); Calculated delay constant for delay routine (3=digits, 5=cycles)
;----------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------
; Code segment start
;
.cseg
;----------------------------------------------------------------------------------------------------------------
; Inits
;
reset:
ldi zl,low(RAMEND) ; Stack pointer setup
out SPL,zl ;
ldi zl,high(RAMEND) ;
out SPH,zl ;
ldi zl,0 ; PORTA0..7 = inputs
out DDRA,zl ;
out DDRD,zl ; PORTD0..7 = inputs (unused)
ldi zl,0xFF ;
out PORTD,zl ; PORTD (unused) pullup resistors ON
ldi zl,0x7F ; PORTB0..6 = outputs
out DDRB,zl ;
ldi zl,3 ; PORTC0..1 = outputs
out DDRC,zl ;
;----------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------
; Main program loop
;
main:
in zl,PINA ; zl.0123 = sensor1, zl.4567 = sensor2
mov zh,zl ; Copy to zh
andi zl,0x0F ; Cut off unused 4 MSbits, zl = sensor1
swap zh ; zh.0123 = sensor2, zh.4567 = sensor1
andi zh,0x0F ; Cut off unused 4 MSbits, zh = sensor2
ldi r16,one ; Prefetch "1" to display as a higher value sensor #
cp zl,zh ; Compare sensor values
brsh display ; Go display "1" and sensor1 value if sensor1 >= sensor2
ldi r16,two ; Prefetch "2" to display as a higher value sensor #
mov zl,zh ; Go display "2" and sensor2 value if sensor1 < sensor2
display:
ldi r17,0xFC ; Set a mux addr register to 00 (ind1), pull up unused PORTC.2..7 pins
mov r0,r16 ; Copy r16 to r0 for a display subroutine
rcall disp1 ; Display a higher value sensor #
ldi zh,high(segtab*2) ; Load a 7-segment coded display table index MSB to a Z pointer
lsl zl ; Multiply a table index by 2 (2 bytes per table entry)
subi zl,-low(segtab*2) ; Calculate a table offset LSB (zl already contains a sensor value*2)
rcall disp ; Display a tens digit of a higher value sensor
inc zl ; Advance a table pointer to a units digit
rcall disp ; Display a units digit of a higher value sensor
rjmp main ; Repeat the main loop forever
;----------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------
; Displays a 7-segment coded digit from a Flash table pointed by a Z register on an indicator selected by r17.0,1
;
disp:
lpm ; Get a 7-segment code of units digit
inc r17 ; Set a mux address register for a next indicator
disp1: ; External entry point to display a leftmost digit
out PORTC,r17 ; Set a mux address on PORTC.0,1
out PORTB,r0 ; Display a units digit of a higher value sensor
ldi xl,low(ndelay) ; Load a 16-bit countdown delay constant to xh:xl
ldi xh,high(ndelay) ;
delcyc: ; Keep displaying a digit for a number of microseconds defined in delmks
sbiw xl,1 ; Decrement an X register pair
nop ; Insert NOP to make a single delay iteration equal to 5 CPU cycles
brne delcyc ; Keep decrementing X to zero
ldi xl,0x80 ; Turn the digit display off to prevent flikker,
out PORTB,xl ; pull up the unused PORTB.7 pin
ret
;----------------------------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------------------------
; 7-segment codes for 0..15 sensor values scaled to mCd
;
segtab:
.db zero,zero ; 0 = 00 mCd
.db zero,three ; 1 = 03 mCd
.db zero,seven ; 2 = 07 mCd
.db one,zero ; 3 = 10 mCd
.db one,three ; 4 = 13 mCd
.db one,seven ; 5 = 17 mCd
.db two,zero ; 6 = 20 mCd
.db two,three ; 7 = 23 mCd
.db two,seven ; 8 = 27 mCd
.db three,zero ; 9 = 30 mCd
.db three,three ; 10 = 33 mCd
.db three,seven ; 11 = 37 mCd
.db four,zero ; 12 = 40 mCd
.db four,three ; 13 = 43 mCd
.db four,seven ; 14 = 47 mCd
.db five,zero ; 15 = 50 mCd
;----------------------------------------------------------------------------------------------------------------
.exit