problemi di codice con 16F88

I

IMSlo

Guest
Qualcuno può dirmi perché il codice allegato non viene eseguito su un PIC 16f88.Questo è un tempo trascorso timer semplice in esecuzione su un timer0 interrompere e visualizzare l'ora su un X 2 16 LCD.Ho scaricato il codice da luoghi diversi e metterli insieme.Con le necessarie modifiche minori il codice verrà eseguito per giorni su un 16f627a.Al 88 verrà eseguito pochi secondi, zero fino eseguire alcuni secondi, fino allo zero e magari anche per pochi minuti e zero su.Con il tempo si chiude a volte con il display che mostra numeri e di nuovo con lo schermo vuoto.Sono al mio spirito di fine.Si prega di ignorare i commenti perché può o non può essere giusto.Qualsiasi aiuto sarebbe apprezzato.

;************************************************* *****************************
; ZERO-ONE ERROR secondo timer
; (Roman Black 2001, di dominio pubblico, usarlo come volete)
;

;
;************************************************* *****************************;================================================= =============================
; Processore definita;
p = 16F88 LIST; assembler raccontare quello che stiamo utilizzando chip
include "P16F88.inc", comprendono i valori di default per il chip
ERRORLEVEL 0, -302; sopprimere i messaggi di selezione banca;================================================= =============================
; MPLAB roba qui

ELENCO b = 5, n = 97, t = ON, st = OFF
; Schede annuncio assoluto = 5, linee = 97, assetto lunghe code = ON, simbolo tavolo = OFF

__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 _DEBUG_OFF & & & _WRT_PROTECT_OFF _CPD_OFF _LVP_OFF & & & _BODEN_OFF _MCLR_OFF _PWRTE_ON & & & _WDT_OFF _INTRC_IO

; Programma di configurazione Registra 2
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

LCD_PORT Equ PORTB
LCD_TRIS Equ TRISB
LCD_RS Equ 0x04; linee di handshake LCD
LCD_RW Equ 0x06
LCD_E Equ 0x07;================================================= =============================
; Variabili qui

CBLOCK 0x20
secondo
sec10
min
min10
hr
HR10
bres_hi; byte hi della nostra variabile 24bit
bres_mid; byte metà
bres_lo; lo byte
; (Abbiamo solo bisogno di 3 byte per questo sistema)

status_temp; utilizzato per interrompere la manutenzione
w_temp; utilizzato per interrompere la manutenzione
templcd; negozio temp per la modalità a 4 bit
templcd2
conte, utilizzati in routine looping
count1; utilizzati in ritardo di routine
CONTA.VALORI; utilizzati in ritardo di routine
countb; utilizzati in ritardo di routine
oldtime
EndC;================================================= =============================
; Codice qui

org 0x000; set base in memoria di programma vettoriale reset 0x000
reset
setup goto; istituire int e porto roba

org 0x004; vettore di interrupt, codice del gestore int viene dopo.
;================================================= =============================

;************************************************* *****************************
; Gestore di interrupt (questo codice viene eseguito ogni timer0 interrupt)
;************************************************* *****************************
;
;------------------
int_handler
;
;------------------

;-------------------------------------------------
Non abbiamo preservare w prima e registro di stato

w_temp movwf; salvare i contenuti di corrente registro W
movf STATUS, w; registro spostare W in stato di registro
status_temp movwf; salvare off contenuto del registro di stato

;-------------------------------------------------
; Nota!siamo arrivati qui ogni 256 istruzioni, abbiamo
; Può ora fare del nostro speciale calendario secondo sistema.

; Questo si compone di tre fasi principali;
; * Sottrarre 256 titoli dal nostro variabile 24bit
; Test *, se avessimo raggiunto il setpoint
; * In caso affermativo, aggiungere 1.000.000 risiedono a 24bit variabile e generare eventi.
;-------------------------------------------------
; * Ottimizzato a 24 bit sottrarre qui
E ciò si realizza con le istruzioni minime.
; Sottraiamo 256 dalla variabile 24bit
; Decremento di appena il byte metà.

tstf bres_mid, primo test per la metà == 0
skpnz; nz = no underflow necessari
decf bres_hi, f, z, è così underflow, in modo da dicembre il MSB

decfsz bres_mid, f; metà dicembre il byte (sottrarre 256)

, Ora la 24bit completo ottimizzato sottrarre è fatto!
, Questo è circa 4 volte più veloce di un "proprio"
; Sottrarre 24bit.

