; ============ vbb ======================= ; cm48.asm === исх. cm47.asm ; 1044-32 byte 1048-32 byte ; ========= AVRASM2 v.2.1.3 ============== ; Purp : CmC with mED44: measure, >0<, calibration v2 ; Hard : file://d:/Work/14/CmC14/cmc14.spl7 p.1 ; Fuses: tn2313: 0xCFD9FF {Ex,Hi,Lo} ext 10MHz ; Extra: ; State: 0707/0707/110116 ; ======================== .DEVICE ATtiny2313 .nolist .include "tn2313def.inc" .include "avr.inc" .list ;***** Constantes ;General: .equ NPD =2 ; number of pairs of digits .equ BPr =7 ; Button pressed ;Keyboard scancodes: .equ K_NO =0x00 ;no press .equ Zero =0x01 ;Zero key, ENTER code .equ K_DN =0x02 ;key DOWN code .equ K_UP =0x04 ;key UP code .equ K_EN =0x08 ;key EXIT code .equ cal_LR =0x0A ;calibration Low Range .equ cal_HR =0x0C ;calibration High Range ;***** Variables .DSEG ;data segment (internal SRAM) RAMBEG: ;internal SRAM: RAMBEG..RAMEND Idle: .byte 1 Comp1: .byte 2 ;Range low compensation Comp2: .byte 2 ;Range high compensation Comp3: .byte 2 ;Zero compensation value Check: .byte 1 ;Check Sum DispPtr:.byte 1 ;Display buffer DispBuf:.byte NPD*2 ;number digits LED (NPD*2) KeySc: .byte 1 StrBuf: .byte 10 ;Decimal conversion buffer .ESEG ;EEPROM initial values, see add.txt Enone: .DB 0 ;address 0 not used EComp: ;values array EComp1: .DW 0x95A0 ;LR (по 4700±1%) EComp2: .DW 0x99B0 ;HR EComp3: .DW 0x0129 ;Z ECS: .DW 0x02FD ;Check Sum 0x55+0x95+0xA0+0x99+0xB0+0x01+0x29=0x02FD Eend: ;end of used EEPROM ;***** Global Register Variables ;r0 used with lpm instruction .def Cnt_pr = r11 ; Cnt_pair .def sc_key = r12 .def _Stm2 = r13 ;System timer (250Hz decrement/zero stopped) .def _Stm1 = r14 ;System timer (250Hz decrement/zero stopped) .def _0 = r15 ;Zero register .def _Flags = r25 ;b0:Result is minus ;b1:Capture completed ;b2:Integration time out ;b7:Button pressed ;r26,r27 used as X register ;r28,r29 used as Y register ;r30,r31 used as Z register ;***** Port Definitions ;DIRx = 1 - out ;PUPx = 1 - IN:pull-up on; OUT: =1 ;Port B: .equ syn2 =PB5 .equ syn0 =PB7 ;Port D: .equ CLK =PD0 .equ SD =PD1 ;----------------------------------------------------------; ; Program code area .cseg .org 0x0000 rjmp reset ;Reset rjmp 0 ;Extrenal INT0 rjmp 0 ;External INT1 rjmp tc1_cap ;TC1 capture rjmp 0 ;TC1 compare rjmp tc1_ovf ;TC1 overflow rjmp tc0_ovf ;TC0 overflow .org 0x0007 ;----------------------------------------------------------; ; Initialize reset: ; outi SPL,low(RAMEND) ;Initial Value RAMEND clr _0 ;Permanent zero reg. ldiw Z, RAMTOP ;Clear RAM ldi AL, 128 st Z+, _0 dec AL brne PC-2 ;/ outi PORTD, 0b0111100 ;Port D outi DDRD, 0b1111111 ;/ outi PORTB,0b01111000 ;Port B outi DDRB, 0b10101101 ;/ ; outi TCCR0A, 0x00 ; initial Value 0 ; outi TCCR0B, 0b00000100 ; TC0.ck = 8.000/256=31,25kHz outi TCCR0B, 0b00000101 ; TC0.ck = 10.000/1024=9,76kHz (102,4u) outi TIMSK, 0b00000010 ; Enable TC0.ov sbi ACSR, ACIC ; Connect ACO to TC1 input capture clr _Flags sei ldi AL, 50 ; rcall dly ;/ rcall load_eep ;Load gain compensation values (проверка КС) breq PC+6 ; если =/=0, то E4 и загрузка значений по умолчанию ldiw Z, form3*2 rcall put_formed ldi AL, 50 rcall dly ;/ ;----------------------------------------------------------; ; Command processing loop (main) main: tst _Stm2 brne PC-1 ;/ sbic GPIOR0, BPr rjmp RNM ldi AL, 112 ;Start SysTimer2 (10mS*106=1 S) mov _Stm2, AL ;/ rcall measLR ;Measure at low range brcc PC+2 ;If time out, retry at high range rcall measHR rcall adjust_zero ;Refresh display rcall adjust_gain rcall disp_val ;/ rjmp main ;------------------------ ; RNM: ; Pressure! mov AL, sc_key cpi AL, Zero ; cal_Zero,ENTER breq can_offset cpi AL, cal_LR breq cal_low cpi AL, cal_HR breq cal_high rjmp ex_pr cal_low: rcall measLR rcall adjust_zero ;/ ldiw C, 0 ;X:D:C = 10000*65536; (1nF reference cap) ldiw D, 10000 ldiw X, 0 ;/ ldi ZL, Comp1 rjmp cal_comp cal_high: rcall measHR ldiw C, 0 ;X:D:C = 1000*65536; (100nF reference cap) ldiw D, 1000 ldiw X, 0 ;/ ldi ZL, Comp2 cal_comp: clrw T0 ;X:D:C /= B:A; clrw T2 ldi EL, 48 lslw C rolw D rolw X rolw T0 rolw T2 cpw T0, A cpcw T2, B brcs PC+6 subw T0, A sbcw T2, B inc CL dec EL brne PC-21 ;/ or DL, DH ;Check over flow or DL, XL or DL, XH brne cal_err ;/ stdw Z+0, C ; address CompN rcall save_eep rcall clr_disp rjmp main can_offset: rcall measLR ;if Carry Set is accident or BL, BH ;Check adjustment range brne cal_err cpi BH, high(2000) brcc cal_err ;/ stsw Comp3, A ;Set the value as zero point rcall clr_disp ;; ЗДЕСЬ БЫ ЗАЖЕЧЬ Co rjmp main ; cal_err: ldiw Z, form4*2 ;E5 rcall put_formed ex_pr: cbi GPIOR0, BPr ldi AL, 6 rcall dly rjmp main ;------------------------ ; dly: mov _Stm1, AL tst _Stm1 brne PC-1 ret ;----------------------------------------------------------; ; Measure capacitance measLR: cbi PORTB, 3 ; Set low range cbi DDRB, 3 ldi AL, 20 ;; 0,1*65536*20=131072 uS rjmp PC+4 measHR: sbi PORTB, 3 sbi DDRB, 3 ; Measure capacitance for reference high ldi AL, 152 ;; 0,1*65536*152=1002 mS measure: ; v2 mov T2H, AL ;/ out TCNT1H, _0 ; Clear TC1 and set time limit out TCNT1L, _0 clr T2L outi TIFR, 0b10001000 ;Enable TC1.ov, TC1.cap сбросить флаги! outi TIMSK, 0b10001010 cbr _Flags, bit0+bit1+bit2 ;/ cbi DDRB, 0 ;Start to charge outi TCCR1B, 0b11000001 ;Start TC1, захват по _/ sbrc _Flags, 2 ;Wait for end of integration (time-out) rjmp mea_over sbrs _Flags, 1 ; b1:Capture completed rjmp PC-3 ;/ outi TCCR1B, 0b01000000 ;Stop TC1 sbi DDRB, 0 ; discharge movew A, T4 ;Get result movew B, T6 ;/ clc ret mea_over: outi TCCR1B, 0b01000000 ;Stop TC1 sbi DDRB, 0 ; discharge ldi AL, 4 ;Wait for 16ms rcall dly ldi BH, -1 sec ret ;----------------- ; adjust_zero: sbic PORTB, 3 ;Skip if in low range rjmp PC+19 ;/ ldsw C, Comp3 ;B:A -= Comp3; subw A, C sbc BL, _0 sbc BH, _0 ;/ brcc PC+10 ;if sign, B:A *= -1; and set sign flag. sbr _Flags, bit0 ; minus! comw A comw B adc AL, _0 ;инверсия + 1 : дополнение до 2-х adc AH, _0 adc BL, _0 adc BH, _0 ;/ ret adjust_gain: ldiw Y, Comp1 sbic PORTB, 3 ;Gain adjustment adiw YL, 2 ;Load compensation value in to D by range lddw D, Y+0 ;/ subw C, C ; B:A = B:A * D / 65536; ldi EL, 33 brcc PC+3 addw C, D rorw C rorw B rorw A dec EL brne PC-10 ;/ movew A, B movew B, C ret ;----------------------------------------------------------; ; Display value of B:A in unit of 0.1pF disp_val: ldiw X, StrBuf ;Decimal buffer clr DL ;Number of digits inc DL ;--- Digits++ clr CL ; --- /= 10; ldi CH,32 lslw A rolw B rol CL cpi CL,10 brcs PC+3 subi CL,10 inc AL dec CH brne PC-10 ; / st X+, CL ; остаток в StrBuf cp AL, _0 cpc AH, _0 cpc BL, _0 cpc BH, _0 brne PC-19 ;/ cpi DL, 2 ;Adjust digits for 0.0pF brcc PC+3 st X+, _0 inc DL ;/ sbic PORTB, 3 ;Adjust digits if in low range addi DL, 3 ;/ ldiw Z, form2*2-4 ;Select form sbrs _Flags, 0 ;b0:Result is minus adiw ZL, 16 ;: adiw ZL, 4 dec DL cpi DL, 2 brcc PC-3 ;/ put_formed: ; v2 ldiw Y, DispBuf lp_pf: lpm AL, Z+ ; memory access programs ; clt cpi AL, 2 brcc PC+3 bst AL, 0 ; Save DP ld AL, -X bld AL, 7 ; newDP st Y+, AL cpi YL, DispBuf+4 brne lp_pf ret clr_disp: ldiw Y, DispBuf st Y+, _0 cpi YL, DispBuf+4 brcs PC-2 ret form4: .db 14, 5, 15, 15 ;E5 form3: .db 14, 4, 15, 15 ;E4 form2: .db 10, 1, 0, 13 ;-0.0p .db 10, 0, 0, 13 ;-00p .db 14, 3, 15, 15 ;E3 .db 14, 3, 15, 15 ;E3 form1: .db 15, 1, 0, 13 ; 0.0p .db 0, 1, 0, 13 ;00.0p .db 0, 0, 0, 13 ;000p .db 1, 0, 0, 12 ;0.00n .db 0, 1, 0, 12 ;00.0n .db 0, 0, 0, 12 ;000n .db 1, 0, 0, 11 ;0.00u .db 0, 1, 0, 11 ;00.0u .db 0, 0, 0, 11 ;000u .db 14, 2, 15,15 ;E2 .db 14, 2, 15,15 ;E2 .db 14, 2, 15,15 ;E2 seg7: ; 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 .db 0xeb,0x82,0xb9,0xb3,0xd2,0x73,0x7b,0x83 ; 8 , 9 , - ,u , n , p , E , .db 0xfb,0xf3,0x10,0xD8,0x1a,0xd9,0x79,0x00 ;==========================================================; ; Load/Save EEPROM load_eep: ; v2 ldiw Y, Comp1 ;Load compensation data ldiw C, 0x5501 ;: rcall read_eep st Y+, AL add CH, AL cpi YL, Comp1+6 brne PC-4 ;/ rcall read_eep ;Check SUM cp AL, CH breq PC+6 sti -Y, -1 ;Set default value if data have been broken st -Y, AL st -Y, AL st -Y, AL ;/ ret ;---------------------------------------------- ;Wait for EEPROM ready and read EEPROM: ;In : CL - address ;Out: AL-data, CL-next address read_eep: sbic EECR, EEPE ; EEPE rjmp PC-1 ;wait for EEPROM ready out EEAR, CL ;EEPROM address sbi EECR, EERE ;strobe inc CL ;EEPROM address inc in AL, EEDR ;read EEPROM ret ;----------------------------------------------------------; ; save_eep: ; v2 ldiw X, Comp1 ; Save compensation data ldiw C, 0x5501 ; начальный адрес и контрольная сумма ;: ld AL, X+ add CH, AL rcall write_eep cpi XL, Comp1+6 brne PC-4 ;/ mov AL, CH ; Save check SUM write_eep: ; in: (AL)-data, (CL)-address sbic EECR, EEPE rjmp PC-1 ; wait for EEPROM ready out EEAR, CL ; The EEPROM Address Register out EEDR, AL cli sbi EECR, EEMPE sbi EECR, EEPE sei inc CL ret ;***** Interrupts Service Routines ;----------------------------------------------------------; ; TC1 overflow interrupt ; ; T2L counts carry outs from TCNT1. When T2L reaches T2H, ; a time-out error flag will be set. tc1_ovf: push AL in AL, SREG push AL inc T2L cp T2L, T2H brcs PC+6 ; brench if (T2H)>(T2L) sbi DDRB, 2 ; go to the threshold 0,17E sbi DDRB, 0 ; discharge sbr _Flags, bit2 ; b2:Integration time out outi TIMSK, 0b00000010 pop AL out SREG, AL pop AL reti ;----------------------------------------------------------; ; TC1 capture interrupt ; ; When Vc reaches 0.17 Vcc, capture t1 and change reference ; voltage to 0.5Vcc. When Vc reaches 0.5 Vcc, capture t2 and ; terminate the measureing. tc1_cap: push AL in AL, SREG push AL sbis DDRB, 2 ;if 0,17E then PC+2 rjmp tc1c_ed tc1c_st: ; Vc reaches 0.17 Vcc in T4L, ICR1L ;Capture t1 in T4H, ICR1H mov T6L, T2L ;/ cbi DDRB, 2 ;Change Vth to 0.5 Vcc. ldi AL, 20 ;Deley several microseconds and clear Irq. dec AL brne PC-1 outi TIFR, 0b00001000 ;/ clear Flag ICF1 rjmp tc1c_e tc1c_ed: ; Vc reaches 0.5 Vcc mov T6H, T4L ;Capture t2-t1 in T4L, ICR1L sub T4L, T6H mov T6H, T4H in T4H, ICR1H sbc T4H, T6H mov T6H, T6L mov T6L, T2L sbc T6L, T6H clr T6H ;/ обязательно!! sbi DDRB, 2 ;Set Vth to 0.17 Vcc. sbi DDRB, 0 ;Discharge capacitor outi TIMSK, 0b00000010 ;Disable Irq. sbr _Flags, bit1 ;End of measureing. tc1c_e: pop AL out SREG, AL pop AL reti ; OUT: T6L:T4H:T4L ;---------------------------------------------------------; ; TC0 overflow interrupt (Fosc=10000/1024=9,76kHz/102,4u) ; - Refresh LED display. ; - Scan button inputs. ; - Decrement _Stm1 and _Stm2. (0,102*98=10 mS) tc0_ovf: ; v2 push AL in AL, SREG pushw A pushw Z sei outi TCNT0, -98 ; 10MHz sbic PORTD, SD rcall SCANm ; (sc_key) - scancode kbd rcall dl_1 ; в соответствии с состоянием SD ; вывод пары в сдвиговый регистр tst _Stm1 ;Decrement Stm with zero stopeed... breq PC+2 dec _Stm1 tst _Stm2 breq PC+2 dec _Stm2 ;/ popw Z popw A out SREG, AL pop AL reti ;***** Keyboard support: ;Scan local keyboard: ;in : clk - x , sd - x ;Out: sc_key - scancode, set BPr (on the second scan) SCANm: ldi AL,0b00001000 ;load 0bXXXX0001 in HC164 rcall wr4b ; OUT: CLK=1, SD=1 (pull-up on) ldi AL,0b00010000 mov sc_key, AL ;scan 4 buttons by 4 impulses sc1: ; IN: CLK==1, SD==Z cbi DDRD, SD ; is input cbi PORTD, SD ; copy sc_key0 <- SD clc sbis PIND, SD ; sd==portc0 sec ; sbi DDRD, SD ; is output, SD==0 cbi PORTD, CLK ; CLK <- 0 rol sc_key sbi PORTD,CLK ; CLK <- 1 write 0, shift, open key sbi PORTD,SD ; SD <- 1 (pull-up on) brcc sc1 ;OUT: CLK=1, SD=1 ;detect: ldiw Z, KeySc ld AL, Z ; read the previous scan st Z, sc_key ; save the current scan cp AL, sc_key breq PC+5 ; brench, kbd inactive eor AL, sc_key and AL, sc_key breq PC+2 sbi GPIOR0, BPr ;/ b7:Button pressed ret ;***** Display support: ; dl_1: ldi AL, NPD mov Cnt_pr, AL ; number of pairs of digits/2 ldiw Y, DispBuf sbis PORTD, SD inc YL ; odd cycle - odd places dl1: ld AL, Y+ ; read LSB, then MSB inc YL ; increment the pointer by 2 ; write symbol from temp to Shift Register ; temp.7 - decimal point ; ;--- save decimal point bst AL, 7 ;T <- temp.0 ;--- andi AL,0x7F ;temp.7 <- 0 ldiw Z, seg7*2 ;char table base rcall RdTbl ;temp <- char bld AL, 2 ;bit 2 - segment H, restore DP ! ;Write data from temp to SD: rcall wr8b ; write byte from AL to SR ; OUT: CLK=1, SD=? dec Cnt_pr brne dl1 cbi PORTD, CLK ; CLK <- 0 , do not delete! ; read lock KBD after recording ;---Reverse the current state of the line SD ; invert bit.0 YL and copy in SD ;--- copy /YL.0 -> SD cbi PORTD, SD ; SD <- 0 ; sbrc YL, 0 ;! or sbrs if the address (DispBuf) is odd! sbrs YL, 0 ;! or sbrc if the address is odd even ! sbi PORTD, SD ;--- ret ;***************************************************** ;Read table to temp: ;in : Z - base, temp - offset ;OUT: (temp) - cardbit RdTbl: add ZL, AL ;add offset (Z + temp) adc ZH, _0 lpm AL, Z ret ;****************************************** ;Write from AL to Shift Register: ;IN: (AH)=n, (AL)=[0bxxxxxxxx], CLK=x, SD=x ; wr4b: ldi AH, 4 rjmp wr_n wr8b: ldi AH, 8 wr_n: sbi DDRD, SD ; SD is output cbi PORTD, CLK ; CLK <- 0 ; copy AL -> SD cbi PORTD, SD ; SD <- 0 sbrc AL, 0 ; Low bit forward sbi PORTD, SD ;/ sbi PORTD, CLK ; CLK <- 1 lsr AL dec AH brne wr_n sbi DDRD, SD ; SD is output (open the gate) ret ;------------ .org PC+0 IDF1: .DB 20,20,20,20,"•","•","c","m","4","8","•","•",20,20,20,20 IDF2: .DB 20,20,20,20,"i","@","v","b","b",".","s","u",20,20,20,20 ;---------