Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

I2C1 STM32

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: I2C1 STM32

Messaggioda Foto Utentelelerelele » 4 mag 2015, 17:26

WALTERmwp ha scritto:Riscrivo, non ho verificato l'impostazione (configurazione) che presumo corretta quindi, per quanto sopra, mi pare che il sensore non risponda (presupposto un coretto interfacciamento).
Allora può darsi che semplicemente non invii l'indirizzo corretto: lui non "si" riconosce e non gestisce l'ACK sulla SDA.
Saluti


in effetti quanto indicato al post #7
lelerelele ha scritto:....lo standard I2C prevede che il master invii lo start, poi la stringa con il codice componente e l'ultima cifra indica se vai in scrittura od in lettura......
saluti.

lasciava pensare appunto che non hai inviato correttamente l'indirizzo del sensore, in binario 0b1110111x dove x=bit lettura scrittura, come indicato a pag 20 del datasheets, se non invii questo il sensore non saprà mai che stai chiamando lui!

saluti.
Avatar utente
Foto Utentelelerelele
4.899 3 7 9
Master
Master
 
Messaggi: 5505
Iscritto il: 8 giu 2011, 8:57
Località: Reggio Emilia

0
voti

[12] Re: I2C1 STM32

Messaggioda Foto Utentealle96 » 5 mag 2015, 8:49

può darsi che semplicemente non invii l'indirizzo corretto: lui non "si" riconosce e non gestisce l'ACK sulla SDA

non avevo preso in considerazione la possibilità. Sta mattina ho cambiato registro passando da 0x55 a 0xEE che è un registro della eeprom e tutto pare funzionare. Mi sono anche accorto che il registro dell'ID è il 0xD0 e non 0x55 ma mi chiedevo come mai nonostante io scriva 0xD0 non funzioni ma funzioni invece solo con 0xEE (premetto che non ho provato altri registri). Se qualcuno può aiutarmi dando una sbirciata al datasheet il sensore è il BMP180.
Grazie dell'aiuto =D>
Avatar utente
Foto Utentealle96
15 4
 
Messaggi: 47
Iscritto il: 21 feb 2012, 16:21

0
voti

[13] Re: I2C1 STM32

Messaggioda Foto Utentelelerelele » 5 mag 2015, 9:21

a pagina 18 del datasheets c'è la mappa dei registri di memoria, non compare affatto il 55h, forse per questo che non ti risponde.

saluti.
Avatar utente
Foto Utentelelerelele
4.899 3 7 9
Master
Master
 
Messaggi: 5505
Iscritto il: 8 giu 2011, 8:57
Località: Reggio Emilia

0
voti

[14] Re: I2C1 STM32

Messaggioda Foto UtenteWALTERmwp » 5 mag 2015, 10:45

Come ti ha fatto notare Foto Utentelelerelele la locazione 0x55 pare non esista.
alle96 ha scritto:Sta mattina ho cambiato registro passando da 0x55 a 0xEE che è un registro della eeprom e tutto pare funzionare.
cosa vuol dire che hai cambiato, in quale posizione del messaggio ?
Lo avrai riportato, appunto, come indirizzo per lo slave.
Riesci a interpretare il contenuto del datasheet ?
Diversamente chiedi pure.

Considera che 0xEE (oppure 0xEF) è l'indirizzo dello slave, cioè del tuo sensore, non è una posizione nella memoria; è il valore contenuto in una posizione (come ti è già stato scritto vedi pag.18) infatti il registro 0x0D è a valore fisso, accessibile in sola lettura: "Chip-id (register D0h): This value is fixed to 0x55 and can be used to check whether communication is functioning.".
A pag.20, invece: "The BMP180 module address is shown below. The LSB of the device address distinguishes between read (1) and write (0) operation, corresponding to address 0xEF (read) and 0xEE (write)."

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[15] Re: I2C1 STM32

Messaggioda Foto Utentealle96 » 5 mag 2015, 22:04

Ringrazio tutti ed in particolare Foto UtenteWALTERmwp per i chiarimenti sull'I2C e chiedo scusa per la mia ignoranza su questo tipo di protocollo.
Al momento il mio obbiettivo sarebbe leggere l'indirizzo 0xD0 e la funzione per la lettura dell'id è cambiata cosi:
Codice: Seleziona tutto
uint16_t status;
   /*wait for line*/
   while((I2C1 ->SR2 & I2C_SR2_BUSY) == I2C_SR2_BUSY);
   /*ack enabled*/
   I2C1 ->CR1 |= I2C_CR1_ACK;
   /*enable line*/
   I2C1 ->CR1 |= 0x0001;
   /*start event generation*/
   I2C1 ->CR1 |= I2C_CR1_START;
   /*check start bit generation*/
   while(!(I2C1 ->SR1 & 0x0001));
   status = I2C1 ->SR1;
   /*write adress*/
   I2C1 ->DR = adr;
   /*wait for adress sent complete*/
   while(!(I2C1 ->SR1 & 0x0002));
   /*read status 4 clear*/
   status = I2C1 ->SR1;
   
   I2C1 ->DR = 0xD0;
   /*wait for adress sent complete*/
   while(!(I2C1 ->SR1 & 0x0002));
   /*ack disable*/
   I2C1 ->CR1 &= ~I2C_CR1_ACK;
   /*read status 4 clear*/
   status = I2C1 ->SR1;
   
   /*stop req*/
   //I2C1 ->CR1 |= I2C_CR1_STOP;
   /*wait*/
   while(!(I2C1 ->SR1 & I2C_SR1_BTF)); //MI BLOCCO QUA
   /*read id*/
   id = I2C1 ->DR;