goto int_exit, NZ, sicuramente non così uno secondo ancora.
, Nella maggior parte dei casi il tutto si int
; Solo 16 istruzioni.
;------------------------
; Test * se abbiamo raggiunto un secondo.
; Ottiene solo qui, quando a metà == 0, può essere un secondo.
; Viene qui solo per 1 ogni 256 volte.
, (Questo è il nostro miglior test ottimizzato)
, Si arriva qui quando bres_mid == 0.

tstf bres_hi; test HI per zero troppo
skpz; sia z = hi e medie sono pari a zero, è un secondo!
goto int_exit; nz, quindi non uno secondo ancora.

;-------------------------------------------------
; Ottiene solo di qui, se abbiamo raggiunto un secondo.

, Ora siamo in grado di generare il nostro unico secondo evento, come aggiungere
, Un secondo per il nostro orologio o altro.
, (In questo esempio alternare un led)

; L'altra cosa che dobbiamo fare è aggiungere 1.000.000 conteggi
; Alla nostra variabile a 24bit e ricominciare tutto daccapo.
;-------------------------------------------------
, Aggiungere la conta 1.000.000 per primo.
; Un secondo = 1.000.000 = 0F 42 40 (in esadecimale)

; Come sappiamo hi 0 == == 0 e la metà questo lo rende molto veloce.
; Questo è un 24bit ottimizzato aggiungere, perché possiamo
: Basta caricare i due byte e solo bisogno di fare
, Un componente aggiuntivo di byte reale sul fondo.Questo è molto più veloce
; Di una "propria" 24bit aggiungere.

Movlw 0x0F; ottenere il valore MSB
movwf bres_hi; carico in msb

Movlw 0x42; ottenere il valore medio
bres_mid movwf; carico a metà

Movlw 0x40; valore LSB da aggiungere
addwf bres_lo, f; aggiungerlo al resto già in LSB
skpnc; nc = non troppo pieno, così la metà è ancora ok

incf bres_mid, f, c, in modo LSB inondato, così a metà inc
, Questo è ottimizzato e si basa sulla media di essere conosciuto
E che la metà non traboccare da un inc.

, Che è tutto!Il nostro 24bit ottimizzato aggiungere è fatto,
, Questo è circa due volte più veloce come una "corretta"
; 24bit aggiungere.
;-------------------------
, Ora facciamo l '"evento" che noi facciamo tutti un secondo.

; Nota!Per questo esempio passare un led, che
; Darà un LED lampeggiante che si trova per un secondo
, E fuori per un secondo.
, Aggiungere il proprio codice per il tuo un evento secondo.

; Nota!La mia porta è acceso il led, 3
, La tua può essere portato su un perno differenti.
; Movlw b'00001000 '; maschera di bit 3
; PORTB xorwf, f; alternare PORTA, bit3 (acceso / spento il led)

movlw sec; punto a registro sec
movwf FSR
newdigit: incf INDF, f; attuale cifra su di un
movlw sec; differenza tra arrivare secondi e FSR
subwf FSR, W
Sethi chiamata; usare per ottenere limite superiore 1
subwf INDF, W; raggiunto tale numero ancora?
Btfss STATUS, Z; saltare se sì
goto int_exit; ISR uscita altro
clrf INDF; set cifra corrente a 0
incf FSR, F; punto in cifra successiva
newdigit goto, no, incrementare la cifra successiva;-------------------------------------------------
, Ora il nostro unico secondo evento è tutto fatto, si può uscire dal
; Gestore di interrupt.
;-------------------------------------------------
E infine abbiamo ripristinare w e registri di stato.
; Cancella anche bandiera int TMRO ora siamo finiti.
int_exit
BCF INTCON, 2; reimpostare il flag di interrupt TMR0
bcf STATUS, Z
status_temp movf, w; recuperare copia del registro di stato
STATUS movwf; ripristinare pre-isr STATUS registrare contenuti
swapf w_temp, f
w_temp swapf, w, il ripristino della pre-isr registro contenuto W

retfie; ritorno da interrupt

;------------------------------------------------- -----------------------------
;------------------------------------------------- ------------------------;
; Alta limite 1 di cifre in posizione W;
;------------------------------------------------- ------------------------;
Sethi:
addwf PCL, f
dt H'A ', H'6', H'A ', H'6', H'A ', H'A';************************************************* *****************************
; SETUP (gestisce questo solo una volta in fase di avvio)
;************************************************* *****************************;
;------------------
installazione; etichetta goto
;------------------

