Vai al contenuto
PLC Forum


Programmino Per Pic16f84a - non capisco


Agamennone_Ares

Messaggi consigliati

Agamennone_Ares

Buongiorno, mi sono appena iscritto a questo bel forum e vorrei approfittare, se possibile, della vostra esperienza per quanto riguarda un problema che ho con un programmino in asm per il pic 16f84a.

Premetto che sono un principiante ed ho iniziato solo da alcuni giorni.

Posso allegareil sorgente in modo tale che vi espongo meglio il problema?

In pratica, il programma genera un segnale su un'iscita alla quale è collegato un buzzer. Il segnale è generato con l'unico timer a disposizione pilotato dal clock interno/4 (quarzo 4M) e caricando in esso il valore 080H tramite una variabile chiamata SUONO.

Allo scadere del timer, viene richiamato l'interrupt e viene invertito lo stato dell'uscita alla quale è collegato il buzzer.

Con un pulsante collegato all'input Ra4, con un MOVF carico un valore diverso nella variabile suono: MOVF Step,SUONO

Quindi, quando il pulsante non è premuto, nella variabile SUONO c'è 080h mentre premendo il pulsante, il valore in SUONO dovrebbe cambiare da 080h a 0b9h che è il valore contenuto in Step.

Succede però che ogni volta che premo il pulsante la frequenza non è mai la stessa, ma aumenta ad ogni pressione del pulsante.

E qui mi sono arenato perchè vorrei capire cosa va a modificare il valore di step o di SUONO.

Il sorgente è piccolo, quindi se posso allegarlo sarà più facile anche per voi capire e vedere quello che ho fatto. Tra l'altro sono partito da un sorgente di esempio chiamato demo4 della demoboard per il 16f84 pubblicata su elettronica in del 2004.

Grazie a tutti per l'attenzione.

Ciao da Aga.

Link al commento
Condividi su altri siti


Ciao e ben venuto!

E' proprio vero, se non si vede il sorgente è difficile darti una mano.

Secondo me, se non è troppo lungo, puoi pubblicarlo....

Link al commento
Condividi su altri siti

Agamennone_Ares

Ciao dott.cicala, ho iniziato questo lunedì con i pic, anzi con il 16f84 (già obsoleto) poi se riesco vorrei proseguire.....per il momento.......Siate buoni e pazienti

Ecco il sorgente:

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

;*** PROGRAMMA PER GENERARE UN SUONO CON IL BUZZER

;*** E COMANDARE 2 RELE (MONOSTABILE) CON I PULSANTI

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

list p=16f84, f=inhx8m

__CONFIG 3FF1h ;configura WD - Xt - prwte - cp

PORT_A EQU 05H ;Porta A = registro 05

PORT_B EQU 06H ;Porta B = registro 06h

TMR0 EQU 01H ;Registro del timer = 01h

COUNT_1 EQU 0CH ;Contatore

COUNT_2 EQU 0DH ;Contatore

PIC84 EQU 03FFH ;Vettore di reset per PIC 84

STATUS EQU 03H ;registro STATUS

INTCON EQU 0BH ;registro INTCON - interrupts config

OPT EQU 01H ;registro Option

SUONO EQU 0FH

#define T0IF INTCON,2

#define T0IE INTCON,5

#define GIE INTCON,7

#define RP0 STATUS,5

#define PS0 OPT,0

#define PS1 OPT,1

#define PS2 OPT,2

#define PSA OPT,3

#define T0CS OPT,5

#define Step 0B9H ;costante SUONO

#define Buzzer PORT_A,0 ;uscita cicalino

#define LED PORT_B,0 ;uscita cicalino

#define Pulsante1 PORT_A,4 ;Pulsante 1 su porta RA4

#define Pulsante2 PORT_A,3 ;Pulsante 2 su porta RA3

#define K1 PORT_A,2 ;Relè 1 su porta RA2

#define K2 PORT_A,1 ;Relè 2 su porta RA1

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

;Rotuine di risposta interrupt

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