ora invio prima 0xEF dicendo così di voler leggere, poi scrivo 0xD0 per l'id (e fin qua 0 problemi...ADDR settato e il datashifting sembra funzionare) poi nella lettura dell'ID resto bloccato aspettando che sia completata la trasmissione...
Se posso chiedervi giusto quest'ultimo aiuto mi sareste davvero di grande aiuto :D
Grazie O_/
Avatar utente
Foto Utentealle96
15 4
 
Messaggi: 47
Iscritto il: 21 feb 2012, 16:21

0
voti

[16] Re: I2C1 STM32

Messaggioda Foto UtenteWALTERmwp » 8 mag 2015, 13:09

Foto Utentealle96, non so se nel frattempo hai risolto: se si, meglio, e ignora quanto riportato altrimenti, per darmi l'opportunità di provare ad interpretare il codice, dovresti rispondere a quanto segue:
ì) qual è il valore di "adr" in questa assegnazione ?
Codice: Seleziona tutto
I2C1 ->DR = adr;
(presumo come scritto dopo 0xEF)

ìì) perché dopo aver scritto "0xD0" in DR esegui questa istruzione ?
Codice: Seleziona tutto
/*ack disable*/
   I2C1 ->CR1 &= ~I2C_CR1_ACK;

iii) hai letto, con attenzione quanto riportato a pag.22 del datasheet del sensore ?
Riesci a interpretare il diagramma dei temi riportato nella stessa ?

Prima abbiamo stabilito che nella trasmissione non specificavi l'indirizzo dello slave mentre ora bisogna stabilire se hai compreso il criterio indicato (sempre pag.22).

Se (il criterio) è valido anche per acquisire il contenuto del registro "0xD0" allora devi:
1) inviare lo start bit,
2) inviare lo "address write command" (ovvero "0xEE") del sensore,
3) inviare il valore dell'indirizzo di memoria del quale intendi leggere il contenuto, cioè "0xD0",
4) inviare, di nuovo, lo start bit (assume significato di "Restart"),
5) inviare lo "address read command" (ovvero "0xEF") del sensore,
6) ricevere (se arriva) dal sensore il byte che contiene il valore richiesto (forse potrebbe rispondere con un solo byte ma anche con due),
7) non inviare allo slave il bit di ACK (se ci si aspetta l'arrivo di un solo byte) e al successivo impulso dello SCL inviare il bit di STOP.

Per quanto riguarda (2) e (3), ovviamente, devi prevedere la ricezione del bit di ACK che il sensore ti deve inviare.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[17] Re: I2C1 STM32

Messaggioda Foto Utentealle96 » 8 mag 2015, 21:20

Mi rendo conto di non aver capito più di tanto sulla I2C ho letto e seguito i passaggi indicati da Foto UtenteWALTERmwp il codice riuslta questo:

Codice: Seleziona tutto
uint16_t status;
   /*wait for line*/
   while((I2C1 ->SR2 & I2C_SR2_BUSY) == I2C_SR2_BUSY);
   /*ack enabled*/
   I2C1 ->CR1 |= I2C_CR1_ACK;
   /*enable line*/
   I2C1 ->CR1 |= 0x0001;
   /*start event generation*/
   I2C1 ->CR1 |= I2C_CR1_START;
   /*check start bit generation*/
   while(!(I2C1 ->SR1 & 0x0001));
   status = I2C1 ->SR1;
   
   
   /*write adress*/
   I2C1 ->DR = 0xEE;
   /*wait for adress sent complete*/
   while(!(I2C1 ->SR1 & 0x0002));
   /*read status 4 clear*/
   status = I2C1 ->SR1;
   
   I2C1 ->DR = adr; //scrivo 0xD0
   /*wait for adress sent complete*/
   while(!(I2C1 ->SR1 & 0x0002));
   /*read status 4 clear*/
   status = I2C1 ->SR1;
   
   /*restart*/
   I2C1 ->CR1 |= I2C_CR1_START;
   /*check start bit generation*/
   while(!(I2C1 ->SR1 & 0x0001));
   status = I2C1 ->SR1;
   
   /*write adress*/
   I2C1 ->DR = 0xEF;
   /*wait for adress sent complete*/
   while(!(I2C1 ->SR1 & 0x0002));
        /*ack disable*/
   /*read status 4 clear*/
   I2C1 ->CR1 &= ~I2C_CR1_ACK;
   status = I2C1 ->SR1;
   
   /*read data*/
   /*wait transmission complete*/
   while(!(I2C1 ->SR1 & I2C_SR1_BTF)); //resto fermo qua
        /*stop condition*/
   I2C1 ->CR1 |= I2C_CR1_STOP;
   id = I2C1 ->DR;


Purtroppo non funziona ancora e non capisco il motivo...mi sembra di aver seguito tutti i passaggi indicati. Qualcuno saprebbe indicarmi l'errore?
Grazie del costante aiuto O_/
Avatar utente
Foto Utentealle96
15 4
 
Messaggi: 47
Iscritto il: 21 feb 2012, 16:21

0
voti

[18] Re: I2C1 STM32

Messaggioda Foto UtenteWALTERmwp » 9 mag 2015, 1:08

Vediamo se riusciamo a fare un altro passo in avanti.
Dovresti però, per cortesia, rispondere alle domande perché io non sono "lì" e non ho la tua visibilità, quindi:
i) perché esegui questa istruzione ?
Codice: Seleziona tutto
I2C1 ->CR1 &= ~I2C_CR1_ACK;

