Jump to content
PLC Forum


Sign in to follow this  
Eduardo Cassisi

Suono Buzzer

Recommended Posts

Eduardo Cassisi

Salve, a tutti sono nuovo del forum è la prima volta che posto qualcosa in quanto avrei bisogno di un grosso aiuto da parte vostra, in quanto è un esame il 17 di questo mese e sono agli sgoccioli.

Dovrei scrivere un programma in assembler per il pic 16f887 ma non so dove mettere le mani.

Il programma da scrivere è il seguente :

Si realizzi un programma che conti quante volte l utente preme un pulsante,terminando il conteggio quanto un time-out di 1 s trascorre senza che sia premuto il tasto,quindi emetta brevi suoni con il buzzer, con n pari al numero di pressioni di contatto.

Il problema è che il buzzer suona di continuo, premo il reset e premo il pulsante e suona tante volte quante volte ho premuto il tasto, però se non lo premo più suona continua a suonaredi continuo...come faccioa risolverlo?
Spero in un vostro aiuto

Grazie

Metto in allegato il codice in assembly

list p=16f887 ; direttiva che definisce il tipo di processore

#include <P16F887.INC> ; file che contiene le definizioni dei simboli

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

; ******CONFIGURATION BIT********

__CONFIG _CONFIG1, _INTRC_OSC_NOCLKOUT & _CP_OFF & _WDT_OFF & _BOR_OFF & _PWRTE_OFF & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

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

; ******** DEFINIZIONE COSTANTI*********

; Costanti con cui settare il contatore del timer per contare un determinato intervallo di tempo.

tmr_50ms EQU (.259 - .195)

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

; *** Definizione variabili ***

; La direttiva UDATA_SHR (uninitialized data shared) dichiara una sezione di dati

; da allocare in RAM, e precisamente nella sezione di RAM comune a tutti

; i banchi, in modo da poter accedere ai dati indipendentemente dal banco

; impostato.

udata_shr

counter RES 1 ; riserva un byte di memoria associato alla label counter (= contatore)

oscil RES 1 ; BYTE PER FAR OSCILLARE IL BUZZER

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

; *** Vettore di reset ***

; Il vettore di reset è l'istruzione che viene eseguita per prima

; dopo un reset del microcontrollore.

; La direttiva CODE dichiara una sezione di codice da allocare in ROM.

; Viene specificato esplicitamente l'indirizzo 0000, in quanto il

; vettore di reset deve trovarsi in questa posizione (codice non rilocabile).

; La label non è necessaria, ma è utilizzata per chiarezza del codice.

RST_VECTOR CODE 0x0000

pagesel start ; imposta la pagina della memoria di programma in cui si trova

;l'indirizzo della label start

goto start ; salta all'indirizzo indicato dalla label start

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

; *** Programma principale ***

; La direttiva CODE dichiara una sezione di codice da allocare in ROM.

; Non viene specificato un indirizzo esplicito, il linker successivamente

; assegnerà un indirizzo assoluto di inizio per la sezione (codice rilocabile)

MAIN CODE

start ; N.B: l'assembler non accetta una label sulla

;stessa riga di una direttiva

; inizializzazione hardware

pagesel INIT_HW ; direttiva che imposta la pagina della memoria

;di programma in cui risiede la subroutine INIT_HW

call INIT_HW ; chiamata alla subroutine indicata dalla label INIT_HW

banksel PORTD

clrf PORTD

clrf counter

; loop principale

main_loop ; N.B: l'assembler non accetta una label su una direttiva

movlw 0x80

banksel TMR1H

movwf TMR1H

banksel PIR1

bcf PIR1,TMR1IF

; loop di attesa pressione pulsante

banksel PORTB ; banco di PORTB

wait_press clrwdt ; azzera timer watchdog per evitare reset

btfss PORTB,0 ; se il bit 0 della porta B è = 0 (pulsante premuto) salta l'istruzione seguente

goto premuto ; ripete il loop

; pulsante premuto: debounce e inizio conteggio di 1 s per determinare pressione successiva

banksel PIR1

btfsc PIR1,TMR1IF