movlw B'01100000 '; 4MHz B'01100000 ='
OSCCON banksel
movwf OSCCON
banksel 0
; Attendere osc stabilizza
LP:
btfss OSCCON, 2
goto lp;-------------------------------------------------
; Nota!16F84 versione.
; Nota!qui abbiamo istituito le periferiche e le direzioni di approdo.
, Questo dovrà essere modificato per foto diverse.
;-------------------------------------------------
; Opzione di installazione
movlw b'00001000 ';

; ------- X;
; Nota!Abbiamo impostato il prescaler al WDT, così timer0; NON ha prescaler e overflow ogni 256
, Istruzioni e fare un interrupt.
;banksel OPTION_REG: va corretto reg banca
movwf OPTION_REG; dati di carico in OPTION_REG
0 banksel; torna alla banca normale 0
;-------------------------------------------------
; PORTB perni direzione di installazione
; 1 = input, 0 = uscita
clrf PORTB;
;
movlw b'00000000 '; tutte le 8 uscite sono PORTB
;
banksel TRISB: va corretto reg banca
movwf TRISB, inviare maschera di PORTB
0 banksel; ritorna al reg banca
;-------------------------------------------------
; PORTA perni direzione di installazione
; 1 = input, 0 = uscita
clrf PORTA;
;
movlw b'00000000 '; tutte e 5 le porta sono uscite,
; (Con porta 16F84 ha solo 5 bit più basso)
;
banksel TRISA: va corretto reg banca
movwf TRISA; inviare maschera a Porta
0 banksel; ritorna al reg banca
;-------------------------------------------------
; INTCON setup
;
, Per questo esempio di codice, possiamo attivare la timer0
; Overflow interrupt.
;
; Abilitare gli interrupt scorso
; Setup di interrupt
movlw b'11100000 '; GIE = on = on TOIE (overflow int timer0)
; BSF INTCON, 7
; BSF INTCON, 6
; BSF INTCON, 5
INTCON banksel
movwf INTCON
banksel 0
clrf sec
clrf sec10
clrf min
clrf min10
clrf hr
clrf HR10

;-------------------------------------------------
; Nota!Ora, l'hardware è costituito abbiamo bisogno di caricare il
; Primo conteggio per un secondo nella nostra Bres variabile 24bit.
;-------------------------------------------------
; Nota!Questo esempio utilizza 4 MHz di clock, che è
; 1.000.000 conteggi per secondo.
;
; Abbiamo bisogno di un periodo di 1 secondo, per cui dobbiamo caricare
; 1.000.000 conta ogni volta.
; 1.000.000 = 0F 42 40 (in esadecimale)
;
, Abbiamo anche bisogno di aggiungere 256 conta per la prima volta,
, Quindi dobbiamo solo aggiungere 1 al byte metà.
; Check overflow metà, se necessario.

, Qui si carica la variabile 24bit.
Movlw 0x0F; ottenere il valore MSB
movwf bres_hi; mettere in hi

movlw 0x42 1; ottenere il valore medio (si noti che abbiamo aggiunto da 1 a esso)
movwf bres_mid; mettere a metà

Movlw 0x40; ottenere il valore di LSB
movwf bres_lo; mettere a metà

, Bando LCD_Init, Ora l'installazione è completa, possiamo iniziare l'esecuzione.
;-------------------------------------------------
goto principale; avviare il programma principale

;------------------------------------------------- -----------------------------
; Inizializza LCD
LCD_Init Delay100 chiamata; aspettare LCD per regolare

Movlw 0x20; Set 4 bit in modalità
chiamata LCD_Cmd

Movlw 0x28; Set display turno
chiamata LCD_Cmd

Movlw 0x06; carattere Imposta la modalità di visualizzazione
chiamata LCD_Cmd

0x0c movlw; Set display on / off e comando del cursore
chiamata LCD_Cmd; cursore Partite

chiamata LCD_Clr; visualizzazione chiara

retlw 0x00
; Comando set di routine
LCD_Cmd movwf templcd
swapf templcd, w, manda alto a sgranocchiare
andlw 0x0F; chiaro superiore 4 bit di W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS; linea RS a 1
chiamata Pulse_e; Pulse la linea ad alta E

movf templcd, w, inviare inferiore nibble
andlw 0x0F; chiaro superiore 4 bit di W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS; linea RS a 1
chiamata Pulse_e; Pulse la linea ad alta E
chiamata Delay5
retlw 0x00

LCD_CharD addlw 0x30, 0x30 aggiungere per convertire in ASCII
LCD_Char movwf templcd
swapf templcd, w, manda alto a sgranocchiare
andlw 0x0F; chiaro superiore 4 bit di W
movwf LCD_PORT
BSF LCD_PORT, LCD_RS; linea RS a 1
chiamata Pulse_e; Pulse la linea ad alta E

