123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- ; Àâòîð: shilow@ukr.net
- ; Äàòà: ìàé-èþíü 2012
- ; Íàçâàíèå: avm
- ; Âåðñèÿ: 1
- ; Èìÿ ôàéëà: avm.asm, avm.spl7, avm.lay
- ; Äëÿ AVR: ATtiny24A
- ; Òàêòîâàÿ ÷àñòîòà: 8MHz, âíóòðåííèé RC-ãåíåðàòîð
- ; Âûïîëíÿåìûå ôóíêöèè: Àâòîìîáèëüíûé âîëüòåìòð
- ; ñì. ReadMe.txt
- ; ñõåìà ïî "Âàðèàíò 5"
- ;******************************
- ; èíêëóäû
- .nolist
- .include "tn24Adef.inc"
- .list
- ;******************************
- ; îïðåäëåíèÿ
- .def job0 = r0
- .def job1 = r1
- .def job2 = r2
- ;.def job3 = r3
- .def LED1 = r4
- .def LED2 = r5
- .def LED3 = r6
- .def LED4 = r7
- .def msrL = r14
- .def msrH = r15
- .def temp = r16 ; ðàáî÷àÿ ïåðåìåííàÿ
- .def tmp1 = r17
- .def cnt1 = r18
- .def cnt2 = r19
- .def LEDN = r20
- .def msek5 = r24 ; 5-òè ìñåê èíòåðâàëû
- .def flags = r25
- ;******************************
- ; êîíñòàíòû
- .equ AtBCD0 = 0 ;address of job0
- .equ AtBCD2 = 2 ;address of job2
- .equ AtLED1 = 4 ;address of LED1
- .equ MSEK100 = 7 ; 7bit of flags == 0.1 sek
- .equ NEED_DOT = 6 ; íóæíà òî÷êà
- .equ DISP_PORT = PORTA
- .equ DISP_DDR = DDRA
- .equ LA1 = 4
- .equ LA2 = 5
- .equ LA3 = 6
- .equ LA4 = 7
- .equ SER_PORT = PORTB
- .equ SER_DDR = DDRB
- .equ SCK = 0
- .equ DATA = 1
- .equ LOCK = 2
- .equ T1DIVL = 0x8F
- .equ T1DIVH = 0xFD ; 0x10000-8MHz/64/200Hz
- .equ VREF = 500 ; îïîðíîå íàïðÿæåíèå * 10 ìÂ
- .equ SPH = 0x3e
- .equ DOT_BIT = 5 ; bit5 -- òî÷êà
- ;******************************
- ; ìàêðîñû
- ; ñîõðàíÿåì â ñòåê SREG è R16
- .MACRO PUSHF
- PUSH R16
- IN R16,SREG
- PUSH R16
- .ENDM
- ; âîññòàíàâëèâàåì èç ñòåêà SREG è R16
- .MACRO POPF
- POP R16
- OUT SREG,R16
- POP R16
- .ENDM
- ;******************************
- ; ÿ÷åéêè â ÑÎÇÓ
- ;.DSEG
- ;.ORG SRAM_START
- ;Display: .byte 4 ; 4 áàéòà äëÿ èíäèêàòîðà
- ;******************************
- ; êîíñòàíòû â EEPROM
- ;.ESEG
- ;smpl1: .DW 0x0000 ; sample 1
- ;smpl2: .DB 0x05 ; sample 2
- ;******************************
- ; ïàìÿòü ïðîãðàìì
- .CSEG
- .ORG 0
- ;******************************
- ; Òàáëèöà âåêòîðîâ ïðåðûâàíèé
- rjmp RESET ; Reset Handler
- reti;jmp INT0 ; IRQ0 Handler
- reti;jmp PCINT0 ; PCINT0 Handler
- reti;jmp PCINT1 ; PCINT1 Handler
- reti;jmp WDT ; Watchdog Interrupt Handler
- reti;jmp TIM1_CAPT ; Timer1 Capture Handler
- reti;jmp TIM1_COMPA ; Timer1 Compare A Handler
- reti;jmp TIM1_COMPB ; Timer1 Compare B Handler
- rjmp TIM1_OVF ; Timer1 Overflow Handler
- reti;jmp TIM0_COMPA ; Timer0 Compare A Handler
- reti;jmp TIM0_COMPB ; Timer0 Compare B Handler
- reti;jmp TIM0_OVF ; Timer0 Overflow Handler
- reti;jmp ANA_COMP ; Analog Comparator Handler
- rjmp ADCC ; ADC Conversion Handler
- ; rjmp EE_RDY ; EEPROM Ready Handler
- ; rjmp USI_STR ; USI STart Handler
- ; rjmp USI_OVF ; USI Overflow Handler
- ;******************************
- ;;;;; Ïåðâè÷íàÿ èíèöèàëèçàöèÿ
- RESET: ldi temp,high(RAMEND); Main program start
- out SPH,temp
- ldi temp,low(RAMEND)
- out SPL,temp; Set Stack Pointer to top of RAM
- ; âûêë. àíàëîã, êîìïàðàòîð
- ldi temp,1<<ACD
- out ACSR,temp
- ; íàñòðîèì ÀÖÏ. îïîðà - Vcc, êàíàë 1, íåïðåðûâíîå ïðåîáðàçîâàíèå. temp=0b00100010
- ldi temp,1<<MUX0
- out ADMUX,temp
- ldi temp,(1<<ADEN)|(1<<ADSC)|(6<<ADPS0)
- out ADCSRA,temp
- ; timer1 - ÷àñòîòà 200 ãö, ïðè òàêòîâîé 8ÌÃö, ïðåñêàëåð=64, TCNT1L=0xñ0, TCNT1H=0x63
- ldi temp,(3<<CS10)
- out TCCR1B,temp
- ldi temp,T1DIVH
- out TCNT1H,temp
- ldi temp,T1DIVL
- out TCNT1L,temp ; çàïóñòèëè òàéìåð 1
- ; ðàçðåøàåì ïðåðûâàíèå îò òàéìåðà
- ldi temp,1<<TOIE1
- out TIMSK1,temp
- ; init
- ldi LEDN,0b11101111 ; ïåðâûé èíäèêàòîð
- ldi temp,(1<<LA1)|(1<<LA2)|(1<<LA3)|(1<<LA4)
- out DISP_DDR,temp
- out DISP_PORT,temp
- ldi temp,(1<<SCK)|(1<<DATA)|(1<<LOCK)
- out SER_DDR,temp
- ldi msek5,20
- clr YH
- ldi YL,AtLED1 ; çàãðóæàåì àäðåñ 1-ãî èíäèêàòîðà
- ldi temp,0x30
- mov LED1,temp
- mov LED2,temp
- mov LED3,temp
- mov LED4,temp
- ; Enable interrupts
- sei
- ;******************************
- ;;;;; Îñíîâíàÿ ïðîãðàììà
- BEGIN:
- sbrs flags,MSEK100 ; ïîðà ïðîèçâîäèòü èçìåðåíèÿ?
- rjmp MLBL1 ; íåò
- ;!! ADATE@ADCSRA==1, ïðè ADTS@ADCSRB==0 -- çàïóñê free running mode
- clr msrL
- clr msrH ; î÷èñòèëè õðàíèëèùå ðåçóëüòàòà
- ldi cnt2,16 ; çàãðóçèëè ñ÷¸ò÷èê èçìåðåíèé
- sbi ADCSRA,ADATE ; çàïóñê free running mode
- sbi ADCSRA,ADIE ; ðàçðåøàåì ïðåðûâàíèÿ îò ÀÖÏ
- sbi ADCSRA,ADSC ; çàïóñê íîâ. ïðåîáðàçîâàíèÿ
- ML1: rjmp PC+1 ; nop x 2 -- 1 world 2 takta
- tst cnt2 ; ãîíÿåì ïóñòîé öèêë ïîêà áóäóò ïðîèñõîäèòü 16 èçìåðåíèé
- brne ML1
- cbi ADCSRA,ADIE ; çàïðåùàåì ïðåðûâàíèÿ îò ÀÖÏ
- cbi ADCSRA,ADATE ; stop free running mode
- lsr msrH
- ror msrL
- lsr msrH
- ror msrL ; ïîäåëèëè ðåçóëüòàò íà 2^2
- ; òåïåðü ìíîæèì íà Vref è äåëèì íà 4096
- ldi temp,low(VREF)
- ldi tmp1,high(VREF)
- rcall MPY16U
- lsr job1 ; âûáðîñèëè job0 == ïîäåëèëè íà 256
- ror job0
- lsr job1
- ror job0
- ;; lsr job1
- ;; ror job0
- ;; lsr job1
- ;; ror job0 ; äîäåëèëè íà 16, èòîãî ïîäåëèëè íà 4096
- ; ldi cnt1,4
- ;ML2: lsr job2
- ; ror job1
- ; dec cnt1
- ; brne ML2
- mov msrL,job0
- mov msrH,job1 ; â MSR - íàïðÿæåíèå â 10ìÂ
- ;!!! óìíîæèòü íà âõîäíîé äåëèòåëü
- ;; -- íå äîäåëèëè íà 4 == óìíîæèëè òåïåðü íà 4.
- ;; â ðåàëå íóæíî áóäåò ìíîæèòü íàïðèìåð íà 400 è äåëèòü íà 100 -- ïîä ðåàëüíûé äåëèòåëü.
- ; òóò ìîæíî äîáàâèòü êîððåêöèþ óñèëåíèÿ.
- rcall bin2BCD16
- ; 4 çíà÷àùèõ öèôðû â job1:job0
- ldi XL,AtLED1
- clr XH
- mov temp,job1
- swap temp
- rcall OUT_NIBBL ; íèááë 3, äåñÿòêè
- mov temp,job1
- sbr flags,1<<NEED_DOT
- rcall OUT_NIBBL ; íèááë 2, åäèíèöû
- cbr flags,1<<NEED_DOT
- mov temp,job0
- swap temp
- rcall OUT_NIBBL ; íèááë 1, äåñÿòûå
- mov temp,job0
- rcall OUT_NIBBL ; íèááë 0, ñîòûå
- MLBL1:
- ;******************************
- ; äåëàòü íå÷åãî - ïîñïèì...
- ldi temp,1<<SE
- out MCUCR,temp ; ïðîñòîé ðåæèì ñíà
- sleep ; ñïèì.
- clr temp
- out MCUCR,temp ; ñî ñíà
- rjmp BEGIN
- ;******************************
- ;;;;; Ïîäïðîãðàììû
- ;******************************
- ; âûäà¸ò â ïîðò 8 áèò èç temp, ïîðòèò cnt1
- LEDOUT: ldi cnt1,8 ; ñ÷åò÷èê áèò
- LO1: cbi SER_PORT,SCK ; SCK=0
- lsl temp ; ñòàðøèé áèò â ïåðåíîñ
- brcc LO0 ; åñëè â ïåðåíîñå 0 — ïåðåéòè
- sbi SER_PORT,DATA ; âûäàëè 1
- rjmp LOE
- LO0: cbi SER_PORT,DATA ; âûäàëè 0
- LOE: sbi SER_PORT,SCK ; SCK=1, ñäâèã äàííûõ
- dec cnt1
- brne LO1
- ret
- ;******************************
- ;** ïåðåâîäèì ìëàäøèé íèááë temp â êîä äëÿ 7-ñãì èíä è êëàä¸ì åãî â îçó ïî àäð Y
- OUT_NIBBL:
- ldi ZL,low(LEDnd*2)
- ldi ZH,high(LEDnd*2); àäðåñ êîäîâ äëÿ èíäèêàòîðà
- andi temp,0x0F ; îòñåêàåì ñò íèááë. ïîëó÷àåì ñìåùåíèå
- add ZL,temp
- adc ZH,XH ; äîáàâèëè ñìåùåíèå
- lpm temp,Z ; ïðî÷èòàëè êîä
- sbrc flags,NEED_DOT ; íóæíà òî÷êà?
- cbr temp,1<<DOT_BIT ; âêëþ÷àåì òî÷êó
- st X+,temp ; çàïèñàëè êîä â ïîçèöèþ èíäèêàòîðà
- ret
- ;******************************
- ; ïåðåìíîæåíèå äâóõ 16-ðàçðÿäíûõ âåëè÷èí, ðåçóëüòàò 3 áàéòà, ðàáî÷àÿ
- ; ìíîæèìîå msrH:msrL, ìíîæèòåëü tmp1:temp, ðåçóëüòàò job2:job1:job0
- ; èñïîëüçóåò cnt1
- MPY16U: clr job2 ;clear 1 highest bytes of result
- ldi cnt1,16 ;init loop counter
- m16u_1: lsr tmp1
- ror temp
- brcc noad8 ;if bit 0 of multiplier set
- add job1,msrL ;add multiplicand Low to byte 1 of res
- adc job2,msrH ;add multiplicand high to byte 2 of res
- noad8: ror job2 ;shift right result byte 2
- ror job1 ;rotate right result byte 1
- ror job0 ;rotate result byte 0 and multiplier Low
- dec cnt1 ;decrement loop counter
- brne m16u_1 ;if not done, loop more
- ret
- ;******************************
- ;* This subroutine converts a 16-bit number (msrH:msrL) to a 5-digit
- ;* packed BCD number represented by 3 bytes (job2:job1:job0).
- ;* MSD of the 5-digit number is placed in the lowermost nibble of job2.
- bin2BCD16:
- ldi cnt1,16 ;Init loop counter
- clr job2 ;clear result (3 bytes)
- clr job1
- clr job0
- clr ZH ;clear ZH
- bBCDx_1:lsl msrL ;shift input value
- rol msrH ;through all bytes
- rol job0
- rol job1
- rol job2
- dec cnt1 ;decrement loop counter
- brne bBCDx_2 ;if counter not zero
- ret ; return
- bBCDx_2:ldi ZL,AtBCD2+1 ;Z points to result MSB + 1
- bBCDx_3:ld temp,-Z ;get (Z) with pre-decrement
- subi temp,-$03 ;add 0x03
- sbrc temp,3 ;if bit 3 not clear
- st Z,temp ; store back
- ld temp,Z ;get (Z)
- subi temp,-$30 ;add 0x30
- sbrc temp,7 ;if bit 7 not clear
- st Z,temp ; store back
- cpi ZL,AtBCD0 ;done all three?
- brne bBCDx_3 ;loop again if not
- rjmp bBCDx_1
- ;******************************
- ;;;;; Îáðàáîò÷èêè ïðåðûâàíèé
- TIM1_OVF: ; Timer1 Overflow Handler
- ; âûâîäèì äàííûå íà 7-ìè ñåãìåíòíûå èíäèêàòîðû
- ; îòñ÷èòûâàåì 100 ìñåê èíòåðâàë äëÿ çàïóñêà èçìåðåíèé
- PUSHF
- dec msek5
- brne T1L1
- ldi msek5,20
- sbr flags,1<<MSEK100
- T1L1:
- ;***************************
- ; âûâîä íà èíäèêàòîð î÷åðåäíîé öèôðû
- ldi temp,0xF0
- out DISP_PORT,temp ; ïîãàñèëè âñå èíäèêàòîðû
- cbi SER_PORT,LOCK ; ïîäãòîâèëè çàù¸ëêó
- ld temp,Y+ ; â òåìï - òåêóùàÿ öèôðà, àäðåñ=+1
- rcall LEDOUT ; âûïèõíóëè î÷åðåäíîé áàéò â ðåãèñòð
- sbi SER_PORT,LOCK ; èç 0 â 1 -- çàù¸ëêèâàíèå äàííûõ â ðåãèñòðå
- mov temp,LEDN
- andi temp,0xF0
- out DISP_PORT,temp ; âêëþ÷àåì î÷åðåäíîé èíäèêàòîð
- lsl LEDN ; ñäâèíóëè - ñëåäóþùèé èíäèêàòîð
- brlo T1L2 ; âûøëè çà ãðàíèöû? ïðîâåðêà
- ldi LEDN,0b11101111 ; äà, çàãðóæàåì íà÷àëüíîå çíà÷åíèå
- ldi YL,AtLED1 ; çàãðóæàåì àäðåñ 1-ãî èíäèêàòîðà
- T1L2:
- ldi temp,T1DIVH
- out TCNT1H,temp
- ldi temp,T1DIVL
- out TCNT1L,temp ; ïåðåçàïóñòèëè òàéìåð 1
- POPF
- reti
- ; ADC Conversion Handler
- ; ñóììèðóåì ðåçóëüòàòû èçìåðåíèé, óìåíüøàåì ñ÷¸ò÷èê.
- ADCC: in temp,ADCL
- add msrL,temp
- in temp,ADCH
- adc msrH,temp
- dec cnt2
- reti
- ;***************************
- ; áàéòû äëÿ âûâîäà 0-9 íà èíäèêàòîðû ñ ÎÀ, áåç òî÷êè. òî÷êà âêë óñòàíîâêîé áèòà 5
- LEDnd: .DB 0x30,0xF3,0x2A,0xA2,0xE1,0xA4,0x24,0xF2,0x20,0xA0
- .exit
- INT0: ; IRQ0 Handler
- reti
- PCINT0: ; PCINT0 Handler
- reti
- PCINT1: ; PCINT1 Handler
- reti
- WDT: ; Watchdog Interrupt Handler
- reti
- TIM1_CAPT: ; Timer1 Capture Handler
- reti
- TIM1_COMPA: ; Timer1 Compare A Handler
- reti
- TIM1_COMPB: ; Timer1 Compare B Handler
- reti
- TIM0_COMPA: ; Timer0 Compare A Handler
- reti
- TIM0_COMPB: ; Timer0 Compare B Handler
- reti
- TIM0_OVF: ; Timer0 Overflow Handler
- reti
- ANA_COMP: ; Analog Comparator Handler
- reti
- EE_RDY: ; EEPROM Ready Handler
- reti
- USI_STR: ; USI STart Handler
- reti
- USI_OVF: ; USI Overflow Handler
- reti
- ;
- .exit
|