ii) qual è il valore di questa define: "I2C_CR1_ACK" ?
(te lo chiedo per conoscerne il contenuto e perché, nel caso del test sul bit ADDR, hai utilizzato invece una costante).

iii) che tipo è la variabile "adr", e a quanto è effettivamente inizializzata ?

iv) ... i commenti in "inglese" li hai inseriti tu ?

L'elenco delle operazioni, riportate nel Post [16], dal punto 1 al 7 mi sembrano coerenti, altra cosa è la corretta trasposizione in istruzioni; ma per questo attendo anche la risposta alla seconda domanda (ii).

Potrei avere errato estendendo la modalità di lettura descritta a pag.22, anche al registro 0xD0; se così dovesse essere sarebbe sufficiente, sempre facendo riferimento all'elenco delle operazioni, sostituirlo con uno proprio della E2PROM, ad esempio 0xAA.

Non mi pare ci sia qualcosa di particolare su cui indagare, il flusso del codice sul master vedo che prosegue ricevendo il bit di ACK dallo slave quindi, previo quanto sopra, cerchiamo di capire se l'approccio verso il sensore è corretto.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[19] Re: I2C1 STM32

Messaggioda Foto Utentelelerelele » 11 mag 2015, 16:14

Data la mia magra esperienza non riconosco il tuo codice,
ti invio quanto ho usato io per la lettura dei parametri.
Codice: Seleziona tutto
UINT16 LeggoParametro(UINT8 Indirizzo) {
    UINT16 Valoreletto;
    CLRWDT();
    Start();

    Invio_Byte(I2C_CodiceScrittura);

    Invio_Byte(Indirizzo);

    ReStart();

    Invio_Byte(I2C_CodiceLettura);


    Valoreletto = Leggo_Byte16();

    Stop();
    return Valoreletto;



saluti.
Avatar utente
Foto Utentelelerelele
4.899 3 7 9
Master
Master
 
Messaggi: 5505
Iscritto il: 8 giu 2011, 8:57
Località: Reggio Emilia

0
voti

[20] Re: I2C1 STM32

Messaggioda Foto Utentealle96 » 12 mag 2015, 18:48

Rispondo innanzitutto a Foto UtenteWALTERmwp

1)Quell'istruzione serve a disabilitare l'acknowledge. Questo è stato fatto poiché mi aspettavo 1 solo byte per l'id ed era richiesto nel datasheet del micro

2)Vale 0x0400 e serve ad abilitare l'acknowledge

3)La variabile adr è un argomento passato dal main alla funzione per la precisione un unsigned char (8bit)

4)I commenti li ho tutti inseriti io, so che l'inglese non è dei migliori ma dato che è per l'esame mi hanno consigliato di scrivere in inglese per fare bella figura. Chiaramente prima di consegnarlo li riscrivo meglio

Ho provato ad inserire il valore 0xAA lasciando l'acknowledge visto che a quel punto mi aspetatvo 2 byte ma rimango sempre fermo allo stesso punto

Foto Utentelelerelele ti posso chiedere da che libreria hai preso quelle funzioni così me le studio?

Grazie per l'aiuto O_/

Avatar utente
Foto Utentealle96
15 4
 
Messaggi: 47
Iscritto il: 21 feb 2012, 16:21

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 18 ospiti