Группа: Новичок
Сообщений: 1
Регистрация: 31-03-06
Пользователь №: 15 665

|
несколько дней уже пытаюсь переделать прошивку в .hex никак не получается очень срочно надо. помогите пожалуйста. частота кварца 4 мгц
;********************************* ; 7 Segment LED Display millivoltmeter ;*********************************
.include "2313def.inc"
;***** 16 bit binary-to-packed-BDC Subroutine Register Variables
.equ AtBCD0 =13 ;address of tBCD0 .equ AtBCD2 =15 ;address of tBCD1
.def tBCD0 =r13 ;BCD value digits 1 and 0 .def tBCD1 =r14 ;BCD value digits 3 and 2 .def tBCD2 =r15 ;BCD value digit 4
.def fbinL =r16 ;binary value Low byte .def fbinH =r17 ;binary value High byte .def cnt16a =r18 ;loop counter .def tmp16a =r19 ;temporary value
;*****other register assignments************
.def segmentvalue = r0 .equ digit1 = $01 ;store of first digit's binary value .def digit1val = r1 ;storage of first digit's 7 segment image .equ digit2 = $02 ;storage of second digit's binary value .def digit2val = r2 ;storage of second digit's 7 segment image .equ digit3 =$03 ;storage of third ditit's binary value .def digit3val = r3 ;storage of thrid digit's 7 segment image .def offsetl = r4 ;offsete to zero reading, low byte .def offseth =r5 ;offset to zero reading, high byte .def flagreg = r6 ;bit 0 true enables measurement during interrupt .def intcountl = r7 ;24 bit timer for power management .def intcountm =r8 ;count low, middle, and high bytes .def intcounth = r9 .def dimflag = r10 ;if not zero, then dim the display .def rezeroedflag = r11 ;nonzero if rezero has occured .def temp = r20 ;general purpose variabl .def digitvalue = r21 ;value of current digit .def digitpointer = r22 ;pointer to digit to be written .def interruptcount = r23 ;keeps track of which task to execute next .def slowdownmeasurements =r24 ;counter to cause less frequent measurements ;when I set this up at +5V and when operating from a 3V battery .equ dimtime = $708 ;dim time 30 mintues .equ sleeptime =$E10 ;shut down time at 60 minutes
.ORG $0000 rjmp start .ORG $0006 rjmp timerservice
start: ldi temp,RAMEND ;Init Stack Pointer out SPL,temp
ldi temp,$00 ;clear measurement during interrupt enable flag mov flagreg,temp
ldi temp,$FF ;segment drivers out DDRD,temp ldi temp,$FC ;digit drivers and power to the external circuit out DDRB,temp ldi temp,$3C ;digit drivers and power to the external circuit out PORTB,temp
ldi temp, $00 ;set up comparitor out ACSR, temp ldi temp,$FF mov dimflag,temp ;set interrupt counter to zero clr intcountl clr intcountm clr intcounth
clr rezeroedflag
ldi temp, $03 ; use temp to initaize prescaler 03 out TCCR0, temp ldi temp,$00 ; use temp to initialize counter out TCNT0,temp ldi temp, $02 ; use temp to initialize TIMSK out TIMSK,temp ldi temp,$FF ;clear measurement during interrupt enable flag mov flagreg,temp sei ;ENABLE THE TIMER INTERRUPTS
loop: ;check to see if its time to dim the display
ldi temp,dimtime ;skip dimming if intcountm is >< dimtime eor temp,intcountm brne dontdim clr dimflag ;make register $FF if its time. com dimflag dontdim:
;check if its past time to sleep the machine
ldi temp,sleeptime ;skip sleeping if intcountm is >< sleep eor temp,intcountm brne dontsleep ;routine to sleep the machine
cli ;disble all interrupts
clr temp out TCCR1b,temp ;stop timer 1 out TCCR0,temp ;stop timer 0 ldi temp,$18 ;make sure watch dog timer is disabled out wdtcr,temp ldi temp,$10 out wdtcr,temp cbi ACSR,$07 ;turn off comparitor ; clr temp ;make I/O pins inputs out DDRB,temp out DDRD,temp ldi temp, $30 out MCUCR,temp ; set MCUCR bit 4 to set power down mode for sleep and ; set MCUCR bit 5 to enable sleep sleep ; enter sleep. Reset to wake up. dontsleep:
;Set up rezeroing of A-to-D after running some short time. ;rezeroiong only happens once and is done in the A-to-D routine inside ;the T0 interrupt. tst rezeroedflag brne dontrezero ldi temp,$02 eor temp,intcountm brne dontrezero ldi temp,$5A mov rezeroedflag,temp ;$5A is the secret word to cause rezeroing
dontrezero:
rjmp loop
;**** A P P L I C A T I O N N O T E A V R 2 0 4 ************************ ;* Title: BCD Arithmetics ;* Version: 1.1 ;* Last updated: 97.07.04 ;* Target: AT90Sxxxx (All AVR Devices) ;* ;* Support E-mail: avr@atmel.com ;*
;* DESCRIPTION ;* This Application Note lists subroutines for the following Binary Coded ;* Decimal arithmetic applications: ;* ;* Binary 16 to BCD Conversion (special considerations for AT90Sxx0x)
;***** Code
bin2BCD16: ldi cnt16a,16 ;Init loop counter clr tBCD2 ;clear result (3 bytes) clr tBCD1 clr tBCD0 clr ZH ;clear ZH (not needed for AT90Sxx0x) bBCDx_1:lsl fbinL ;shift input value rol fbinH ;through all bytes rol tBCD0 ; rol tBCD1 rol tBCD2 dec cnt16a ;decrement loop counter brne bBCDx_2 ;if counter not zero ret ; return
bBCDx_2:ldi r30,AtBCD2+1 ;Z points to result MSB + 1 bBCDx_3: ld tmp16a,-Z ;get (Z) with pre-decrement ;---------------------------------------------------------------- ;For AT90Sxx0x, substitute the above line with: ; ; dec ZL ; ld tmp16a,Z ; ;---------------------------------------------------------------- subi tmp16a,-$03 ;add 0x03 sbrc tmp16a,3 ;if bit 3 not clear st Z,tmp16a ; store back ld tmp16a,Z ;get (Z) subi tmp16a,-$30 ;add 0x30 sbrc tmp16a,7 ;if bit 7 not clear st Z,tmp16a ; store back cpi ZL,AtBCD0 ;done all three? brne bBCDx_3 ;loop again if not rjmp bBCDx_1
putsegments: ; Enter with value (0..9) in digitvalue, ; and destingation digit in digitpointer ldi ZH,high(2*ledlut) ; Load high part of byte address into ZH ldi ZL,low(2*ledlut) ; Load low part of byte address into ZL add ZL,digitvalue ; Add index (which is digitvalue) to LUT address ldi temp,$00 adc ZH,temp lpm ; Load byte from program memory into r0 mov ZL,digitpointer ;Point Z register to the desination memroy location ldi ZH,$00 st Z,r0 ;move contets of r0 to location pointed to by digitpointer ret
dimifnecessary: ;check if its past time to start dimming
tst dimflag breq donedim dimit: ;routine to dim the display
dimmingtime: ;leave the chars on some some ldi fbinL,$00 ldi fbinH,$03 dimmingtimeloop: dec fbinL cpi fbinL,$00 brne dimmingtimeloop dec fbinH cpi fbinH,$00 brne dimmingtimeloop ;now that thime's up, blank display to dim. cbi PORTB,2 ;blank all digits cbi PORTB,3 cbi PORTB,4
donedim: ret
;************************
timerservice: ;service timer interrupt
;round-robin multitasking, different task on each interrupt ;Display digit1 ;display digit2 ;display digit3 ;acquire new ADC value and put in digit registers push temp push xl push xh lds temp,$5F ;push status register onto stack push temp push fbinL push fbinH ldi temp,$01 ;keep timer for dimming and shut down add intcountl,temp clr temp adc intcountm,temp adc intcounth,temp
inc interruptcount ;point to the next task andi interruptcount,$03 ;only four tasks allowed cbi PORTB,2 ;blank all digits cbi PORTB,3 ;by making all cathode drivers inputs cbi PORTB,4
;round-robin starts here cpi interruptcount,$00 breq showdigit1 cpi interruptcount,$01 breq showdigit2 cpi interruptcount,$02 breq showdigit3 cpi interruptcount,$03 breq AtoDConversion rjmp endoftimerservice ;go back and wait for another interrupt
showdigit1: out PORTD,digit1val ;copy digit value to output port sbi PORTB,4 ;enable this digit rcall dimifnecessary rjmp endoftimerservice
showdigit2: out PORTD,digit2val ;copy digit value to output port sbi PORTB,3 ;enable this digit rcall dimifnecessary rjmp endoftimerservice
showdigit3: out PORTD,digit3val ;copy digit value to output port sbi PORTB,2 ;enable this digit rcall dimifnecessary rjmp endoftimerservice
AtoDConversion: ;convert input voltage to a value, set flag for foreground routine to convert to BCD and store in digit memories sbrs flagreg,$01 ;if flag not set, don't do conversions jrelay: rjmp finishedconverison
inc slowdownmeasurements cpi slowdownmeasurements,$08 brne jrelay ;don't do it, didn't wait long enough clr slowdownmeasurements ;set counter to zero for next time
;set PORTB bit 0 to 0 to assure no current out of pins cbi PORTB,0
;set DDRB, bit 0 an output. This discharges the capacitor on the I/O pin. sbi DDRB,0
ldi fbinL,$00 ldi fbinH,$08 turnondelay: dec fbinL cpi fbinL,$00 brne turnondelay ;set DDRB bit 0 to input cbi DDRB,$00
ldi xh,$00 ldi xl,$00 waitforramp: sbiw xh:xl,1 in temp,acsr sbis acsr,aco ;branch back to waiting if comparitor not tripped rjmp waitforramp ;Zero ADC by measuring offset. Only happens once. ; after running about a ldi temp,$5A eor temp,rezeroedflag brne dontrezeroagain mov offsetl,xl mov offseth,xh ldi temp,$FF mov rezeroedflag,temp clr dimflag dontrezeroagain: sub xl,offsetl ;subtract offset to zero reference reading sbc xh,offseth brpl positivenumber ldi xh,0 ;if we'r here, its negative, so set to zero; ldi xl,0 ;negative field strength doesn't make any sense in the real world positivenumber: ;now we have the number, we just need to convert it.
; Check for overflow mov temp,xh andi temp,$0F subi temp,$03 brpl overflow brne defintelynotoverflow mov temp,xl subi temp,$E7 brpl overflow defintelynotoverflow: mov fbinL,xl ;move counter contents to input for number conversion mov fbinH,xh rcall bin2BCD16 ;Convert to 2.5-byte packed BCD format ;result: tBCD2:tBCD1:tBCD0 = $054321
mov digitvalue,tBCD0 ; now send it to the LED display andi digitvalue,$0F ldi digitpointer,$01 rcall putsegments
mov digitvalue,tBCD0 lsr digitvalue lsr digitvalue lsr digitvalue lsr digitvalue ldi digitpointer,$02 rcall putsegments
mov digitvalue,tBCD1 andi digitvalue,$0F ldi digitpointer,$03 rcall putsegments rjmp finishedconverison overflow: ;set display for overflow indication ldi digitvalue,$0A ldi digitpointer,$01 rcall putsegments
ldi digitvalue,$0A ldi digitpointer,$02 rcall putsegments
ldi digitvalue,$0A ldi digitpointer,$03 rcall putsegments finishedconverison:
endoftimerservice: pop fbinH pop fbinL pop temp sts $5F,temp ;restore status register pop xh pop xl pop temp
reti
ledlut: ;LED Look-Up Table, Segent codes for 0..9 on 7 segment display .db $3F,$06,$5B,$4F,$66,$6D,$7d,$07,$7F,$6F,$09,$08
Сообщение отредактировал sergun - Mar 31 2006, 12:27
|