;______________________________________ ; Fréquencemètre ; Matériel : ATtiny 45/85 4MHz 5V ; LCD1602 I²C ; (c) sammy76.free.fr ; V1.0 2016/11/16 ; Maj : 2016/11/16 ;______________________________________ ; ATtiny45 - 8MHz interne ; +-\/-+ ; PB5 1|- -|8 Vcc ;Signal PB3 2|- -|7 PB2 SENSELED ; PB4 3|- -|6 PB1 SDA ; GND 4|- -|5 PB0 SCL ; +----+ ; Principe de fonctionnement: ;Le processeur compte en permanence ; si signal 0->1 sur la broche Signal ;Le processeur compte toujours ; si signal 1-0 sur la broche Signal ;On affiche la valeur suivant le calcul ;Suivant la vitesse du CPU : ;La boucle fait 29cycl ;Soit une fréquence: ;F_CPU = Hz ;------------ ;29xCompteur ;Soit une vitesse de rotation : ;F_CPUx60 = /min ;------------ ;29xCompteur .CSEG .include "../includes/tn85def.inc" .define F_CPU 16500000 ;16.5MHz .define clk_per_boucl 8; .define tps_bcl_s (F_CPU/clk_per_boucl) ;Temps boucle par seconde,constante pour les calculs F .define tps_bcl_m (F_CPU*60/clk_per_boucl) ;Temps boucle par minute,constante pour les calculs N .macro ldz .message "no parameters specified" .endm .macro ldz_i ldi ZL, LOW(@0<<1) ldi ZH, HIGH(@0<<1) .endm .macro ldnum .message "no parameters specified" .endm .macro ldnum_i ldi A,low(@0) mov a0,A ldi A,high(@0) mov a1,A ldi A,BYTE3(@0) mov a2,A ldi A,BYTE4(@0) mov a3,A .endm .macro load .message "no parameters specified" .endm .macro load_16_i ldi @0,high(@2) ldi @1,low(@2) .endm .macro convstr32 mov DATA,b3 rcall conv_ASC mov DATA,b2 rcall conv_ASC mov DATA,b1 rcall conv_ASC mov DATA,b0 rcall conv_ASC ser A st Z+,A .endm ;.def A = r16 ; .def a0 = r0 .def a1 = r1 .def a2 = r2 .def a3 = r3 .def b0 = r4 .def b1 = r5 .def b2 = r6 .def b3 = r7 .def A = r16 .def buffer= r9 .def count= r17 ;.def ADR = r19 ; .equ SENSELED=PB1 ;SENSELED pin (Output on AVR) .equ SIGNAL=PB3 ;CAPTEUR ; I2C Device addressing ;.equ LCD1602 = 0x3F ; LCD1602 address byte ;----------------------------------------------------------------- .org 0000 ;************************************************ ;* Interrupt Vectors * ;************************************************ zRESET: ; Reset Handler rjmp ON_RESET zINT0addr: ; External Interrupt 0 reti zPCI0addr: ; Pin change Interrupt Request 0 reti zOC1Aaddr: ; Timer/Counter1 Compare Match 1A reti zOVF1addr: ; Timer/Counter1 Overflow reti zOVF0addr: ; Timer/Counter0 Overflow reti zERDYaddr: ; EEPROM Ready reti zACIaddr: ; Analog comparator reti zADCCaddr: ; ADC Conversion ready reti zOC1Baddr: ; Timer/Counter1 Compare Match B reti zOC0Aaddr: ; Timer/Counter0 Compare Match A reti zOC0Baddr: ; Timer/Counter0 Compare Match B reti zWDTaddr: ; Watchdog Time-out reti ;rjmp WDTinterrupt zUSI_STARTaddr: ; USI START reti zUSI_OVFaddr: ; USI Overflow reti ;***** Include modules .include "../utils/i2c_attiny.inc" .include "../utils/lcd_.inc" .include "../utils/wait.inc" .include "../utils/div32_24.inc" .include "../utils/bin2dcb32.inc" ;______________________________________ ; SETUP ;______________________________________ ON_RESET: ldi A, LOW(RAMEND) ;Setup of stack pointer 0x15F out SPL, A ldi A, HIGH(RAMEND) out SPH, A ldi A,0b10000000 ;Attention, ces 2 instructions sont importantes pour le changement de fréquence (sécurité AVR) out CLKPR,A ldi A,0b0000000 ;divise par 0le clock RC de 8MHz, donc 8MHz out CLKPR,A ;Eteint le CAN cbi ADCSRA, ADEN ;switch Analog to Digitalconverter OFF cbi DDRB,SIGNAL ;Port PB3 input ;______________________________________ ; BOUCLE PRINCIPALE ;______________________________________ rcall LCD_Init ldi DATA,0x40 ;chr 0 rcall LCD_DATA_write_cmd ldz [copyright] rcall LCD_write_string ldi DATA,0x48 ;chr 1 rcall LCD_DATA_write_cmd ldz [moin1] rcall LCD_write_string; ldi DATA,0x50 ;chr 2 rcall LCD_DATA_write_cmd ldz [e_acc] rcall LCD_write_string; ;ldi ZL,Low(compteur<<1) ;[1] ;ldi ZH,high(compteur<<1) ;[1] ;______________________________________ ;Boucle d'affichage ;______________________________________ ldnum [tps_bcl_m] ;charge avant division (dividende) load [BM:BL,0xFFFF] ;Valeur du compteur de boucles (diviseur) ldi BH,0xFF rcall DIV3224 ;a3:a2:a1:a0/BH:BL=a3:a2:a1:a0 rcall BIN2DCB32 ;Conversion BIN a3:a2:a1:a0 ->DCB b3:b2:b1:b0 ldz [L3] ;Z=adresse de L3 convstr32 ; ldnum [tps_bcl_m] ;charge avant division (dividende) load [BM:BL,0x1] ;Valeur du compteur de boucles (diviseur) clr BH rcall DIV3224 ;a3:a2:a1:a0/BH:BL=a3:a2:a1:a0 rcall BIN2DCB32 ;Conversion BIN a3:a2:a1:a0 ->DCB b3:b2:b1:b0 ldz [L4] ;Z=adresse de L4 convstr32 rcall LCD_clear ldz [txt5] ;Vitesse maxi rcall LCD_write_string ldi DATA,0xC0 ;Ligne 2 1100 0000 0x40 rcall LCD_DATA_write_cmd ldz [L4] rcall sup0tete ldz [txt4] rcall LCD_write_string ;min-1 ldi A, 1 rcall Waitseconds rcall LCD_clear ldz [txt6] ;Vitesse mini rcall LCD_write_string ldi DATA,0xC0 ;Ligne 2 1100 0000 0x40 rcall LCD_DATA_write_cmd ldz [L3] rcall sup0tete ldz [txt4] rcall LCD_write_string ;min-1 ldi A, 1 rcall Waitseconds loop_affiche: ldnum [tps_bcl_s] ;charge avant division (dividende) ;load [BM:BL,13750] ;Valeur du compteur de boucles (diviseur) ;clr BH rcall DIV3224 ;a3:a2:a1:a0/BH:BL=a3:a2:a1:a0 rcall BIN2DCB32 ;Conversion BIN a3:a2:a1:a0 ->DCB b3:b2:b1:b0 ldz [L1] ;Z=adresse de L1 convstr32 ;DCB b3:b2:b1:b0 ->STR pointer par Z finissant par 0xFF ldnum [tps_bcl_m] ;charge avant division (dividende) ;load [BH:BL,13750] ;Valeur du compteur de boucles (diviseur) rcall DIV3224 ;a3:a2:a1:a0/BH:BL=a3:a2:a1:a0 rcall BIN2DCB32 ;Conversion BIN a3:a2:a1:a0 ->DCB b3:b2:b1:b0 ldz [L2] ;Z=adresse de L2 convstr32 ; rcall LCD_clear ldz [txt1] ;F : rcall LCD_write_string ldz [L1] ;Fréquence rcall sup0tete ldz [txt2] ; Hz rcall LCD_write_string ldi DATA,0xC0 ;Ligne 2 1100 0000 0x40 rcall LCD_DATA_write_cmd ldz [txt3] ;N : rcall LCD_write_string ldz [L2] rcall sup0tete ldz [txt4] rcall LCD_write_string ldi A, 200 rcall WaitMiliseconds affiche: clr BH clr BM clr BL clr A main_bcl: ldi A,1 ;[1] clr A ;[1] add BL,A ;[1] adc BM,A ;[1] adc BH,A ;[1] sbis PORTB,SIGNAL ;[1] Saute si bit 1 set rjmp main_bcl ;[2] ;attend le retour à 0 bcl_0: ;[+1] sbis ldi A,1 ;[1] clr A ;[1] add BL,A ;[1] adc BM,A ;[1] adc BH,A ;[1] sbic PORTB,SIGNAL ;[1] Saute si bit 0 set rjmp bcl_0 ;[2] rjmp affiche ; 8 cycles conv_ASC: mov A,DATA swap A ;HIGH rcall conv_digit mov A,DATA ;LOW rcall conv_digit ret conv_digit: ;DCB->ASC 0123456789ABCDEF andi A,0x0F cpi A,0x0A BRLT suit_asc1 ;A<10 subi A,0x09 ori A,0x40 rjmp suit_asc2 suit_asc1: ori A,0x30 suit_asc2: st Z+,A ret sup0tete: ;supprime les 0 en début de chaine push ZH push ZL sup0tete1: LD A, Z cpi A,'0' brne suitetete ldi A,' ' st Z+,A rjmp sup0tete1 suitetete: pop ZL pop ZH rcall LCD_write_string_sram ret ;------------------------------------------------------------------ copyright: .db 0b01110, 0b10101, 0b11011, 0b11001, 0b11001, 0b11011, 0b10101, 0b01110,0xFF,0 moin1: .db 0b00001, 0b01101, 0b00001, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000,0xFF,0 e_acc: .db 0b00010, 0b00100, 0b01110, 0b10001, 0b11111, 0b10000, 0b01110, 0b00000,0xFF,0 txt1: .db "F: ",0xFF txt2: .db " Hz",0xFF txt3: .db "N: ",0xFF txt4: .db " min",1,0xFF txt5: .db "Vitesse maxi : ",0xff txt6: .db "Vitesse mini : ",0xff .dseg .org 0x60 L1: .byte 17 L2: .byte 17 L3: .byte 17 L4: .byte 17 compteur: .byte 5; // adresse: .byte 128; //