INT ORG 04H ;Locazione di destinazione interrupt

MOVF Buzzer ;cicalino

XORLW 01H ;Complementa il bit relativo al buzzer

MOVWF PORT_A ;Porta RbA

MOVLW SUONO ;costante SUONO

MOVWF TMR0 ;Carica il timer con la costante SUONO

BCF T0IF ;Abilita interrupt di TMR0

BSF GIE ;Abilitazione globale interrupt

RETFIE ;Ritorna a Main

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

;Inizializzazioni

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

INIT ORG 0050H

BSF RP0 ;STATUS BIT5: Seleziona banco1

BCF T0CS ;OPTION BIT5: Modalità timer

BCF PSA ;OPTION BIT3: Prescaler al timer

BSF PS0 ;OPTION BIT0: Prescaler

BSF PS1 ;OPTION BIT1: Prescaler

BSF PS2 ;OPTION BIT2: Prescaler

BCF RP0 ;STATUS BIT5: Seleziona banco0

BSF T0IE ;INTCON BIT5: Abilitato interrupt da overflow timer

MOVLW SUONO ;Carica in W costante SUONO

MOVWF TMR0 ;Configura il timer con W

MOVLW 00H

TRIS PORT_B ;Configura la porta b

MOVLW 0F8H

TRIS PORT_A ;Configura la porta a

BSF GIE ;Abilita le interrupt

MOVLW 080H

MOVWF SUONO

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

;Programma principale

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

MAIN BTFSS Pulsante1

GOTO UPF

BTFSS Pulsante2

BSF K1

BTFSC Pulsante1

BCF K2

BTFSC Pulsante2

BCF K1

NOP

GOTO MAIN

UPF BSF K2

MOVF Step,SUONO ;MOVF R,D . D = R

RETURN

ORG PIC84

GOTO INIT ;Vai a INIT

GOTO MAIN

END

Link al commento
Condividi su altri siti

Allora, se ho capito bene, quando non premi Pulsante1, la "frequenza" è sempre la stessa, se invece premi il pulsante e quindi il progr va a UPS ogni volta hai una frequenza diversa che aumenta ad ogni nuova pressione....

E' questo il tuo problema?

Link al commento
Condividi su altri siti

Agamennone_Ares

Come avrai capito i pulsanti sono attivi bassi.

La frequenza che viene generata a pulsante premuto è di volta in volta sempre diversa, invece TMR0 dovrebbe venir caricato con il valore di SUONO che a sua volta e caricato con il valore contenuto in Step.

A pulsante non premuto la frequenza è sempre quella data dal valore 080H caricata in SUONO.

Come mai?

Va azzerato TMR0 prima di poter cambiare il suo valore?

Sembra che premendo il pulsante TMR0 sia caricato da step+il valore attuale di TMR0...

Link al commento
Condividi su altri siti

Dammi tempo, ho bisogno di rimettere un po' in ordine il sorgente per leggerlo meglio....e inoltre non sono ferratissimo con i pic.

Link al commento
Condividi su altri siti

Agamennone_Ares

Sì, certo, non c'è problema, figurati.

L'obbiettivo del progettino sarebbe quello di generare una frequenza che possa essere variata con due pulsanti.

Premendo P1 dovrebbe aumentare, premendo P2 dovrebbe diminuire.

Inoltre ad ogni pulsante premuto corrisponde l'eccitazione di un relè.

Al momento, volevo solo far generare 2 frequenze distinte e poi, risolto il problema che si è inaspettatamente presentato, passare a fare la variazione di frequenza +/-.

Accettasi critiche, rimproveri e suggerimenti.....

Link al commento
Condividi su altri siti

Rimproveri e critiche no, per il momento non ho suggerimenti da darti.

Se hai iniziato lunedì(ieri?) sei già avanti e prometti bene....

Link al commento
Condividi su altri siti

Agamennone_Ares

No, non ieri, ma la settimana scorsa biggrin.gif ....ci ho messo una settimana per riuscire a configurare, trasferire, leggere, settare qualche bit, accendere qualche led...ecc ecc.....passo per passo.

