Vai al contenuto
PLC Forum


Rb0 Come Input Per Frequenzimetro - RB0 come input per frequenzimetro


Piero71

Messaggi consigliati

Buondì a tutti.

Ho un problema stranissimo da sottoporvi e spero vivamente che mi possiate aiutare in questo mite agosto; sono ad un passo dalla conclusione.

Sto realizzando un frequenzimetro con LCD usando un 16F628A con clock a 20MHz e la scheda si sviluppo Easypic2.

Per testare il progetto ho iniettato sul pin RB0, che uso come ingresso con interrupt, un segnale ad onda quadra generato in vari modi, con un NE555, con un 4093 e disaccoppiatore a transistor e generatore di funzioni.

Controllando il segnale all'uscita degli oscillatori non rilevo nessun problema: onda quadra stabile.

Tenete conto che ho provato a montare il circuito (pic, lcd e oscillatore) su una beadboard senza che nulla sia cambiato.

Veniamo al dunque: l'indicazione sull'lcd è "ballerina", ciclicamente la frequenza indicata passa dal valore reale e scende anche fino a zero, per poi ritornare al valore corretto.

Controllando con un oscilloscopio ho notato che il segnale rilevato sul pin rb0 è instabile e quando sull'lcd leggo zero, l'oscilloscopio mi fa vedere una tensione continua pari a vcc!

Ho provato a riempire il circuito di condensatori per filtrare l'alimentazione, ma a nulla è servito.

Inoltre sono costretto a disaccoppiare l'oscillatore di test (circa 2KHz) con un transistor, in quanto collegandolo direttamente rilevo un segnadi di circa 500mV-picco!

In pratica è come se l'rb0 andasse in corto internamente.

La cosa assurda è che il transistor di disaccoppiamento lo collego direttamente con l'emettitore su rb0 e il collettore su vcc!

Con una Rbase di solo 1K...

Ho provato con tre diversi pic 628a, ma il risultato non cambia!

Spero che qualcuno abbia già affrontato tale calamità, in fondo credo sia frequente l'uso del pin rb0 in input con IRQ.

Non posto subito il codice (mikrobasic) per non allungare il post. Lo farò se me lo chiederete, e la foto del "campo di battaglia" la pubblicherei volentieri se capissi come fare...

Grazie fin d'ora a chi mi darà retta.

Cordialità.

Piero Di Stefano

Link al commento
Condividi su altri siti


Ciao Livio,

direi di si.

Anzi visto la leggibilità del codice lo posto.

Dal punto di vista logico non vedo quali possano essere le cause.

Forse la funzione che gestisce l'lcd interferisce con lo stato di rb0?

Potrei tentare di pilotare l'lcd con PORTA. Provo e vi faccio sapere.

Sempre grazie!

Piero

program Freqmeter

'Ricordarsi che verrà usato un quarzo da ben 20MHZ!

dim RBCounter as longint

dim Text as char[7]

dim tmr0_cnt as word

'*******************************************************************************

sub procedure INTERRUPT

'diciamo che se l'interrupt chiamante è quello del timer faccio quanto segue,

'OGNI 64*125*0,2 = 1600 microsecondi TMR0 lancia l'irq...

if INTCON.2 = 1 then

tmr0_cnt= tmr0_cnt + 1 'Incremento tmr0_cnt ogni irq

TMR0 = 130

end if

if INTCON.1 =1 then

RBCounter = RBCounter + 1 'incremento la variabile longint locale

end if

' e poi esco e reimposto il flag del registro INTCON, per poter rilevare altri IRQ

INTCON = %11110000 'Clear T0IF and INTF

end sub

'*******************************************************************************

sub procedure LongintToStrWithZeros(dim input_ as longint, dim byref output as char[6])

dim len_ as byte

' the output is right justified

' output = "0000000"

output = " 0"

len_ = 1

if input_ > 9 then

Inc(len_)

end if

if input_ > 99 then

Inc(len_)

end if

if input_ > 999 then

Inc(len_)

end if

if input_ > 9999 then

Inc(len_)

end if

if input_ > 99999 then

Inc(len_)

end if

if input_ > 999999 then

Inc(len_)

end if

output[6] = "0" ' this will set FSR to point to the last element of output

while len_ > 0

INDF = input_ mod 10 ' we are free to use INDF now, since FSR is set above

input_ = (input_ - INDF) div 10

asm

MOVLW 48 ;'convert number to character

ADDWF INDF, F ;' by adding 48 to number

DECF FSR, F

end asm

Dec(len_)

wend

end sub

'*******************************************************************************

Main:

'INIZIALIZZAZIONE REGISTRI FATTA SOLTANTO ALL'AVVIO DEL PROGRAMMA

OPTION_REG = %10000101 'RB pullup Disabled; RBo falling edge; Assign prescaler to TMR0: 101 = 1/64

TRISA = %11110000 'ininfluente, non usiamo PORTA

TRISB = %00000001 'Solo RB0 in input con rising slope

' Inizializza le variabili globali

tmr0_cnt = 0

