;______________________________________ ; GESTION DU PUITS ; Matériel : ATtiny 85 16,5MHz 5V ; HC-SR04 ; (c) sammy76.free.fr ;______________________________________ ; V1.0 ESSAI ; V2.0 MESURE ; V3.0 WATCHDOG ; V4.0 EEPROM WRITE ; V5.0 FLASH ROM WRITE ; V6.0 Modification pour Digispark ; V6.1 Erreur de début à 0X01 au lieu de 0x00 pour EEPROM ;ATtiny85 - 16.5MHz Digispark ;P0 : ;P1 : SENSELED (Interne) ;P2 : ;P3 : Trigger ;P4 : Echo ;P5 : .define F_CPU 16500000 ;16.5MHz ;FUSE H:FE, E:DD, L:E1 ;w lfuse 0 0xe1 ;w hfuse 0 0xdd ;w efuse 0 0xfe .CSEG .include "../includes/tn85def.inc" .equ SENSELED=PORTB1 ; SENSELED pin (Output on AVR) Objet détecte Sur led board .equ TRIG=PORTB3 ; Sensor TRIG pin (Output on AVR, input on sensor) .equ ECHO=PORTB4 ; Sensor ECHO pin (Input on AVR, output on sensor) ; 16,5MHz =>0,060606µs/clk ;10µs => 165clks ((F_CPU/100000)-7)/4=39 x BDELAY ; .equ BDV10usCNT=((F_CPU/100000)-7)/4 ; Nombre d'itérations de BDELAY(4*BDV+7) .equ V=17010 ;Vitesse du son en cm/s ;Le son vas à 340,19m/s soit A/R 170,10m/s ;F_CPU[clk/s] [clk].[s] ;-------------=-----------= clk/cm donc (F_CPU/V)=nombre de clk ; V[cm/s] [cm].[s] ;16,5E6[clk/s] ;-------------==970 clks/cm ;17010 [cm/s] ;(970-15)/4=238 x BDELAY pour 1cm .equ BDV1cmCNT=(F_CPU/V-15)/4 ; Nombre d'itérations de BDELAY(4*BDV+7)+8/cm pour une résolution d'1cm. .equ mesure_temps=30 ; les mesures toutes les X min .equ time_wait=(mesure_temps*60)/8 ;mettre 225 (x8S) pour 30min ******************************************************* .equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB (PAGESIZE=64 pour ATtiny85) is page size in BYTES, not words FLASH RAM .equ MAX_SAVE=0xC0 ; Nombre de sauvegarde dans l'EEPROM 192 (3x64 0x40) bytes soit 96h(4j) .def A = R16 ; GENERAL PURPOSE ACCUMULATOR .def BDV = R17 ; Counter used in BDELAY routine. .def DATA =R18 ; Data to EEPROM ou FLASH ou SRAM .def temp1=R19 ;Pour FLASH RAM (do_spm) .def temp2=R20 ;Pour FLASH RAM (do_spm) .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 rjmp WDTinterrupt zUSI_STARTaddr: ; USI START reti zUSI_OVFaddr: ; USI Overflow reti ;______________________________________ ; SETUP ;______________________________________ ON_RESET: ldi A, LOW(RAMEND) ;Setup of stack pointer 0x15F t45/0x25F t85 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,0b00000000 ;divise par 1 le clock RC de 8MHz, donc 8MHz out CLKPR,A ;Eteint le CAN cbi ADCSRA, ADEN ;switch Analog to Digitalconverter OFF ;rcall WDT_on ;Set le watchdog at boot not set rcall WDT_off ;Stop le watchdog ;Configure les sorties ldi A, (1<=1 brge GEPret ; [1]/2=4 If CNT overflows to zero, exit routine. ; Timing: false:1clk, true:2clk ldi BDV,BDV1cmCNT ; [1]=5 Charge le compteur de délai rcall BDELAY ; *time is 8+(4*BDV+7) incl. setting BDV and this rcall. ; BDV1cmCNT=(4*BDV+7) sbic PINB, ECHO ; [1]/2=6 Check ECHO pin. If no ECHO, skip over next instruction. ; Timing: false:1clk, true:2clk rjmp GEP1 ; [2]=8 GEPret: ;Prépare la sauvegarde cpi XH,1 ;Sinon si XH>=1 (>511cm); objet non détecté brge MAINWAIT tst XL breq MAINWAIT ;Si 0 pas d'objet OBJETOK: rcall sauvegarde ;SBI PORTB,SENSELED ; Allume la Led SENSELED Objet détecté. ;rjmp MAINWAIT MAINWAIT: ldi A,time_wait ;225x8S pour 30min BOUCLE: ;Pause du watchdog (8s) Push A rcall WDT_on ; Watchdog on ldi A,(1<8MHz dec BDV ; [1] BDV-1 brne BDELAY ; [2] boucle si non égal ; Temp: false:1clks, true:2clks ret ; [4] Else return ;___________________________________________ ; RECUPERE L'ADRESSE DANS L'EEPROM (YL) ; SAUVEGARDE LA DONNEE-100cm (XH:XL) ;___________________________________________ ; RECUPERE L'ADRESSE DANS L'EEPROM (00:YL) sauvegarde: ;Départ EEPROM ;Lit Les 2 premiers octets pour l'adresse ou écrire ;EEPROM_readAnything(0, adr); ser YL ;YL=FF rcall EEPROM_read ;Read EEPROM (00:FF)->DATA (YL) mov YL,DATA ; SAUVEGARDE LA DONNEE-100cm dans OO:YL inc_adr: inc YL ;Adresse de sauvegarde +1 ldi A,MAX_SAVE cp A,YL ;if (0xBF>=YL) ; ;En fonction de la taille mémoire brsh save_adr ;si >= alors save_adr ;Sauvegarde dans RAM FLASH rcall save_flash ser YL ;YL=FF RETOURNE A LA VALEUR 0 (inc au premier tour) save_adr: ;Sauve l'adresse en 0xFF mov DATA,YL ;DATA=YL ser YL ;YL=FF rcall EEPROM_write ;write EEPROM (00:FF)<-DATA (YL) mov YL,DATA ;Déduit 100cm sbiw XH:XL,63 ;Si dist=dist-100 (63+37) brmi save_data3 ;si<0 sbiw XH:XL,37 ; brpl save_data1 ;si >0 save_data3: clr XL ;Sinon XL 0 si (dist-100)<0 clr XH save_data1: tst XH ;Si XH=0 sauve breq save_data2 ser XL ;sinon XL=maxi (0xFF) save_data2: mov DATA,XL rcall EEPROM_write ret ;_______________________ ; END SAUVEGARDE ;_______________________ ;___________________________________________ ; SAUVEGARDE FLASH de 0x00 à 0xBF ; DANS RAM FLASH de 0x0200 à 0x7FF par plage de 32 mots ;___________________________________________ save_flash: ;Récupère l'adresse de la FLASH RAM dans ZH:ZL ldi YL,LOW(memsave) ;YL=FD rcall EEPROM_read ;Read EEPROM (00:FD)->DATA (ZH) mov ZH,DATA rcall EEPROM_read ;Read EEPROM (00:FE)->DATA (ZL) mov ZL,DATA clr YH clr YL ldi temp1,3 wrloop: push ZH push ZL ;write_page: ;Efface la page pointé par Z ldi A, (1<DATA (ZH) mov r0,DATA rcall EEPROM_read ;Read EEPROM (00:FD)->DATA (ZH) mov r1,DATA ldi A, (1<=ZH brsh save_adr_flash ;si >= ldi ZH,0x02 ;RAZ adr ZH:ZL clr ZL save_adr_flash: ldi YL,LOW(memsave);0xFD mov DATA,ZH rcall EEPROM_write ;DATA (00)->EEPROM (00:FD) ZH inc YL mov DATA,ZL rcall EEPROM_write ;DATA (00)->EEPROM (00:FE) ZL ret ;_______________________ ; END SAUVEGARDE ;_______________________ ; Interruption du timeout du watchdog. On retourne simplement juste après le "sleep" ! WDTinterrupt: reti ;***** Include modules .include "../utils/watchdog.asm" .include "../utils/eeprom_V5.asm" ;______________________________________ ; END OF PROGRAM ; ;______________________________________ .org 0xc0 .db 30,10,16,7,30,0 ;Date et heure de mise à jour .ESEG .org 0xc0 buildtime: .db "sammy76.free.fr " .db "V5.10:%DAY%.%MONTH%.%YEAR% %HOUR%:%MINUTE%" .org 0xfd memsave: .db 02,00,0xFF ;FD FE FF