Progetto accensione 8 luci Rnd

Eseguito per la Chiesa di Romanoro nel Dicembre 1999

 

 

Schema

Flow-chart

Sorgente asm pic

 

Il progetto prevede l’ uso di un microcontrollore PIC16C84 con 8 uscite per accensione luci e 3 uscite ausiliarie. Si prevedono  anche 2 ingressi.

Descrizione del circuito:

In fase di riposo il pic controlla continuamente un ingresso e se lo trova basso spegne tutte le luci che sono collegate alla porta b, quando l’ ingresso cambia di stato (va alto),  alza o (abbassa dipende come e’ meglio) il bit di una uscita ausiliaria (si puo’ collegare lo spegnimento del mulino)e dopo un po’ di ritardo (fisso), accende a caso le varie luci delle casette (otto uscite), tenendo un breve ritardo tra una accensione e l’ altra (circa 1 secondo). Oppure, invece di controllare sempre l’ ingresso, si può far partire il tutto nel momento che viene alimentato.

Comunque sia il metodo per la partenza, quando ha acceso tutte le luci, dopo un periodo di tempo comincia a spegnere a random le luci e aspetta tra uno spegnimento e l’ altro un tempo superiore rispetto a quello avvenuto prima tra una accensione e l’ altra.

Ovviamente tutto questo ciclo (accensione, spegnimento di tutte le luci) deve avvenire in un tempo inferiore al tempo NOTTE fissato nella centralina alba tramonto.Questo perché avvenendo l’ inizializzazione del ciclo quando va in NOTTE la centralina alba tramonto,  prima che quest’ ultima faccia ALBA o comunque quando é ancora NOTTE devono essere spente tutte le case.

Per la generazione del numero random si usa una routine che necessita di due registri (RAND_HI e RAND_LO) nei quali sono caricati 2 numeri (a 8 bit). Il registro con il Byte RAND_HI ha un valore random all’ accensione del pic, in altre parole non gli viene assegnato nessun valore, mentre il registro RAND_LO prende il valore dalla EEPROM del pic. Il valore che prende lo legge come già detto da un registro della EEPROM pic. Questo registro e’ quello puntato dal valore messo in un altro registro Eeprom che potrebbe essere l’ ultimo (63 D); al primo uso il valore contenuto in questo registro vale 0 quindi il numero passato a RAND_LO sarà quello contenuto nel registro 00 della Eeprom pic; la seconda volta che il programma ripartirà caricherà in RAND_LO il  valore che ha trovato nel addr Eeprom pic 01 (era stato incrementato) ecc…

Il numero massimo di registri è volutamente 32 (si effettua un AND con 32 con il numero letto nel adr 63D)  in modo che possano rimanere liberi altri 32 registri della Eeprom pic per eventuali future modifiche.

Con questi numeri casuali contenuti nei registri della Eeprom pic, la routine genererà per 8 volte altri numeri casuali (con l’ aiuto di RAND_HI) che opportunamente filtrati ed elaborati contribuiranno ad accendere le luci nelle casette in modo casuale.

I vari ritardi (in secondi) sono dichiarati all’ inizio del listato asm:

 

RIT_INI :    ritardo iniziale dopo che la centralina AGTN ha dato alimentazione al pic

RIT_TRA_ACC:  ritardo tra una accensione di una casetta e l’ altra

RIT_ACC_ALL :  ritardo prima di iniziare a spegnere dopo che si sono accese tutte le casette

RIT_TRA_SPE :  ritardo tra uno spegnimento e l’ altro

Schema

 

 

Flow-chart

Sorgenti

;**************************************************************************

;

;                             Fontana Dino

;

;                      listato asm luci presepe

;

;                      Versione 1.2 del 01-12-99

;

;**************************************************************************

 

      LIST p=16c84