Ho anche scaricato moltissimi tutorial, pic by example, e molti molti molti altri.

La demoboard, il programmatore ponyprog2000 li avevo comprati nel 2004 ma non mi ero mai messo all'opera.

Link al commento
Condividi su altri siti

L'istruzione

MOVF Step,SUONO ;MOVF R,D . D = R

sposta il contenuto del registro Step in W se SUONO vale zero, in Step se SUONO vale 1 e quindi non fa quello che vuoi tu. Giusto?

Ciao.

Link al commento
Condividi su altri siti

Agamennone_Ares

ciao giacomo,

purtroppo non è così.

Dal manuale "programmazione del micro 16f84" di microchip,

l'istruzione MOVFè spiegata così:

MOVF R,D

Assegna a D il contenuto di R.

Flag modificati dopo la sua esecuzione:

• Z = 1 se R = 0.

(Z è il bit2 del registro STATUS ed è messo a 1 quando un'operazione Aritmetica o logica da come risultato=0)

.....quindi in SUONO dovrebbe esserci Step.

Step ha un valore fisso e definito da #define Step 09BH: è una costante.

Invece ogni volta che viene premuto Pulsante1 il buzzer emette una frequenza sempre diversa.

Sto studiando il problema nel poco tempo che ho durante la notte (con mia moglie che stressa perchè il buzzer rompe le scatole....)

Modificato: da Agamennone_Ares
Link al commento
Condividi su altri siti

MOVF R,D

come dici tu assegna a D il contenuto di R, dove R è l'indirizzo del registro non il contenuto. D può essere o il registro W (D=0) o lo stesso registro R (D=1).

Non c'è l'istruzione che permette di caricare in un registro qualunque una costante devi passare sempre per W in questo modo:

movlw Step

movwf SUONO

Se puoi metti un led momentaneamente al posto del buzzer!

Ciao.

Link al commento
Condividi su altri siti

Agamennone_Ares

Ciao giacomo,

grazie x la delucidazione del movf: avevo qualche dubbio.

comunque ho sostituito le istruzioni con movlw-movwf come mi hai suggerito.

Ho fatto alcune modifiche, ho eliminato il return inutile, non ho sostituito il buzzer col led, altrimenti non posso sentire la variazione di frequenza.

Non ho ancora raggiunto l'obbiettivo, ma almeno adesso, premendo un pulsante viene emessa una frequenza.

Mi sto rileggendo come va gestito il TMR0: mi sa che non posso cambiare il valore al volo.

Adesso il sorgente è cosi (ma suona solo premendo il P2 !!) e su portb ho collegato 8 led per vedere quale valore viene trasferito su suono.

In pratica, quando premo, disabilito il timer, l'interrupt e cambio il valore di tmr0, poi riabilito il tutto.

Però mi piacerebbe anche capire perchè col sorgente iniziale, ad ogni pressione del pulsante veniva emessa una frequenza sempre diversa.

Ci sono ancora molti interrogativi ai quali dovrò dare una risposta esatta.

Ulteriore difficoltà è che col 16f84 non si può fare icd, ma non sono ancora attrezzato per altro. Così a ogni modifica devo togliere l'ic dalla demoboard e metterlo sul programmatore e viceversa. Dovrei vedere se posso simularlo.

Ecco il supersorgente.....

list p=16f84, f=inhx8m

__CONFIG 3FF1h ;configura WD - Xt - prwte - cp

TMR0 EQU 01H ;Registro del timer = 01h

STATUS EQU 03H ;registro STATUS

PORT_A EQU 05H ;Porta A = registro 05

PORT_B EQU 06H ;Porta B = registro 06h

INTCON EQU 0BH ;registro INTCON - interrupts config

COUNT_1 EQU 0CH ;Contatore

COUNT_2 EQU 0DH ;Contatore

OPT EQU 01H ;registro Option

PIC84 EQU 03FFH ;Vettore di reset per PIC 84

SUONO EQU 00H

Step EQU 05BH ;costante SUONO

#define T0IF INTCON,2

#define T0IE INTCON,5

#define GIE INTCON,7

#define RP0 STATUS,5 ;Register Bank Select bits

#define PS0 OPT,0 ;Prescaler Rate Select bit0

#define PS1 OPT,1 ;Prescaler Rate Select bit1

#define PS2 OPT,2 ;Prescaler Rate Select bit2

#define PSA OPT,3 ;Prescaler Assignment =0 TMR0 - 1=WDT

#define T0CS OPT,5 ;Clock Source Select bit: 0 = Internal clock

#define Buzzer PORT_A,0 ;uscita cicalino

#define Pulsante1 PORT_A,4 ;Pulsante 1 su porta RA4

#define Pulsante2 PORT_A,3 ;Pulsante 2 su porta RA3

#define K1 PORT_A,2 ;Relè 1 su porta RA2

#define K2 PORT_A,1 ;Relè 2 su porta RA1

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

;Inizializzazioni

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

INIT ORG 050H

BSF RP0

BCF T0CS

BCF PSA

BSF PS0

BCF PS1

BSF PS2

BSF T0IE

BCF RP0

MOVLW 0B0H

MOVWF SUONO

MOVWF TMR0

MOVLW 0F8H

TRIS PORT_A

MOVLW 00H

TRIS PORT_B

BSF GIE

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

;Programma principale

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

MAIN BTFSS Pulsante1

GOTO UPF

BCF K1

BTFSS Pulsante2

GOTO DWN

BCF K2

GOTO MAIN

UPF BSF K1

BSF RP0

BCF T0IE

BCF GIE

MOVLW 0AAH

MOVWF SUONO

MOVWF TMR0

MOVWF PORT_B

BSF T0IE

BSF GIE

BCF RP0

GOTO MAIN

DWN BSF K2

BSF RP0

BCF T0IE

BCF GIE

MOVLW 00AH

MOVWF SUONO

MOVWF TMR0

MOVWF PORT_B

BSF T0IE

BSF GIE

BCF RP0

GOTO MAIN

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

;Rotuine di risposta interrupt

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

INT ORG 04H

MOVF Buzzer

XORLW 01H

MOVWF PORT_A

MOVLW SUONO

MOVWF TMR0

BCF T0IF

BSF GIE

RETFIE

ORG PIC84

GOTO INIT

END

Modificato: da Agamennone_Ares
Link al commento
Condividi su altri siti

Agamennone_Ares

If the TMR0 register is written, the increment is

inhibited for the following two instruction cycles. The

user can work around this by writing an adjusted value

to the TMR0 register.

Link al commento
Condividi su altri siti

Allora, ho debuggato un pò il tuo codice, certo che più incasinato non si poteva, anche se devo dire che per un principiante non te la sei cavata poi maluccio rolleyes.gif ...

Ora viene il bello:

1) Il prescaler non funziona...