movf templcd, w, inviare inferiore nibble
andlw 0x0F; chiaro superiore 4 bit di W
movwf LCD_PORT
BSF LCD_PORT, LCD_RS; linea RS a 1
chiamata Pulse_e; Pulse la linea ad alta E
chiamata Delay5
retlw 0x00

LCD_Line1 movlw 0x80; spostare al 1 ° riga, prima colonna
chiamata LCD_Cmd
retlw 0x00

movlw 0xC0 LCD_Line2; passare alla 2 ° fila, prima colonna
chiamata LCD_Cmd
retlw 0x00

LCD_Line1W addlw 0x80; spostare al 1 ° riga, colonna W
chiamata LCD_Cmd
retlw 0x00

LCD_Line2W addlw 0xC0; passare alla 2 ° fila, colonna W
chiamata LCD_Cmd
retlw 0x00

LCD_CurOn movlw 0x0d; display on / off e comando del cursore
chiamata LCD_Cmd
retlw 0x00

LCD_CurOff movlw 0x0C; display on / off e comando del cursore
chiamata LCD_Cmd
retlw 0x00

LCD_Clr movlw 0x01; display Clear
chiamata LCD_Cmd
retlw 0x00

; LCD_HEX movwf tmp1
; Swapf tmp1, w
; Andlw 0x0f
, Bando HEX_Table
, Bando LCD_Char
; Movf tmp1, w
; Andlw 0x0f
, Bando HEX_Table
, Bando LCD_Char
; Retlw 0x00

Delay255 movlw 0xFF; ritardo 255 mS
goto d0
Delay100 movlw d'100 '; 100mS ritardo
goto d0
Delay50 d'movlw 50 '; 50mS ritardo
goto d0
Delay20 d'movlw 20 '; 20mS ritardo
goto d0
Delay5 movlw 0x05; ritardo di 5,000 ms (4 MHz di clock)
d0 movwf count1
d1 movlw 0xC7; 1mS ritardo
movwf CONTA.VALORI
movlw 0x01
movwf countb
Delay_0
decfsz CONTA.VALORI, f
goto $ 2
decfsz countb, f
goto Delay_0

decfsz count1, f
goto d1
retlw 0x00

Pulse_e LCD_PORT BSF, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00

; Fine di routine LCD

DispTime
Movlw 0x04
CALL LCD_Line1W
movf HR10, w
CALL LCD_CharD
movf h, w
CALL LCD_CharD
Movlw ":"
CALL LCD_Char
movf min10, w
CALL LCD_CharD
movf min, w
CALL LCD_CharD
Movlw ":"
CALL LCD_Char
movf sec10, 10
CALL LCD_CharD
movf sec, w
CALL LCD_CharD
RETURN;************************************************* ****************************;************************************************* *****************************
; MAIN (loop principale del programma)
;************************************************* *****************************
;
;------------------
principale; etichetta goto
;------------------
chiamata LCD_Init
;-------------------------------------------------
; Nota!In questo esempio viene utilizzato il timer0 overflow interrupt.
; Questo interrompere il nostro programma principale ogni 256 istruzioni
, E fare l'unica timer di sistema secondo.
;-------------------------------------------------
main_loop;
oldtime movf, W; oldtime è la stessa sec?
subwf sec, W
Btfsc STATUS, Z; in caso contrario, saltare la prossima istruzione
main_loop goto, altrimenti continuare il controllo
chiamata DispTime; sec è cambiato, visualizzare l'ora
movf sec, W; fare sec e oldsec lo stesso
movwf oldtime

Oppure chiamate ai pezzi principale del programma.
; L'interrupt fa tutto quello timer roba secondo.
; Roba
; Roba
; Roba
; Roba

;-------------------------------------------------
main_loop goto; mantenere l'esecuzione del codice principale.

;------------------------------------------------- -----------------------------;================================================= =============================
fine, nessun codice dopo questo punto.
;================================================= =============================

 
suona come qualcosa a che fare con il vostro orologio di sistema o reset

controllare i valori di cristallo tappi
se il tuo utilizzando una basetta / millefori rimuovere i tappi in quanto la commissione per caricare il cristallo troppo come ha capacità anche

 
Non ho né tutte le coperture di cristallo.Sto utilizzando l'orologio interno al PIC.Tutto quello che ho sulla basetta è un regolatore di tensione, il PIC e un display LCD.

 
Avrete bisogno di un tappo di 0,1 vicino alla VDD e VSS pin del PIC.

 
Grazie per l'aiuto.
Ho installato tappi come indicato nello schema qui sotto.Non so se questa è la corretta installazione o meno.Non avevano alcun effetto sul mio problema.<img src="http://images.elektroda.net/32_1164126605.JPG" border="0" alt="Code problems with 16F88" title="problemi di codice con 16F88"/>
 