#include p16c84.inc;   

      __CONFIG 11h

      constant BASE_VAR=0CH

      LOOP3       equ BASE_VAR+0          ; for timing

      LOOP2       equ BASE_VAR+1

      LOOP1       equ BASE_VAR+2

      LOOP4       equ BASE_VAR+3   

      RAND_HI     equ BASE_VAR+4          ; 16-bit random number

      RAND_LO     equ BASE_VAR+5

      TEMPB       equ BASE_VAR+6   

      TEMPLETTO   equ BASE_VAR+7

      TEMPDATA    equ BASE_VAR+8

     

;-------------------------------------------------------------------------------

; assegnazione ritardi (x 1 sec.)

      RIT_INI           equ   .1          ; ritardo all' accensione

      RIT_TRA_ACC equ   .1          ; ritardo tra due accensioni

      RIT_ACC_ALL equ   .5          ; ritardo dopo che tutto e' acceso prima di cominciare a spegnere

      RIT_TRA_SPE equ   .2          ; ritardo tra due spegnimenti

 

MAIN:

      clrf  PORTB

;     clrf  RAND_HI

;     clrf  RAND_LO

      bsf   STATUS,RP0

      clrf TRISB                   ; all bits on PORTB are outputs

      movlw b'11111000'

      movwf TRISA

      bcf   STATUS, RP0

      clrf  PORTA

;------------------------------------------------------------------------------------------------------

;

; Lettura della EEPROM pic all' adr 63 dove e' contenuto l' adr prossimo da leggere

; si fa un and con il  numero 31

;

;--------------------------------------------------------------------------------------------

 

      movlw .63

      movwf EEADR                   ; leggi dalla eeprom quale regitro della stessa devo leggere    

      call  readeeprom

      movf  EEDATA,W                ; in EEDATA ho il valore letto

      movwf TEMPDATA                ; metto in TEMPDATA

      movlw b'00011111'

      andwf TEMPDATA,F              ; faccio and con il numero 31 in modo da avere sempre un numero compreso tra 0 e 31

      movf  TEMPDATA,W 

      movwf EEADR                   ; metto questo numero compreso tra 0 e 31 in EEADR

      call  readeeprom              ; leggo questo registro della EEPROM

      movf  EEDATA,W

      movwf RAND_LO                      ; e metto il dato letto in RAND_LO

      incf  TEMPDATA,W              ; aumento di uno il registro letto prima

      movwf EEDATA

      movlw .63                     ; lo scrivo nell' adr 63 cosi' la prossima volta andro' a prendere i dati da un Adr eeprom pic successivo

      movwf EEADR

      call  writeeprom

      movlw RIT_INI                      ; ritardo iniziale

      movwf LOOP4

      call  DELAY

main_1

      call  RANDOM                       ; generate 16-bit random number

      movf  RAND_LO,W

      andlw b'00001111'

      btfsc STATUS,Z                ; se il risultato e' zero rirandomizza

      goto  main_1

      call  table

      movwf TEMPLETTO

      movf  PORTB,W

      andwf TEMPLETTO,W

      btfss STATUS,Z                ; salta se non c'e' già

      goto  main_1

      movf  PORTB,W

      iorwf TEMPLETTO,W

      movwf PORTB

      movf  PORTB,W

      xorlw b'11111111' ; ho acceso tutto

      btfss STATUS,Z    ; se z e' 1 vuol dire che ho acceso tutto

      goto  rita

      goto  cspegni

rita

      movlw RIT_TRA_ACC             ; ritardo tra una accensione e l' altra       

      movwf LOOP4

      call  DELAY

      goto  main_1            ; repeat indefinitely

; -------------------------------- Inizio spegnimenti ------------------------

cspegni

      movlw RIT_ACC_ALL             ; ritardo dopo che sono accesi tutti prima di cominciare a spegnere

      movwf LOOP4

      call  DELAY

main_2

      call  RANDOM                       ; generate 16-bit random number

      movf  RAND_LO,W

      andlw b'00001111'

      btfsc STATUS,Z                ; se il risultato e' zero rirandomizza

      goto  main_2

      call  table

     

      movwf TEMPLETTO