goto buzzer

goto wait_press

; periodo timer scaduto (1s)

premuto

pagesel DELAY

movlw tmr_50ms

call DELAY ; *** provare a commentare la chiamata a subroutine DELAY per evitare il debouncing ***

; loop di attesa rilascio pulsante

banksel PORTB ; banco di PORTB

asp_press clrwdt ; azzera timer watchdog per evitare reset

btfss PORTB,0 ; se il bit 0 della porta B è = 1 (pulsante rilasciato) salta l'istruzione seguente

goto asp_press ; ripete il loop

; pulsante rilasciato: attesa debouncing e ripetizione loop principale

pagesel DELAY ; imposta la pagina della memoria di programma in cui risiede la subroutine DELAY

; carica in W la costante (precedentemente definita) per la misura di 10 ms

movlw tmr_50ms

call DELAY ; *** provare a commentare la chiamata a subroutine DELAY per evitare il debouncing ***

incfsz counter,f ; incrementa counter

goto main_loop

buzzer

banksel PORTD

bsf PORTD,0

loop_buzzer

call beep

movlw tmr_50ms

call DELAY

decfsz counter

goto loop_buzzer

goto main_loop

beep

movlw .200

movwf oscil

beep1

movlw B'00000100' ; carico il valore binario in W

banksel PORTC

xorwf PORTC,f ; inversione del bit

movlw .253

call DELAY

decfsz oscil,f

goto beep1

return

; *** Subroutine DELAY: attesa di un tempo selezionabile ***

; nel registro W viene passato il valore da impostare come contatore iniziale del timer.

DELAY

; Utilizzo del timer in polling: settare il contatore al valore iniziale voluto,

; azzerare il flag e attendere tramite un loop che il flag venga settato di nuovo.

banksel TMR0

movwf TMR0 ; copia W in TMR0 (contatore del timer)

bcf INTCON,T0IF ; azzera il flag di overflow di TMR0

wait_delay clrwdt ; azzera timer watchdog per evitare reset

btfss INTCON,T0IF ; se il flag di overflow del timer è = 1, salta l'istruzione seguente

goto wait_delay ; ripeti il loop di attesa

return ; uscita da subroutine e ritorno al punto del codice in cui era stata chiamata

INIT_HW

; registro OPTION_REG:

; - pull-up porta B abilitati.

; - TMR0 incrementato da clock interno (1 MHz)

; - prescaler assegnato a TMR0

; - valore prescaler 1:256 (clock TMR0 = 3.90625 kHz)

; Le impostazioni precedenti determinano per TMR0 i seguenti valori:

; - periodo di un singolo incremento (tick) = 256 us

; - periodo totale (da 00 a FF) = 65.536 ms

banksel OPTION_REG ; banco di OPTION_REG

movlw B'00000111' ; carica costante binaria 00000110 in W

movwf OPTION_REG ; copia W (11000110b) in OPTION_REG

; registro INTCON:

; - tutti gli interrupt disabilitati

clrf INTCON ; INTCON = 0

; Porte I/O:

; - porte A,C,B,E settate come input digitali per tutti i pin,

; tranne RA0 settato come input analogico

; - porta D: pin 0..3 settati come output (LED), pin 4..7 come input

banksel TRISA ; banco di TRISA, stesso banco anche per gli altri registri TRISx

movlw 0xFF ; carica costante FF in W

movwf TRISA ; copia W (FF) in TRISA

movwf TRISB ; copia W (FF) in TRISB

movwf TRISE ; copia W (FF) in TRISE

movlw 0xF0 ; carica costante F0 in W

movwf TRISD ; copia W (F0) in TRISD

movlw B'11111011' ;

movwf TRISC ;

; Di default, tutti i pin connessi all'ADC sono settati come input analogici,

; impedendone l'uso come I/O digitali. L'impostazione seguente rende I/O digitali

; i pin RB0..RB3

banksel ANSELH ; banco di ANSELH

clrf ANSELH ; AN8..AN13 disattivati

movlw B'00001011'

banksel T1CON

movwf T1CON

return

end

user_offline.gif

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...