2) La selezione dei banchi è messa a caso...

3) Il buzzer suona sempre e rompe...

4) Non esiste nessuna routine di delay per la pressione dei pulsanti...

5) Ci sono troppe istruzioni inutili e mancano quelle corrette...

6) Se vuoi utilizzare il RETURN devi utilizzare la CALL e non il GOTO

7) Etc. etc...

Per comprendere meglio la selezione dei banchi ed altro ancora devi sbirciare nel file PIC16F84A.INC dove è tutto spiegato, ti evitavi un sacco di codice aggiungendolo nell'intestazione tipo #include "PIC16F84A.INC", inoltre l'utilizzo di MACRO agli inizi complica la lettura e la comprensione del codice, quella roba è per i professionisti, io ti consiglio di utilizzare il linguaggio standard, almeno chi ti dovrebbe aiutare non deve prima interpretare il linguaggio criptico, altresì ti renderai conto della semplicità, qualcuno lo ha studiato per benino prima di te...

Anche le ORG sono lasciano a desiderare come la sequenza delle routine, esiste un metodo corretto per agevolare la stesura del codice, tu lo hai praticamente invertito, il resto lo lascio sperimentare a te, io la soluzione l'ho trovata e simulata, ma ora non ho il tempo per scriverla con tanto di spiegazioni, magari tra qualche giorno, non vorrei tolglierti il divertimento, ti dico solamente che se aggiusti il prescaler sei già sulla buona strada...