Ciao,

Tale schema sembra strano per me.Solo assicuratevi di avere un tetto 0.1uF collegato da VDD a VSS ( 5 V a GND) vicino al vostro PIC.Per la F88 thats dai pin 14 e 5.Il tappo non (o non dovrebbe) hanno una polarità in modo più o in meno in giro avrebbe fatto.
E sono sicuro che la-5V in tale schema è un errore, significherebbe che si sta eseguendo il vostro PIC da -5 a 5 V, e PIC non piace scappare 10v

<img src="http://www.edaboard.com/images/smiles/icon_biggrin.gif" alt="Very Happy" border="0" />Inoltre, MCLR (il perno di riarmo globale).Si potrebbe avere una trazione interno su questo pin, in modo da poter utilizzare MCLR come ho regolare / O.Oppure, è sufficiente tirare questo pin alto con un 22k 4.7K resistenza a 5 V.In entrambi i casi, ha bisogno di essere tirato alto.

Un '' intermitent problema di solito è verso il basso per far scattare il reset del rumore, o un alimentatore dodgy.Ho costruito un circuito PIC pochi stripboard, e utilizzando il osc interno è l'unico modo davvero ... come xtal oscillatore esterno è tirato fuori frequenza su stripboard di base (quick and dirty).Non riesco a vedere nulla subito male con il codice, e scremato sopra per la selezione della banca (mi viene sempre nel mio codice), ma è un po 'confuso.Mi rendo conto che copia / incolla non sempre mantenere la formattazione, ma ho notato un paio di casi in cui hai il nome di una subroutine con un diritto di istruzione dopo che sulla stessa linea ... sicuramente sarebbe MPLAB a gridare allo scandalo ?E vedo 'LP:', non sapevo due punti possono essere utilizzati nelle etichette.

In ogni caso, potrebbe essere un problema software, forse vale la pena scrivere un programma di prove in simle molto per la vostra configurazione hardware.Le stesse impostazioni solo senza il 'timer' di codice.Ancora impostare il I / O sui registri tris, e il vostro OSC interno, ma forse fare un ritardo di base per un LED o due, giusto per vedere se il suo ok di lavoro.Devo dire, che alcuni di indirizzamento indiretto è piuttosto complicato e può essere facile perdere la traccia di solo che cosa esattamente si sta mettendo in FSR, fate attenzione.

Buriedcode.

 
il prob principale è la stringa di configurazione doesnt specificare la configurazione osc
quindi se mi ricordo il valore predefinito è esterno I / O o cristallo MPLAB hs
Se non definirlo

E 'un prob orologio di sicuro

il codice guarda bene, e qui viene eseguito in proteus utilizza il 54% della CPU e dosnt crash
e passi multa codice per cinque ore o giù di lì l'ho lasciato acceso per la notte scorsa

Proteo ha rifiutato di regolare l'orologio da codice
quindi so proprio un problema di configurazione di sicuro

 
Grazie per la risposta Buriedcode.
Il diagramma, sto imparando è strano, io non ne so molto di elettronica e non sapevo davvero come collegare i tappi.
Ho collegato uno tarato il modo in cui lei ha suggerito, con ancora nessun risultato.Io davvero non credo che l'alimentazione è il problema perché, come ho affermato nel mio post originale un 627a avrà una durata di giorni senza perdere un colpo.Penso che ci sia un timer o qualche impostazione che mi manca che la causa del problema.Parte del codice è piuttosto complicato io certo non lo scrivo come ho detto prima l'ho copiato ma funziona bene sul 627a.

Grazie ancora per la risposta.

 
VSMVDD,
Apparentemente non ho notato la tua risposta precedente.La dichiarazione di configurazione prima contiene una impostazione dell'orologio penso che sia INTOS_IO.L'orologio è ulteriormente configurato nel registro OSCCON.E 'configurato per 4 mhz.

Ho pulito il codice e cercherò di attsach come un file asm. Zippato.Forse sarà un po 'più facile da leggere.
Ci dispiace, ma è necessario il login per visualizzare questo attaccamento

 
VSMVDD,

Volevo chiederle in post ultimo e dimenticato.

Che cosa è Proteo?Suona come potrebbe essere un simulatore.

 

Welcome to EDABoard.com

Sponsor

Back
Top