;     movf  PORTB,W

      comf  PORTB,W

      andwf TEMPLETTO,W

      btfss STATUS,Z                ; salta se non c'e' già

      goto  main_2

;     movf  PORTB,W

      comf  PORTB,W

      iorwf TEMPLETTO,F

      comf  TEMPLETTO,W

      movwf PORTB

;     movf  PORTB,W

      xorlw b'00000000'             ; ho acceso tutto

      btfss STATUS,Z                ; se z e' 1 vuol dire che ho acceso tutto

      goto  rita_1

      goto  hofinito

rita_1

      movlw RIT_TRA_SPE             ; ritardo tra una accensione e l' altra       

      movwf LOOP4

      call  DELAY

      goto  main_2                       ; repeat indefinitely

; *****************************************************************************************

; Inizio Sub

; *****************************************************************************************

RANDOM:

      movf  RAND_HI, W        ; if current random is 0000, make it 00FFH

      iorwf RAND_LO, W

      btfsc STATUS, Z

      comf RAND_LO, F  

      btfss RAND_HI, 6  ; hi.7 = hi.7 xor hi.6

      movlw 00H

      btfsc RAND_HI, 6

      movlw 80H

      xorwf RAND_HI, F 

      btfss RAND_HI, 4  ; hi.7 = hi.7 xor hi.4

      movlw 00H

      btfsc RAND_HI, 4

      movlw 80H

      xorwf RAND_HI, F 

      btfss RAND_LO, 3  ; hi.7 = hi.7 xor lo.3

      movlw 00H

      btfsc RAND_LO, 3

      movlw 80H

      xorwf RAND_HI, F 

      rlf RAND_HI, W          ; carry = hi.7

      rlf RAND_LO, F          ; double left shift

      rlf RAND_HI, F

      return

;'''''''''''''''''''

DELAY:                       ; delays LOOP4 * 1 Sec

      movlw .100

      movwf LOOP3

DELAY_3

      movlw .10         ; 10 msecs

      movwf LOOP2

DELAY_1:

      movlw .110

      movwf LOOP1

DELAY_2:

      clrwdt

      nop  

      nop

      nop

      nop

      nop

      decfsz LOOP1, F

      goto DELAY_2

      decfsz LOOP2, F

      goto DELAY_1

      decfsz LOOP3, F

      goto DELAY_3

      decfsz      LOOP4,F

      goto DELAY

      return

;'''''''''''''''''''''''''''

;--------------- Scrive un byte in eeprom

; dati in imput :

;

;  EEADR = indirizzo di locazione (0-63)(banco 0)

;  EEDATA = Valore da memorizzare (banco 0)

;-----

writeeprom

      bsf   STATUS,RP0

      bcf   INTCON,GIE

      bsf   EECON1,2

      movlw 0x55

      movwf EECON2

      movlw 0xAA

      movwf EECON2

      bsf   EECON1,1

aspfine clrwdt               ; attendi fine scrittura

      btfss EECON1,4

      goto  aspfine

      bcf   EECON1,4

      bcf   EECON1,2

      bcf   STATUS,RP0

      retlw 0

;

; ----------------- legge un byte in eeprom ---------

;

; Dati in input:

;

; EEADR = indirizzo locazione da leggere ( 0 - 63 ) (banco 0)

; -----------------------------------------

;

; Dati in output

;

; EEDATA = valore letto (banco 0)

; ---------------------------

readeeprom

      bsf   STATUS,RP0

      bsf   EECON1,0

      bcf   STATUS,RP0

     

        retlw     0

;'''''''''''''''''''''''''

table

      addwf PCL,F

      retlw .1

      retlw .2

      retlw .4

      retlw .8

      retlw .16

      retlw .32

      retlw .64

      retlw .128

      retlw .1

      retlw .2

      retlw .4

      retlw .8

      retlw .16

      retlw .32

      retlw .64

      retlw .128                   

      retlw .255

hofinito

      clrwdt

      goto  hofinito

      end

- Indietro

- Home page