INTCON = %11110000 ' CLEAR TMRO and RB0 interrupt flag

LCD_Init(PORTB) 'Inizilizza i PIN da collegare all'LCD

LCD_Cmd(LCD_Cursor_off)

'delay_ms(500)

RBCounter = 0

'*******************************************************************************

Ciclo_Scrittura_LCD:

IF (tmr0_cnt = 625) THEN '250 [at] 8MHz, 625 [at] 20MHz

tmr0_cnt = 0 'In 1 sec sono trascorsi 625 Interrupt di TMR0 (nIrq= 625)

LongintToStrWithZeros(RBCounter, Text) ' Convert word to string with zeros (right justified)

If RBCounter < 1000 Then 'Tutto ciò serve a inserire i punti separatori di migliaia e milioni

Lcd_Chr(1, 1, "f")

Lcd_Chr(1, 2, "=")

Lcd_Chr(1, 3, " ")

Lcd_Chr(1, 4, " ")

Lcd_Chr(1, 5, " ")

Lcd_Chr(1, 6, " ")

Lcd_Chr(1, 7, " ")

Lcd_Chr(1, 8, " ")

Lcd_Chr(2, 1, " ")

Lcd_Chr(2, 2, " ")

Lcd_Chr(2, 3, Text[4])

Lcd_Chr(2, 4, Text[5])

Lcd_Chr(2, 5, Text[6])

Lcd_Chr(2, 6, " ")

Lcd_Chr(2, 7, "H")

Lcd_Chr(2, 8, "z")

End If

If RBCounter >= 1000 Then

Lcd_Chr(1, 1, "f")

Lcd_Chr(1, 2, "=")

Lcd_Chr(1, 3, " ")

Lcd_Chr(1, 4, " ")

Lcd_Chr(1, 5, " ")

Lcd_Chr(1, 6, " ")

Lcd_Chr(1, 7, Text[1])

Lcd_Chr(1, 8, Text[2])

Lcd_Chr(2, 1, Text[3])

Lcd_Chr(2, 2, ".")

Lcd_Chr(2, 3, Text[4])

Lcd_Chr(2, 4, Text[5])

Lcd_Chr(2, 5, Text[6])

Lcd_Chr(2, 6, " ")

Lcd_Chr(2, 7, "H")

Lcd_Chr(2, 8, "z")

End If

If RBCounter >= 1000000 Then

Lcd_Chr(1, 1, "f")

Lcd_Chr(1, 2, "=")

Lcd_Chr(1, 3, " ")

Lcd_Chr(1, 4, " ")

Lcd_Chr(1, 5, Text[0])

Lcd_Chr(1, 6, ".")

Lcd_Chr(1, 7, Text[1])

Lcd_Chr(1, 8, Text[2])

Lcd_Chr(2, 1, Text[3])

Lcd_Chr(2, 2, ".")

Lcd_Chr(2, 3, Text[4])

Lcd_Chr(2, 4, Text[5])

Lcd_Chr(2, 5, Text[6])

Lcd_Chr(2, 6, " ")

Lcd_Chr(2, 7, "H")

Lcd_Chr(2, 8, "z")

End If

RBCounter = 0

END IF

goto Ciclo_Scrittura_LCD 'Attenzione, non Main!

end.

Link al commento
Condividi su altri siti

Scusa, forse non ho capito bene. Ma tu usi la medesima porta per leggere e per comandare il display. Devi verificare, magari nell'espanso asm del compilatore, che RB0 sia sempre settato come ingresso. Ho il sospetto che in alcuni momenti passi come uscita.

Link al commento
Condividi su altri siti

Si anch'io credo che passi come uscita;

tant'è che se attivo i led su portb della scheda easypic2, vedo il led sulla rb0 che tende ad accendersi a 5volt, con una certa sincronia rispetto agli altri pin della portb che pilotano l'lcd.

Come avevo scritto prima dovrei usare porta per pilotare il display e portb solo per l'ingresso.

Nel codice asm trovo semplicemente la dichiarazione:

$0536 $3001 MOVLW 1

$0537 $0086 MOVWF TRISB

che non lascia dubbi, e nessuna altra istruzione che coinvolga portb o porb.0

Purtroppo se provo a configurare porta per l'lcd, l'hex viene generato ma quando lo carico sul pic, sull'lcd non vedo nulla.

Non mi resta che sentire gli inventori del compilatore per sapere che a loro risulta che portb debba essere usata per intero solo e solo per il pilotaggio dell'lcd e perchè la configurazione di porta non vuol saperne di andare.

Che rabbia, funzionava praticamente tutto, e con una manciata di componenti!

Grazie comunque Livio, ora scrivo agli amici di Belgrado e terrò tutti voi aggiornati.

E' da pochissimo che mi diletto con questi pic, volevo approfittare dell'ozio agostano per avvicinarmi a questo mondo e SBAM! la prima travata in faccia. Se il buongiorno si vede dal mattino...

Ma non mi darò per vinto! A presto...

Buona serata.

PIERO

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...