allora, ho riletto e modificato un po di codice e commenti: effettivamente a volte cambio il codice ma non i commenti, quindi risulta difficile capirci qualcosa. Rispondo alle tue domande così vediamo di capirci meglio:
i)ho avuto modo di vedere all'università (10 minuti) con l'oscilloscopio che effettivamente riesco a spedire il primo byte: quello dell'indirizzo e l'ack del nono bit
ii) per quale motivo inserisci lo "shift" sul valore dell'indirizzo ?
ii) lo shift a destra lo faccio perché so che nell'i2c il primo bit del primo byte corrisponde a R/W, pertanto uno 0 simboleggia un write da parte del PIC. Sbaglio?
iii) per quale motivo all'interno della funzione
- Codice: Seleziona tutto
call SendI2C
non viene verificata la presenza del bit di acknowledge che lo slave deve inviare (almeno così mi sembra) ?
iii) ogni byte che inivio devo sempre verificare il bit ack?
iv) dai commenti riportati non mi appare evidente la posizione e l'ordine che avresti associato alle uscite; mi riferisco quindi a quanto riportato negli statement con il trasferimento della costante espressa in bit(s)
iv)spero che ora sia più chiaro il codice
v) per quanto riguarda i byte(s) inviati tramite i2c al modulo LCD, all'interno della routine "SendI2C", quale funzione, ognuno di essi, rispettando l'ordine sequenziale, dovrebbero assolvere ?
v)l'ordine di invio dei byte segue lo schema citato dal datasheet del controller HD44780, pag 46.
E il fatto di commutare ogni volta la linea dell'enebale lo intuita sempre da quel datasheet, sbaglio?
vi) qual è il clock che stai utilizzando ?
vi)supponendo che abbia fatto tutto come si deve il clock dell'i2c è di 100kHz
vii) la routine di ritardo "mdel" a quale tempo dovrebbe corrispondere secondo i tuoi calcoli ?
vii)la routine mdel effettua un ritardo che non ho letto da nessuna parte