OPTION_REG  EQU  H'0081'

    MOVLW   0x02           ; Prescaler on, internal clocking, divide by 4            
    MOVWF   OPTION_REG

P.S. Che compilatore usi???

Link al commento
Condividi su altri siti

Agamennone_Ares

list p=16f84, f=inhx8m

__CONFIG 3FF1h ;configura WD - Xt - prwte - cp

TMR0 EQU 001H ;Registro del timer = 01h

STATUS EQU 003H ;registro STATUS

PORT_A EQU 005H ;Porta A = registro 05

PORT_B EQU 006H ;Porta B = registro 06h

INTCON EQU 00BH ;registro INTCON - interrupts config

COUNT_1 EQU 00CH ;Contatore

COUNT_2 EQU 00DH ;Contatore

COUNT_3 EQU 00EH ;Contatore

OPT EQU 001H ;registro Option

PIC84 EQU 03FFH ;Vettore di reset per PIC 84

SUONO EQU 000H ;Valore TMR0

Step1 EQU 0B9H ;costante SUONO1

Step2 EQU 0FCH ;costante SUONO2

#define T0IF INTCON,2

#define T0IE INTCON,5

#define GIE INTCON,7

#define RP0 STATUS,5

#define PS0 OPT,0

#define PS1 OPT,1

#define PS2 OPT,2

#define PSA OPT,3

#define T0CS OPT,5

#define Buzzer PORT_A,0

#define Pulsante1 PORT_A,4

#define Pulsante2 PORT_A,3

#define K1 PORT_A,2

#define K2 PORT_A,1

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

;Inizializzazioni

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

INIT ORG 050H

BSF RP0

BCF T0CS ;OPTION BIT5: Modalità timer

BCF PSA ;OPTION BIT3: Prescaler al timer

BSF PS0 ;OPTION BIT0: Prescaler

BSF PS1 ;OPTION BIT1: Prescaler

BSF PS2 ;OPTION BIT2: Prescaler

BSF T0IE ;INTCON BIT5: Abilitato interrupt da overflow timer

BCF RP0 ;STATUS BIT5: Seleziona mem. banco0

MOVLW 025H

MOVLW SUONO

MOVWF TMR0

MOVLW 0F8H

TRIS PORT_A ;Configura la porta a

MOVLW 000H

TRIS PORT_B ;Configura la porta b

BCF GIE ;Abilita le interrupt

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

;Programma principale

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

MAIN CLRWDT

BTFSS Pulsante1

GOTO UK1

BTFSC Pulsante1

BCF K1

BTFSS Pulsante2

GOTO UK2

BTFSC Pulsante2

BCF K2

GOTO MAIN

UK1 BSF K1

BSF GIE

CALL DELAY

BCF GIE

GOTO MAIN

UK2 BSF K2

BSF GIE

CALL DELAY

BCF GIE

GOTO MAIN

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

;Rotuine di ritardo

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

DELAY DECFSZ COUNT_1,1

GOTO DELAY

MOVLW 0FF

MOVWF COUNT_1

DECFSZ COUNT_2,1

GOTO DELAY

MOVLW 04F

MOVWF COUNT_1

MOVLW 03F

MOVWF COUNT_2

DECFSZ COUNT_3,1

GOTO DELAY

MOVLW 03F

MOVWF COUNT_1

MOVLW 03F

MOVWF COUNT_2

MOVLW 03F

MOVWF COUNT_3

RETURN

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

;Rotuine di risposta interrupt

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

INT ORG 004H

MOVF Buzzer

XORLW 001H

MOVWF PORT_A

BTFSS Pulsante1

MOVLW Step1

BTFSS Pulsante2

MOVLW Step2

MOVWF SUONO