. E' di circa 6 us.
allego il nuovo codice, sperando di risolvere qualcosa. Grazie per la tua pazienza
- Codice: Seleziona tutto
list p=16f887 ; direttiva che definisce il tipo di processore
#include "p16f887.inc" ; file che contiene le definizioni dei simboli
;************************************************************************
; Configuration bits |
; I bit di configurazione (impostazioni dell'hardware settate in fase |
; di programmazione del dispostitivo). |
; sono definiti tramite una direttiva nel codice. |
; Impostazioni importanti: |
; - Clock interno (di default 4MHz; fist=1MHz-->T=1us) |
; - Wathcdog timer disattivato (_WDT_OFF). |
;************************************************************************
__CONFIG _CONFIG1, _INTRC_OSC_NOCLKOUT & _CP_OFF & _WDT_OFF & _BOR_OFF & _PWRTE_OFF & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
;****************************************
; Definizioni costanti |
;****************************************
TMR0_PERIOD equ (.256 - .39) ; we use tmr0 to generate a periodic interrupt every 10 ms
DISP_ADDR equ 0x27 ;indirizzo del modulo slave i2c
;****************************************************************************************
; La direttiva UDATA (uninitialized data) dichiara una sezione di dati da allocare in |
; RAM, in un qualunque banco. In questo modo si possono avere strutture di dimensioni |
; maggiori (la RAM condivisa tra i banchi e'solo di 16 byte), con lo svantaggio di dover|
; settare il banco prima di ogni accesso. Anche in questo caso il codice è rilocabile. |
; Dichiarando due sezion i con label diverse, il linker può posizionarle |
; in due banchi diversi. |
; NOTA: i valori a 16 bit sono memorizzati in formato Little Endian |
;****************************************************************************************
udata
i2cAddr res .1 ;riservo un byte per indirizzo per indirizzo slave
;*******************************************************************************
; Vettore di reset |
; Il vettore di reset contiene l'istruzione che viene eseguita per prima dopo |
; un reset del microcontrollore. La direttiva CODE dichiara una sezione di |
; codice da allocarein 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 per non ricadere nelle prime 4 locazioni
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
banksel TRISC
bsf TRISC, 3 ;bit 3 e 4 del portc com input per i2c
bsf TRISC, 4
bcf TRISA, 7 ;spi_ss (se impostato a zero seleziono i2c)
clrf SSPSTAT
movlw .9 ;clock 100kHz (di default il clock del PIC è 4 MHz)
movwf SSPADD
;------------------------------------------------------------------------------
banksel SSPCON
movlw B'00101000' ;module enabled, I2C master: Fosc/(4 *(SSPADD+1))
movwf SSPCON
START_IIC
bcf PIR1, SSPIF ; reset interrupt flag
banksel SSPCON2
bsf SSPCON2, SEN ; initiate start
btfsc SSPCON2, SEN ;aspetto che SEN vada a 0: start condition terminata
goto $-1
movlw DISP_ADDR
banksel i2cAddr
movwf i2cAddr
bcf STATUS, C
rlf i2cAddr, w ;con rlf il bit di carry (0--> operazione di scrittura) va al primo posto di i2cAddr
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
banksel SSPCON2
btfsc SSPCON2, ACKSTAT ;ACK received from slave? if yes skip
goto NO_ACK ;if no, end transaction
pagesel SendI2C
call SendI2C
;------------------------------------------------------------------------------
banksel SSPCON2
NO_ACK bsf SSPCON2, PEN ;initiate STOP
banksel WAIT
call WAIT
goto START_IIC ;try again...
;------------------------------------------------------------------------------
SEND_W_ON_IIC
movwf SSPBUF ;begin transmission
WAIT btfss PIR1, SSPIF ;send completed? if Yes skip next
goto WAIT
bcf PIR1, SSPIF ;yes, clear flag
return
;configurazione iniziale richiesta da dasheet
SendI2C
movlw B'00100011';Set 8 bit operation R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel delay
call delay
movlw B'00000011' ;Set 8 bit operation R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
movlw B'00100011';Set 8 bit operation R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel delay
call delay
movlw B'00000011' ;Set 8 bit operation R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
movlw B'00100011';Set 8 bit operation R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel delay
call delay
movlw B'00000011' ;Set 8 bit operation R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
;--------------------Set to 4 bit operation -----------------------------------
;SendI2C
movlw B'00100010';0010 Set 4 bit operation R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000010' ;0010 Set 4 bit operation R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
;--------------------Function set 1st nibble---------------------------------
movlw B'00100010' ;0010 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000010' ;0010 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------Function set 2nd nibble---------------------------------
movlw B'00101000' ;1000 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00001000' ;1000 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;off
;1st nibble---------------------------------
movlw B'00100000' ;0010 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000000' ;0010 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;2nd nibble---------------------------------
movlw B'00101000' ;1000 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00001000' ;1000 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;clear
;1st nibble---------------------------------
movlw B'00100000' ;0010 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000000' ;0010 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;2nd nibble---------------------------------
movlw B'00101001' ;1000 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00001001' ;1000 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;entrymode
;1st nibble---------------------------------
movlw B'00100000' ;0010 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000000' ;0010 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;2nd nibble---------------------------------
movlw B'00100111' ;1000 Function set 1st nibble R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000111' ;1000 Function set 1st nibble R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------Display ON, Cursor On, Cursor Blinking 1st nibble-----
movlw B'00100000' ;0000 Display ON, Cursor On, Cursor Blinking R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000000' ;0000 Display ON, Cursor On, Cursor Blinking R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------Display ON, Cursor On, Cursor Blinking 2nd nibble-----
movlw B'00101111' ;1111 Display ON, Cursor On, Cursor Blinking R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00001111' ;1111 Display ON, Cursor On, Cursor Blinking R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------Entry Mode, Increment cursor position, No display shift 1st nibble-----
movlw B'00100000' ;0000 Entry Mode, Increment cursor position, No display shift R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000000' ;0000 Entry Mode, Increment cursor position, No display shift R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------Entry Mode, Increment cursor position, No display shift 2nd nibble-----
movlw B'00100110' ;0110 Entry Mode, Increment cursor position, No display shift R/S =0 E=1
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'00000110' ;0110 Entry Mode, Increment cursor position, No display shift R/S =0 E=0
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;----------------------------------------------------------------------------------------
;--------------------H 1st nibble-------------------------------------------------------
; movlw 0x14 ;0100 'H' R/S =0 E=1 -->010100
; call SEND_W_ON_IIC
; movlw 0x34 ;0100 'H' R/S =1 E=1 -->110100
; call SEND_W_ON_IIC
; movlw 0x24 ;0100 'H' R/S =1 E=0 -->100100
; call SEND_W_ON_IIC
;--------------------H 2nd nibble-------------------------------------------------------
; movlw 0x18 ;1000 'H' R/S =1 E=0 -->101000
; call SEND_W_ON_IIC
; movlw 0x38 ;1000 'H' R/S =1 E=1 -->111000
; call SEND_W_ON_IIC
; movlw 0x28 ;1000 'H' R/S =1 E=0 -->101000
; call SEND_W_ON_IIC
;----------------------------------------------------------------------------------------
;---------------------------------------S------------------------------------------------
;--------------------S 1st nibble--------------------------------------
loop
movlw B'00100101'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'01100101'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'01000101'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
;--------------------2nd nibble----------------------------------------
movlw B'00100011'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'01100011'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
movlw B'01000011'
pagesel SEND_W_ON_IIC
call SEND_W_ON_IIC
pagesel mdel
call mdel
goto loop
mdel
loop4 movlw 0x5
movwf 0x22
decfsz 0x22,1
goto loop4
return
delay ;routine di ritardo di 10 ms per tempi di attesa display
movlw TMR0_PERIOD
banksel TMR0
movwf TMR0
bcf INTCON,2 ;azzera flag overflow
cicla
btfss INTCON,T0IF ;testa se bit TOIF ha generato overflow (Settato a 1)
goto cicla
bcf INTCON,T0IF ;azzera bit TOIF (flag owerflow) per prossimo conteggio
return
end