MOVWF PORT_B

MOVWF TMR0

BCF T0IF

BSF GIE

RETFIE

ORG PIC84

GOTO INIT

END

Link al commento
Condividi su altri siti

Agamennone_Ares

Ciao GiRock,

uso mpsam 5.42 integrato in mplab ide 8.76.

Sopra c'è il sorgente funzionante così come lo volevo.

il prescaler è impostato tramite i bit ps0-ps1-ps2 che ho definito così:

#define PS0 OPT,0 ;Prescaler Rate Select bit0

#define PS1 OPT,1 ;Prescaler Rate Select bit1

#define PS2 OPT,2 ;Prescaler Rate Select bit2

nell'inizializzazione imposto i bit in base al rate che mi serve

l'accesso al banco 0 o al banco 1 l'ho definito così:

#define RP0 STATUS,5 ;Register Bank Select bits

Nell'inizializzazione seleziono il banco al quale devo accedere.

la routine DELAY l'ho aggiunta ieri sera, ma potevo anche farne a meno....

le istruzioni inutili le ho eliminate....dopo aver capito quali fossero.

il return l'ho tolto perchè non ho usato nessuna call.

Usare i #define, mi ha permesso di capire meglio cosa stavo facendo....

Le ORG....ecco, lì ho ancora dei dubbi.

PS: nel sorgente sopra il __config è sbagliato. in realtà il WD è attivo, ma alla fine non cambia niente....ogni tanto bisogna fare un bel CLRWDT

Modificato: da Agamennone_Ares
Link al commento
Condividi su altri siti

Agamennone_Ares

Mi sto lambiccando il cervello........ma cos'hanno di sbagliato le ORG?

ORG PIC84 dovrebbe essere ok perchè punta a 3FF cioè da dove parte all'accensione....(o no?)

ORG 04H è giusta perchè è dove va in caso di interrupt. (sicuro)

ORG 50H....l'ho presa un po' larga....

non capisco cos' abbiano di sbagliato.

"metodo corretto per agevolare la stesura"....

Qual'è? Dove posso trovare info?

Non vanno bene i seguenti testi "sacri":

"Processo di sviluppo di un'applicazione software"

oppure

"Ingegneria del software"?

Non va bene il metodo per lo sviluppo di programmi PLC

in linguaggio IL-SCL-C/C++?

Ho trovato anche un Ladder, ma vorrei impratichirmi con l'assembly del PIC,

non usare il Ladder e, conosciuta la struttura PIC, passare al C....

...in un mese max. rolleyes.gif

Link al commento
Condividi su altri siti

Se non erro il restart sul power on e sul reset è 0000.

Domandina banale. Lo hai letto il manuale del pic16f84?

Link al commento
Condividi su altri siti

Agamennone_Ares

Mi sembrava di aver capito che all'accensione il 16f84 non va a 000 ma si posiziona a 3ff, da lì bisogna inserire un salto a dove inizia il programma, nel mio caso 50h.

Sì li ho letti i manuali, continuo a rileggerli. Li leggo sempre i manuali....non leggo altro.

In ogni caso, sarà un caso, ma il sorgentino funziona proprio come volevo.

Ho anche capito il perchè della frequanza diversa ad ogni pressione del pulsante nell'esempio iniziale....

....principiante non è sinonimo di idiota....

volevo solo scambiare qualche idea con persone più esperte....

ma sssìììììì......

grazie a tutti

Link al commento
Condividi su altri siti

laugh.gif

Calma!

Ho cercato la demoboard alla quale ti riferisci, si trova qui

http://www.futurashop.it/index.html

cercando FT215 si può anche scaricare il sw.

All'interno dello zip c'è Demo4 dal quale sei partito.

Ora, il risultato che volevi l'hai ottenuto. Mi sembra sia nata una disputa sul vettore di reset.....in demo4 c'è proprio questo:

PIC84 EQU 03FF ;Vettore di reset per PIC 84

però io non ho la rivista con l'articolo.

Leggendo i vari manuali invece il vettore di reset è a 000.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...